Skip to content

Commit

Permalink
selftests: ntsync: Add some tests for wakeup signaling with WINESYNC_…
Browse files Browse the repository at this point in the history
…IOC_WAIT_ALL.

Test contended "wait-for-all" waits, to make sure that scheduling and wakeup
logic works correctly, and that the wait only exits once objects are all
simultaneously signaled.

Signed-off-by: Elizabeth Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Frade <kernel@xanmod.org>
  • Loading branch information
Elizabeth Figura authored and xanmod committed Mar 1, 2024
1 parent 63e55ce commit 5785db9
Showing 1 changed file with 98 additions and 0 deletions.
98 changes: 98 additions & 0 deletions tools/testing/selftests/drivers/ntsync/ntsync.c
Original file line number Diff line number Diff line change
Expand Up @@ -706,4 +706,102 @@ TEST(wake_any)
close(fd);
}

TEST(wake_all)
{
struct ntsync_mutex_args mutex_args = {0};
struct ntsync_wait_args wait_args = {0};
struct ntsync_sem_args sem_args = {0};
struct wait_args thread_args;
int objs[2], fd, ret;
__u32 count, index;
pthread_t thread;

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

sem_args.count = 0;
sem_args.max = 3;
sem_args.sem = 0xdeadbeef;
ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
EXPECT_EQ(0, ret);
EXPECT_NE(0xdeadbeef, sem_args.sem);

mutex_args.owner = 123;
mutex_args.count = 1;
mutex_args.mutex = 0xdeadbeef;
ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
EXPECT_EQ(0, ret);
EXPECT_NE(0xdeadbeef, mutex_args.mutex);

objs[0] = sem_args.sem;
objs[1] = mutex_args.mutex;

wait_args.timeout = get_abs_timeout(1000);
wait_args.objs = (uintptr_t)objs;
wait_args.count = 2;
wait_args.owner = 456;
thread_args.fd = fd;
thread_args.args = &wait_args;
thread_args.request = NTSYNC_IOC_WAIT_ALL;
ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
EXPECT_EQ(0, ret);

ret = wait_for_thread(thread, 100);
EXPECT_EQ(ETIMEDOUT, ret);

count = 1;
ret = post_sem(sem_args.sem, &count);
EXPECT_EQ(0, ret);
EXPECT_EQ(0, count);

ret = pthread_tryjoin_np(thread, NULL);
EXPECT_EQ(EBUSY, ret);

check_sem_state(sem_args.sem, 1, 3);

ret = wait_any(fd, 1, &sem_args.sem, 123, &index);
EXPECT_EQ(0, ret);
EXPECT_EQ(0, index);

ret = unlock_mutex(mutex_args.mutex, 123, &count);
EXPECT_EQ(0, ret);
EXPECT_EQ(1, count);

ret = pthread_tryjoin_np(thread, NULL);
EXPECT_EQ(EBUSY, ret);

check_mutex_state(mutex_args.mutex, 0, 0);

count = 2;
ret = post_sem(sem_args.sem, &count);
EXPECT_EQ(0, ret);
EXPECT_EQ(0, count);
check_sem_state(sem_args.sem, 1, 3);
check_mutex_state(mutex_args.mutex, 1, 456);

ret = wait_for_thread(thread, 100);
EXPECT_EQ(0, ret);
EXPECT_EQ(0, thread_args.ret);

/* delete an object while it's being waited on */

wait_args.timeout = get_abs_timeout(200);
wait_args.owner = 123;
ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
EXPECT_EQ(0, ret);

ret = wait_for_thread(thread, 100);
EXPECT_EQ(ETIMEDOUT, ret);

close(sem_args.sem);
close(mutex_args.mutex);

ret = wait_for_thread(thread, 200);
EXPECT_EQ(0, ret);
EXPECT_EQ(-1, thread_args.ret);
EXPECT_EQ(ETIMEDOUT, thread_args.err);

close(fd);
}

TEST_HARNESS_MAIN

0 comments on commit 5785db9

Please sign in to comment.