Test basic synchronous functionality of NTSYNC_IOC_WAIT_ALL, and when objects
are considered simultaneously signaled.

Signed-off-by: Elizabeth Figura <zfig...@codeweavers.com>
---
 .../testing/selftests/drivers/ntsync/ntsync.c | 99 ++++++++++++++++++-
 1 file changed, 97 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c 
b/tools/testing/selftests/drivers/ntsync/ntsync.c
index 40ad8cbd3138..c0f372167557 100644
--- a/tools/testing/selftests/drivers/ntsync/ntsync.c
+++ b/tools/testing/selftests/drivers/ntsync/ntsync.c
@@ -73,7 +73,8 @@ static int unlock_mutex(int mutex, __u32 owner, __u32 *count)
        return ret;
 }
 
-static int wait_any(int fd, __u32 count, const int *objs, __u32 owner, __u32 
*index)
+static int wait_objs(int fd, unsigned long request, __u32 count,
+                    const int *objs, __u32 owner, __u32 *index)
 {
        struct ntsync_wait_args args = {0};
        struct timespec timeout;
@@ -86,11 +87,21 @@ static int wait_any(int fd, __u32 count, const int *objs, 
__u32 owner, __u32 *in
        args.objs = (uintptr_t)objs;
        args.owner = owner;
        args.index = 0xdeadbeef;
-       ret = ioctl(fd, NTSYNC_IOC_WAIT_ANY, &args);
+       ret = ioctl(fd, request, &args);
        *index = args.index;
        return ret;
 }
 
+static int wait_any(int fd, __u32 count, const int *objs, __u32 owner, __u32 
*index)
+{
+       return wait_objs(fd, NTSYNC_IOC_WAIT_ANY, count, objs, owner, index);
+}
+
+static int wait_all(int fd, __u32 count, const int *objs, __u32 owner, __u32 
*index)
+{
+       return wait_objs(fd, NTSYNC_IOC_WAIT_ALL, count, objs, owner, index);
+}
+
 TEST(semaphore_state)
 {
        struct ntsync_sem_args sem_args;
@@ -461,4 +472,88 @@ TEST(test_wait_any)
        close(fd);
 }
 
+TEST(test_wait_all)
+{
+       struct ntsync_mutex_args mutex_args = {0};
+       struct ntsync_sem_args sem_args = {0};
+       __u32 owner, index, count;
+       int objs[2], fd, ret;
+
+       fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
+       ASSERT_LE(0, fd);
+
+       sem_args.count = 2;
+       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 = 0;
+       mutex_args.count = 0;
+       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;
+
+       ret = wait_all(fd, 2, objs, 123, &index);
+       EXPECT_EQ(0, ret);
+       EXPECT_EQ(0, index);
+       check_sem_state(sem_args.sem, 1, 3);
+       check_mutex_state(mutex_args.mutex, 1, 123);
+
+       ret = wait_all(fd, 2, objs, 456, &index);
+       EXPECT_EQ(-1, ret);
+       EXPECT_EQ(ETIMEDOUT, errno);
+       check_sem_state(sem_args.sem, 1, 3);
+       check_mutex_state(mutex_args.mutex, 1, 123);
+
+       ret = wait_all(fd, 2, objs, 123, &index);
+       EXPECT_EQ(0, ret);
+       EXPECT_EQ(0, index);
+       check_sem_state(sem_args.sem, 0, 3);
+       check_mutex_state(mutex_args.mutex, 2, 123);
+
+       ret = wait_all(fd, 2, objs, 123, &index);
+       EXPECT_EQ(-1, ret);
+       EXPECT_EQ(ETIMEDOUT, errno);
+       check_sem_state(sem_args.sem, 0, 3);
+       check_mutex_state(mutex_args.mutex, 2, 123);
+
+       count = 3;
+       ret = post_sem(sem_args.sem, &count);
+       EXPECT_EQ(0, ret);
+       EXPECT_EQ(0, count);
+
+       ret = wait_all(fd, 2, objs, 123, &index);
+       EXPECT_EQ(0, ret);
+       EXPECT_EQ(0, index);
+       check_sem_state(sem_args.sem, 2, 3);
+       check_mutex_state(mutex_args.mutex, 3, 123);
+
+       owner = 123;
+       ret = ioctl(mutex_args.mutex, NTSYNC_IOC_MUTEX_KILL, &owner);
+       EXPECT_EQ(0, ret);
+
+       ret = wait_all(fd, 2, objs, 123, &index);
+       EXPECT_EQ(-1, ret);
+       EXPECT_EQ(EOWNERDEAD, errno);
+       check_sem_state(sem_args.sem, 1, 3);
+       check_mutex_state(mutex_args.mutex, 1, 123);
+
+       /* test waiting on the same object twice */
+       objs[0] = objs[1] = sem_args.sem;
+       ret = wait_all(fd, 2, objs, 123, &index);
+       EXPECT_EQ(-1, ret);
+       EXPECT_EQ(EINVAL, errno);
+
+       close(sem_args.sem);
+       close(mutex_args.mutex);
+
+       close(fd);
+}
+
 TEST_HARNESS_MAIN
-- 
2.43.0


Reply via email to