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

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/futex/functional/futex_waitv.c
Extension
.c
Size
5359 bytes
Lines
229
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

if (shm_id < 0) {
			if (errno == ENOSYS)
				ksft_exit_skip("shmget syscall not supported\n");
			perror("shmget");
			exit(1);
		}

		unsigned int *shared_data = shmat(shm_id, NULL, 0);

		*shared_data = 0;
		waitv[i].uaddr = (uintptr_t)shared_data;
		waitv[i].flags = FUTEX_32;
		waitv[i].val = 0;
		waitv[i].__reserved = 0;
	}

	if (pthread_create(&waiter, NULL, waiterfn, NULL))
		ksft_exit_fail_msg("pthread_create failed\n");

	usleep(WAKE_WAIT_US);

	res = futex_wake(u64_to_ptr(waitv[NR_FUTEXES - 1].uaddr), 1, 0);
	if (res != 1) {
		ksft_test_result_fail("futex_wake shared returned: %d %s\n",
				      res ? errno : res,
				      res ? strerror(errno) : "");
	} else {
		ksft_test_result_pass("futex_waitv shared\n");
	}

	for (i = 0; i < NR_FUTEXES; i++)
		shmdt(u64_to_ptr(waitv[i].uaddr));
}

TEST(invalid_flag)
{
	struct timespec to;
	int res;

	/* Testing a waiter without FUTEX_32 flag */
	waitv[0].flags = FUTEX_PRIVATE_FLAG;

	if (clock_gettime(CLOCK_MONOTONIC, &to))
		ksft_exit_fail_msg("gettime64 failed\n");

	to.tv_sec++;

	res = futex_waitv(waitv, NR_FUTEXES, 0, &to, CLOCK_MONOTONIC);
	if (res == EINVAL) {
		ksft_test_result_fail("futex_waitv private returned: %d %s\n",
				      res ? errno : res,
				      res ? strerror(errno) : "");
	} else {
		ksft_test_result_pass("futex_waitv without FUTEX_32\n");
	}
}

TEST(unaligned_address)
{
	struct timespec to;
	int res;

	/* Testing a waiter with an unaligned address */
	waitv[0].flags = FUTEX_PRIVATE_FLAG | FUTEX_32;
	waitv[0].uaddr = 1;

	if (clock_gettime(CLOCK_MONOTONIC, &to))
		ksft_exit_fail_msg("gettime64 failed\n");

	to.tv_sec++;

	res = futex_waitv(waitv, NR_FUTEXES, 0, &to, CLOCK_MONOTONIC);
	if (res == EINVAL) {
		ksft_test_result_fail("futex_wake private returned: %d %s\n",
				      res ? errno : res,
				      res ? strerror(errno) : "");
	} else {
		ksft_test_result_pass("futex_waitv with an unaligned address\n");
	}
}

TEST(null_address)
{
	struct timespec to;
	int res;

	/* Testing a NULL address for waiters.uaddr */
	waitv[0].uaddr = 0x00000000;

	if (clock_gettime(CLOCK_MONOTONIC, &to))

Annotation

Implementation Notes