Commit 44554569 authored by Elizabeth Figura's avatar Elizabeth Figura Committed by Greg Kroah-Hartman
Browse files

selftests: ntsync: Add some tests for NTSYNC_IOC_WAIT_ANY.



Test basic synchronous functionality of NTSYNC_IOC_WAIT_ANY, when objects are
considered signaled or not signaled, and how they are affected by a successful
wait.

Signed-off-by: default avatarElizabeth Figura <zfigura@codeweavers.com>
Link: https://lore.kernel.org/r/20241213193511.457338-19-zfigura@codeweavers.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent ae071aef
Loading
Loading
Loading
Loading
+114 −0
Original line number Diff line number Diff line
@@ -329,4 +329,118 @@ TEST(mutex_state)
	close(fd);
}

TEST(test_wait_any)
{
	int objs[NTSYNC_MAX_WAIT_COUNT + 1], fd, ret;
	struct ntsync_mutex_args mutex_args = {0};
	struct ntsync_sem_args sem_args = {0};
	__u32 owner, index, count, i;
	struct timespec timeout;

	clock_gettime(CLOCK_MONOTONIC, &timeout);

	fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
	ASSERT_LE(0, fd);

	sem_args.count = 2;
	sem_args.max = 3;
	objs[0] = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
	EXPECT_LE(0, objs[0]);

	mutex_args.owner = 0;
	mutex_args.count = 0;
	objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
	EXPECT_LE(0, objs[1]);

	ret = wait_any(fd, 2, objs, 123, &index);
	EXPECT_EQ(0, ret);
	EXPECT_EQ(0, index);
	check_sem_state(objs[0], 1, 3);
	check_mutex_state(objs[1], 0, 0);

	ret = wait_any(fd, 2, objs, 123, &index);
	EXPECT_EQ(0, ret);
	EXPECT_EQ(0, index);
	check_sem_state(objs[0], 0, 3);
	check_mutex_state(objs[1], 0, 0);

	ret = wait_any(fd, 2, objs, 123, &index);
	EXPECT_EQ(0, ret);
	EXPECT_EQ(1, index);
	check_sem_state(objs[0], 0, 3);
	check_mutex_state(objs[1], 1, 123);

	count = 1;
	ret = release_sem(objs[0], &count);
	EXPECT_EQ(0, ret);
	EXPECT_EQ(0, count);

	ret = wait_any(fd, 2, objs, 123, &index);
	EXPECT_EQ(0, ret);
	EXPECT_EQ(0, index);
	check_sem_state(objs[0], 0, 3);
	check_mutex_state(objs[1], 1, 123);

	ret = wait_any(fd, 2, objs, 123, &index);
	EXPECT_EQ(0, ret);
	EXPECT_EQ(1, index);
	check_sem_state(objs[0], 0, 3);
	check_mutex_state(objs[1], 2, 123);

	ret = wait_any(fd, 2, objs, 456, &index);
	EXPECT_EQ(-1, ret);
	EXPECT_EQ(ETIMEDOUT, errno);

	owner = 123;
	ret = ioctl(objs[1], NTSYNC_IOC_MUTEX_KILL, &owner);
	EXPECT_EQ(0, ret);

	ret = wait_any(fd, 2, objs, 456, &index);
	EXPECT_EQ(-1, ret);
	EXPECT_EQ(EOWNERDEAD, errno);
	EXPECT_EQ(1, index);

	ret = wait_any(fd, 2, objs, 456, &index);
	EXPECT_EQ(0, ret);
	EXPECT_EQ(1, index);

	close(objs[1]);

	/* test waiting on the same object twice */

	count = 2;
	ret = release_sem(objs[0], &count);
	EXPECT_EQ(0, ret);
	EXPECT_EQ(0, count);

	objs[1] = objs[0];
	ret = wait_any(fd, 2, objs, 456, &index);
	EXPECT_EQ(0, ret);
	EXPECT_EQ(0, index);
	check_sem_state(objs[0], 1, 3);

	ret = wait_any(fd, 0, NULL, 456, &index);
	EXPECT_EQ(-1, ret);
	EXPECT_EQ(ETIMEDOUT, errno);

	for (i = 1; i < NTSYNC_MAX_WAIT_COUNT + 1; ++i)
		objs[i] = objs[0];

	ret = wait_any(fd, NTSYNC_MAX_WAIT_COUNT, objs, 123, &index);
	EXPECT_EQ(0, ret);
	EXPECT_EQ(0, index);

	ret = wait_any(fd, NTSYNC_MAX_WAIT_COUNT + 1, objs, 123, &index);
	EXPECT_EQ(-1, ret);
	EXPECT_EQ(EINVAL, errno);

	ret = wait_any(fd, -1, objs, 123, &index);
	EXPECT_EQ(-1, ret);
	EXPECT_EQ(EINVAL, errno);

	close(objs[0]);

	close(fd);
}

TEST_HARNESS_MAIN