tools/testing/selftests/futex/functional/futex_numa_mpol.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/futex/functional/futex_numa_mpol.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/futex/functional/futex_numa_mpol.c
Extension
.c
Size
5508 bytes
Lines
217
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct thread_args {
	void *futex_ptr;
	unsigned int flags;
	int result;
};

static struct thread_args thread_args[MAX_THREADS];

#ifndef FUTEX_NO_NODE
#define FUTEX_NO_NODE (-1)
#endif

#ifndef FUTEX2_MPOL
#define FUTEX2_MPOL	0x08
#endif

static void *thread_lock_fn(void *arg)
{
	struct thread_args *args = arg;
	int ret;

	pthread_barrier_wait(&barrier_main);
	ret = futex2_wait(args->futex_ptr, 0, args->flags, NULL, 0);
	args->result = ret;
	return NULL;
}

static void create_max_threads(void *futex_ptr)
{
	int i, ret;

	for (i = 0; i < MAX_THREADS; i++) {
		thread_args[i].futex_ptr = futex_ptr;
		thread_args[i].flags = FUTEX2_SIZE_U32 | FUTEX_PRIVATE_FLAG | FUTEX2_NUMA;
		thread_args[i].result = 0;
		ret = pthread_create(&threads[i], NULL, thread_lock_fn, &thread_args[i]);
		if (ret)
			ksft_exit_fail_msg("pthread_create failed\n");
	}
}

static void join_max_threads(void)
{
	int i, ret;

	for (i = 0; i < MAX_THREADS; i++) {
		ret = pthread_join(threads[i], NULL);
		if (ret)
			ksft_exit_fail_msg("pthread_join failed for thread %d\n", i);
	}
}

static void __test_futex(void *futex_ptr, int err_value, unsigned int futex_flags)
{
	int to_wake, ret, i, need_exit = 0;

	pthread_barrier_init(&barrier_main, NULL, MAX_THREADS + 1);
	create_max_threads(futex_ptr);
	pthread_barrier_wait(&barrier_main);
	to_wake = MAX_THREADS;

	do {
		ret = futex2_wake(futex_ptr, to_wake, futex_flags);

		if (err_value) {
			if (ret >= 0)
				ksft_exit_fail_msg("futex2_wake(%d, 0x%x) should fail, but didn't\n",
						   to_wake, futex_flags);

			if (errno != err_value)
				ksft_exit_fail_msg("futex2_wake(%d, 0x%x) expected error was %d, but returned %d (%s)\n",
						   to_wake, futex_flags, err_value, errno, strerror(errno));

			break;
		}
		if (ret < 0) {
			ksft_exit_fail_msg("Failed futex2_wake(%d, 0x%x): %m\n",
					   to_wake, futex_flags);
		}
		if (!ret)
			usleep(50);
		to_wake -= ret;

	} while (to_wake);
	join_max_threads();

	for (i = 0; i < MAX_THREADS; i++) {
		if (err_value && thread_args[i].result != -1) {
			ksft_print_msg("Thread %d should fail but succeeded (%d)\n",
				       i, thread_args[i].result);

Annotation

Implementation Notes