projects/linux·blob master · refs

1474 lines · 34.3 KiB

1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Various unit tests for the "ntsync" synchronization primitive driver.
4 *
5 * Copyright (C) 2021-2022 Elizabeth Figura <[email protected]>
6 */
7
8#define _GNU_SOURCE
9#include <sys/ioctl.h>
10#include <sys/stat.h>
11#include <sys/wait.h>
12#include <fcntl.h>
13#include <sched.h>
14#include <time.h>
15#include <pthread.h>
16#include <linux/ntsync.h>
17#include "kselftest_harness.h"
18
19#ifndef CLONE_NEWTIME
20#define CLONE_NEWTIME 0x00000080
21#endif
22
23static int read_sem_state(int sem, __u32 *count, __u32 *max)
24{
25 struct ntsync_sem_args args;
26 int ret;
27
28 memset(&args, 0xcc, sizeof(args));
29 ret = ioctl(sem, NTSYNC_IOC_SEM_READ, &args);
30 *count = args.count;
31 *max = args.max;
32 return ret;
33}
34
35#define check_sem_state(sem, count, max) \
36 ({ \
37 __u32 __count, __max; \
38 int ret = read_sem_state((sem), &__count, &__max); \
39 EXPECT_EQ(0, ret); \
40 EXPECT_EQ((count), __count); \
41 EXPECT_EQ((max), __max); \
42 })
43
44static int release_sem(int sem, __u32 *count)
45{
46 return ioctl(sem, NTSYNC_IOC_SEM_RELEASE, count);
47}
48
49static int read_mutex_state(int mutex, __u32 *count, __u32 *owner)
50{
51 struct ntsync_mutex_args args;
52 int ret;
53
54 memset(&args, 0xcc, sizeof(args));
55 ret = ioctl(mutex, NTSYNC_IOC_MUTEX_READ, &args);
56 *count = args.count;
57 *owner = args.owner;
58 return ret;
59}
60
61#define check_mutex_state(mutex, count, owner) \
62 ({ \
63 __u32 __count, __owner; \
64 int ret = read_mutex_state((mutex), &__count, &__owner); \
65 EXPECT_EQ(0, ret); \
66 EXPECT_EQ((count), __count); \
67 EXPECT_EQ((owner), __owner); \
68 })
69
70static int unlock_mutex(int mutex, __u32 owner, __u32 *count)
71{
72 struct ntsync_mutex_args args;
73 int ret;
74
75 args.owner = owner;
76 args.count = 0xdeadbeef;
77 ret = ioctl(mutex, NTSYNC_IOC_MUTEX_UNLOCK, &args);
78 *count = args.count;
79 return ret;
80}
81
82static int read_event_state(int event, __u32 *signaled, __u32 *manual)
83{
84 struct ntsync_event_args args;
85 int ret;
86
87 memset(&args, 0xcc, sizeof(args));
88 ret = ioctl(event, NTSYNC_IOC_EVENT_READ, &args);
89 *signaled = args.signaled;
90 *manual = args.manual;
91 return ret;
92}
93
94#define check_event_state(event, signaled, manual) \
95 ({ \
96 __u32 __signaled, __manual; \
97 int ret = read_event_state((event), &__signaled, &__manual); \
98 EXPECT_EQ(0, ret); \
99 EXPECT_EQ((signaled), __signaled); \
100 EXPECT_EQ((manual), __manual); \
101 })
102
103static int wait_objs(int fd, unsigned long request, __u32 count,
104 const int *objs, __u32 owner, int alert, __u32 *index)
105{
106 struct ntsync_wait_args args = {0};
107 struct timespec timeout;
108 int ret;
109
110 clock_gettime(CLOCK_MONOTONIC, &timeout);
111
112 args.timeout = timeout.tv_sec * 1000000000 + timeout.tv_nsec;
113 args.count = count;
114 args.objs = (uintptr_t)objs;
115 args.owner = owner;
116 args.index = 0xdeadbeef;
117 args.alert = alert;
118 ret = ioctl(fd, request, &args);
119 *index = args.index;
120 return ret;
121}
122
123static int wait_any(int fd, __u32 count, const int *objs, __u32 owner, __u32 *index)
124{
125 return wait_objs(fd, NTSYNC_IOC_WAIT_ANY, count, objs, owner, 0, index);
126}
127
128static int wait_all(int fd, __u32 count, const int *objs, __u32 owner, __u32 *index)
129{
130 return wait_objs(fd, NTSYNC_IOC_WAIT_ALL, count, objs, owner, 0, index);
131}
132
133static int wait_any_alert(int fd, __u32 count, const int *objs,
134 __u32 owner, int alert, __u32 *index)
135{
136 return wait_objs(fd, NTSYNC_IOC_WAIT_ANY,
137 count, objs, owner, alert, index);
138}
139
140static int wait_all_alert(int fd, __u32 count, const int *objs,
141 __u32 owner, int alert, __u32 *index)
142{
143 return wait_objs(fd, NTSYNC_IOC_WAIT_ALL,
144 count, objs, owner, alert, index);
145}
146
147TEST(semaphore_state)
148{
149 struct ntsync_sem_args sem_args;
150 struct timespec timeout;
151 __u32 count, index;
152 int fd, ret, sem;
153
154 clock_gettime(CLOCK_MONOTONIC, &timeout);
155
156 fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
157 ASSERT_LE(0, fd);
158
159 sem_args.count = 3;
160 sem_args.max = 2;
161 sem = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
162 EXPECT_EQ(-1, sem);
163 EXPECT_EQ(EINVAL, errno);
164
165 sem_args.count = 2;
166 sem_args.max = 2;
167 sem = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
168 EXPECT_LE(0, sem);
169 check_sem_state(sem, 2, 2);
170
171 count = 0;
172 ret = release_sem(sem, &count);
173 EXPECT_EQ(0, ret);
174 EXPECT_EQ(2, count);
175 check_sem_state(sem, 2, 2);
176
177 count = 1;
178 ret = release_sem(sem, &count);
179 EXPECT_EQ(-1, ret);
180 EXPECT_EQ(EOVERFLOW, errno);
181 check_sem_state(sem, 2, 2);
182
183 ret = wait_any(fd, 1, &sem, 123, &index);
184 EXPECT_EQ(0, ret);
185 EXPECT_EQ(0, index);
186 check_sem_state(sem, 1, 2);
187
188 ret = wait_any(fd, 1, &sem, 123, &index);
189 EXPECT_EQ(0, ret);
190 EXPECT_EQ(0, index);
191 check_sem_state(sem, 0, 2);
192
193 ret = wait_any(fd, 1, &sem, 123, &index);
194 EXPECT_EQ(-1, ret);
195 EXPECT_EQ(ETIMEDOUT, errno);
196
197 count = 3;
198 ret = release_sem(sem, &count);
199 EXPECT_EQ(-1, ret);
200 EXPECT_EQ(EOVERFLOW, errno);
201 check_sem_state(sem, 0, 2);
202
203 count = 2;
204 ret = release_sem(sem, &count);
205 EXPECT_EQ(0, ret);
206 EXPECT_EQ(0, count);
207 check_sem_state(sem, 2, 2);
208
209 ret = wait_any(fd, 1, &sem, 123, &index);
210 EXPECT_EQ(0, ret);
211 ret = wait_any(fd, 1, &sem, 123, &index);
212 EXPECT_EQ(0, ret);
213
214 count = 1;
215 ret = release_sem(sem, &count);
216 EXPECT_EQ(0, ret);
217 EXPECT_EQ(0, count);
218 check_sem_state(sem, 1, 2);
219
220 count = ~0u;
221 ret = release_sem(sem, &count);
222 EXPECT_EQ(-1, ret);
223 EXPECT_EQ(EOVERFLOW, errno);
224 check_sem_state(sem, 1, 2);
225
226 close(sem);
227
228 close(fd);
229}
230
231TEST(mutex_state)
232{
233 struct ntsync_mutex_args mutex_args;
234 __u32 owner, count, index;
235 struct timespec timeout;
236 int fd, ret, mutex;
237
238 clock_gettime(CLOCK_MONOTONIC, &timeout);
239
240 fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
241 ASSERT_LE(0, fd);
242
243 mutex_args.owner = 123;
244 mutex_args.count = 0;
245 mutex = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
246 EXPECT_EQ(-1, mutex);
247 EXPECT_EQ(EINVAL, errno);
248
249 mutex_args.owner = 0;
250 mutex_args.count = 2;
251 mutex = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
252 EXPECT_EQ(-1, mutex);
253 EXPECT_EQ(EINVAL, errno);
254
255 mutex_args.owner = 123;
256 mutex_args.count = 2;
257 mutex = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
258 EXPECT_LE(0, mutex);
259 check_mutex_state(mutex, 2, 123);
260
261 ret = unlock_mutex(mutex, 0, &count);
262 EXPECT_EQ(-1, ret);
263 EXPECT_EQ(EINVAL, errno);
264
265 ret = unlock_mutex(mutex, 456, &count);
266 EXPECT_EQ(-1, ret);
267 EXPECT_EQ(EPERM, errno);
268 check_mutex_state(mutex, 2, 123);
269
270 ret = unlock_mutex(mutex, 123, &count);
271 EXPECT_EQ(0, ret);
272 EXPECT_EQ(2, count);
273 check_mutex_state(mutex, 1, 123);
274
275 ret = unlock_mutex(mutex, 123, &count);
276 EXPECT_EQ(0, ret);
277 EXPECT_EQ(1, count);
278 check_mutex_state(mutex, 0, 0);
279
280 ret = unlock_mutex(mutex, 123, &count);
281 EXPECT_EQ(-1, ret);
282 EXPECT_EQ(EPERM, errno);
283
284 ret = wait_any(fd, 1, &mutex, 456, &index);
285 EXPECT_EQ(0, ret);
286 EXPECT_EQ(0, index);
287 check_mutex_state(mutex, 1, 456);
288
289 ret = wait_any(fd, 1, &mutex, 456, &index);
290 EXPECT_EQ(0, ret);
291 EXPECT_EQ(0, index);
292 check_mutex_state(mutex, 2, 456);
293
294 ret = unlock_mutex(mutex, 456, &count);
295 EXPECT_EQ(0, ret);
296 EXPECT_EQ(2, count);
297 check_mutex_state(mutex, 1, 456);
298
299 ret = wait_any(fd, 1, &mutex, 123, &index);
300 EXPECT_EQ(-1, ret);
301 EXPECT_EQ(ETIMEDOUT, errno);
302
303 owner = 0;
304 ret = ioctl(mutex, NTSYNC_IOC_MUTEX_KILL, &owner);
305 EXPECT_EQ(-1, ret);
306 EXPECT_EQ(EINVAL, errno);
307
308 owner = 123;
309 ret = ioctl(mutex, NTSYNC_IOC_MUTEX_KILL, &owner);
310 EXPECT_EQ(-1, ret);
311 EXPECT_EQ(EPERM, errno);
312 check_mutex_state(mutex, 1, 456);
313
314 owner = 456;
315 ret = ioctl(mutex, NTSYNC_IOC_MUTEX_KILL, &owner);
316 EXPECT_EQ(0, ret);
317
318 memset(&mutex_args, 0xcc, sizeof(mutex_args));
319 ret = ioctl(mutex, NTSYNC_IOC_MUTEX_READ, &mutex_args);
320 EXPECT_EQ(-1, ret);
321 EXPECT_EQ(EOWNERDEAD, errno);
322 EXPECT_EQ(0, mutex_args.count);
323 EXPECT_EQ(0, mutex_args.owner);
324
325 memset(&mutex_args, 0xcc, sizeof(mutex_args));
326 ret = ioctl(mutex, NTSYNC_IOC_MUTEX_READ, &mutex_args);
327 EXPECT_EQ(-1, ret);
328 EXPECT_EQ(EOWNERDEAD, errno);
329 EXPECT_EQ(0, mutex_args.count);
330 EXPECT_EQ(0, mutex_args.owner);
331
332 ret = wait_any(fd, 1, &mutex, 123, &index);
333 EXPECT_EQ(-1, ret);
334 EXPECT_EQ(EOWNERDEAD, errno);
335 EXPECT_EQ(0, index);
336 check_mutex_state(mutex, 1, 123);
337
338 owner = 123;
339 ret = ioctl(mutex, NTSYNC_IOC_MUTEX_KILL, &owner);
340 EXPECT_EQ(0, ret);
341
342 memset(&mutex_args, 0xcc, sizeof(mutex_args));
343 ret = ioctl(mutex, NTSYNC_IOC_MUTEX_READ, &mutex_args);
344 EXPECT_EQ(-1, ret);
345 EXPECT_EQ(EOWNERDEAD, errno);
346 EXPECT_EQ(0, mutex_args.count);
347 EXPECT_EQ(0, mutex_args.owner);
348
349 ret = wait_any(fd, 1, &mutex, 123, &index);
350 EXPECT_EQ(-1, ret);
351 EXPECT_EQ(EOWNERDEAD, errno);
352 EXPECT_EQ(0, index);
353 check_mutex_state(mutex, 1, 123);
354
355 close(mutex);
356
357 mutex_args.owner = 0;
358 mutex_args.count = 0;
359 mutex = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
360 EXPECT_LE(0, mutex);
361 check_mutex_state(mutex, 0, 0);
362
363 ret = wait_any(fd, 1, &mutex, 123, &index);
364 EXPECT_EQ(0, ret);
365 EXPECT_EQ(0, index);
366 check_mutex_state(mutex, 1, 123);
367
368 close(mutex);
369
370 mutex_args.owner = 123;
371 mutex_args.count = ~0u;
372 mutex = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
373 EXPECT_LE(0, mutex);
374 check_mutex_state(mutex, ~0u, 123);
375
376 ret = wait_any(fd, 1, &mutex, 123, &index);
377 EXPECT_EQ(-1, ret);
378 EXPECT_EQ(ETIMEDOUT, errno);
379
380 close(mutex);
381
382 close(fd);
383}
384
385TEST(manual_event_state)
386{
387 struct ntsync_event_args event_args;
388 __u32 index, signaled;
389 int fd, event, ret;
390
391 fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
392 ASSERT_LE(0, fd);
393
394 event_args.manual = 1;
395 event_args.signaled = 0;
396 event = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
397 EXPECT_LE(0, event);
398 check_event_state(event, 0, 1);
399
400 signaled = 0xdeadbeef;
401 ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled);
402 EXPECT_EQ(0, ret);
403 EXPECT_EQ(0, signaled);
404 check_event_state(event, 1, 1);
405
406 ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled);
407 EXPECT_EQ(0, ret);
408 EXPECT_EQ(1, signaled);
409 check_event_state(event, 1, 1);
410
411 ret = wait_any(fd, 1, &event, 123, &index);
412 EXPECT_EQ(0, ret);
413 EXPECT_EQ(0, index);
414 check_event_state(event, 1, 1);
415
416 signaled = 0xdeadbeef;
417 ret = ioctl(event, NTSYNC_IOC_EVENT_RESET, &signaled);
418 EXPECT_EQ(0, ret);
419 EXPECT_EQ(1, signaled);
420 check_event_state(event, 0, 1);
421
422 ret = ioctl(event, NTSYNC_IOC_EVENT_RESET, &signaled);
423 EXPECT_EQ(0, ret);
424 EXPECT_EQ(0, signaled);
425 check_event_state(event, 0, 1);
426
427 ret = wait_any(fd, 1, &event, 123, &index);
428 EXPECT_EQ(-1, ret);
429 EXPECT_EQ(ETIMEDOUT, errno);
430
431 ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled);
432 EXPECT_EQ(0, ret);
433 EXPECT_EQ(0, signaled);
434
435 ret = ioctl(event, NTSYNC_IOC_EVENT_PULSE, &signaled);
436 EXPECT_EQ(0, ret);
437 EXPECT_EQ(1, signaled);
438 check_event_state(event, 0, 1);
439
440 ret = ioctl(event, NTSYNC_IOC_EVENT_PULSE, &signaled);
441 EXPECT_EQ(0, ret);
442 EXPECT_EQ(0, signaled);
443 check_event_state(event, 0, 1);
444
445 close(event);
446
447 close(fd);
448}
449
450TEST(auto_event_state)
451{
452 struct ntsync_event_args event_args;
453 __u32 index, signaled;
454 int fd, event, ret;
455
456 fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
457 ASSERT_LE(0, fd);
458
459 event_args.manual = 0;
460 event_args.signaled = 1;
461 event = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
462 EXPECT_LE(0, event);
463
464 check_event_state(event, 1, 0);
465
466 signaled = 0xdeadbeef;
467 ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled);
468 EXPECT_EQ(0, ret);
469 EXPECT_EQ(1, signaled);
470 check_event_state(event, 1, 0);
471
472 ret = wait_any(fd, 1, &event, 123, &index);
473 EXPECT_EQ(0, ret);
474 EXPECT_EQ(0, index);
475 check_event_state(event, 0, 0);
476
477 signaled = 0xdeadbeef;
478 ret = ioctl(event, NTSYNC_IOC_EVENT_RESET, &signaled);
479 EXPECT_EQ(0, ret);
480 EXPECT_EQ(0, signaled);
481 check_event_state(event, 0, 0);
482
483 ret = wait_any(fd, 1, &event, 123, &index);
484 EXPECT_EQ(-1, ret);
485 EXPECT_EQ(ETIMEDOUT, errno);
486
487 ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled);
488 EXPECT_EQ(0, ret);
489 EXPECT_EQ(0, signaled);
490
491 ret = ioctl(event, NTSYNC_IOC_EVENT_PULSE, &signaled);
492 EXPECT_EQ(0, ret);
493 EXPECT_EQ(1, signaled);
494 check_event_state(event, 0, 0);
495
496 ret = ioctl(event, NTSYNC_IOC_EVENT_PULSE, &signaled);
497 EXPECT_EQ(0, ret);
498 EXPECT_EQ(0, signaled);
499 check_event_state(event, 0, 0);
500
501 close(event);
502
503 close(fd);
504}
505
506TEST(test_wait_any)
507{
508 int objs[NTSYNC_MAX_WAIT_COUNT + 1], fd, ret;
509 struct ntsync_mutex_args mutex_args = {0};
510 struct ntsync_sem_args sem_args = {0};
511 __u32 owner, index, count, i;
512 struct timespec timeout;
513
514 clock_gettime(CLOCK_MONOTONIC, &timeout);
515
516 fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
517 ASSERT_LE(0, fd);
518
519 sem_args.count = 2;
520 sem_args.max = 3;
521 objs[0] = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
522 EXPECT_LE(0, objs[0]);
523
524 mutex_args.owner = 0;
525 mutex_args.count = 0;
526 objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
527 EXPECT_LE(0, objs[1]);
528
529 ret = wait_any(fd, 2, objs, 123, &index);
530 EXPECT_EQ(0, ret);
531 EXPECT_EQ(0, index);
532 check_sem_state(objs[0], 1, 3);
533 check_mutex_state(objs[1], 0, 0);
534
535 ret = wait_any(fd, 2, objs, 123, &index);
536 EXPECT_EQ(0, ret);
537 EXPECT_EQ(0, index);
538 check_sem_state(objs[0], 0, 3);
539 check_mutex_state(objs[1], 0, 0);
540
541 ret = wait_any(fd, 2, objs, 123, &index);
542 EXPECT_EQ(0, ret);
543 EXPECT_EQ(1, index);
544 check_sem_state(objs[0], 0, 3);
545 check_mutex_state(objs[1], 1, 123);
546
547 count = 1;
548 ret = release_sem(objs[0], &count);
549 EXPECT_EQ(0, ret);
550 EXPECT_EQ(0, count);
551
552 ret = wait_any(fd, 2, objs, 123, &index);
553 EXPECT_EQ(0, ret);
554 EXPECT_EQ(0, index);
555 check_sem_state(objs[0], 0, 3);
556 check_mutex_state(objs[1], 1, 123);
557
558 ret = wait_any(fd, 2, objs, 123, &index);
559 EXPECT_EQ(0, ret);
560 EXPECT_EQ(1, index);
561 check_sem_state(objs[0], 0, 3);
562 check_mutex_state(objs[1], 2, 123);
563
564 ret = wait_any(fd, 2, objs, 456, &index);
565 EXPECT_EQ(-1, ret);
566 EXPECT_EQ(ETIMEDOUT, errno);
567
568 owner = 123;
569 ret = ioctl(objs[1], NTSYNC_IOC_MUTEX_KILL, &owner);
570 EXPECT_EQ(0, ret);
571
572 ret = wait_any(fd, 2, objs, 456, &index);
573 EXPECT_EQ(-1, ret);
574 EXPECT_EQ(EOWNERDEAD, errno);
575 EXPECT_EQ(1, index);
576
577 ret = wait_any(fd, 2, objs, 456, &index);
578 EXPECT_EQ(0, ret);
579 EXPECT_EQ(1, index);
580
581 close(objs[1]);
582
583 /* test waiting on the same object twice */
584
585 count = 2;
586 ret = release_sem(objs[0], &count);
587 EXPECT_EQ(0, ret);
588 EXPECT_EQ(0, count);
589
590 objs[1] = objs[0];
591 ret = wait_any(fd, 2, objs, 456, &index);
592 EXPECT_EQ(0, ret);
593 EXPECT_EQ(0, index);
594 check_sem_state(objs[0], 1, 3);
595
596 ret = wait_any(fd, 0, NULL, 456, &index);
597 EXPECT_EQ(-1, ret);
598 EXPECT_EQ(ETIMEDOUT, errno);
599
600 for (i = 1; i < NTSYNC_MAX_WAIT_COUNT + 1; ++i)
601 objs[i] = objs[0];
602
603 ret = wait_any(fd, NTSYNC_MAX_WAIT_COUNT, objs, 123, &index);
604 EXPECT_EQ(0, ret);
605 EXPECT_EQ(0, index);
606
607 ret = wait_any(fd, NTSYNC_MAX_WAIT_COUNT + 1, objs, 123, &index);
608 EXPECT_EQ(-1, ret);
609 EXPECT_EQ(EINVAL, errno);
610
611 ret = wait_any(fd, -1, objs, 123, &index);
612 EXPECT_EQ(-1, ret);
613 EXPECT_EQ(EINVAL, errno);
614
615 close(objs[0]);
616
617 close(fd);
618}
619
620TEST(test_wait_all)
621{
622 struct ntsync_event_args event_args = {0};
623 struct ntsync_mutex_args mutex_args = {0};
624 struct ntsync_sem_args sem_args = {0};
625 __u32 owner, index, count;
626 int objs[2], fd, ret;
627
628 fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
629 ASSERT_LE(0, fd);
630
631 sem_args.count = 2;
632 sem_args.max = 3;
633 objs[0] = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
634 EXPECT_LE(0, objs[0]);
635
636 mutex_args.owner = 0;
637 mutex_args.count = 0;
638 objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
639 EXPECT_LE(0, objs[1]);
640
641 ret = wait_all(fd, 2, objs, 123, &index);
642 EXPECT_EQ(0, ret);
643 EXPECT_EQ(0, index);
644 check_sem_state(objs[0], 1, 3);
645 check_mutex_state(objs[1], 1, 123);
646
647 ret = wait_all(fd, 2, objs, 456, &index);
648 EXPECT_EQ(-1, ret);
649 EXPECT_EQ(ETIMEDOUT, errno);
650 check_sem_state(objs[0], 1, 3);
651 check_mutex_state(objs[1], 1, 123);
652
653 ret = wait_all(fd, 2, objs, 123, &index);
654 EXPECT_EQ(0, ret);
655 EXPECT_EQ(0, index);
656 check_sem_state(objs[0], 0, 3);
657 check_mutex_state(objs[1], 2, 123);
658
659 ret = wait_all(fd, 2, objs, 123, &index);
660 EXPECT_EQ(-1, ret);
661 EXPECT_EQ(ETIMEDOUT, errno);
662 check_sem_state(objs[0], 0, 3);
663 check_mutex_state(objs[1], 2, 123);
664
665 count = 3;
666 ret = release_sem(objs[0], &count);
667 EXPECT_EQ(0, ret);
668 EXPECT_EQ(0, count);
669
670 ret = wait_all(fd, 2, objs, 123, &index);
671 EXPECT_EQ(0, ret);
672 EXPECT_EQ(0, index);
673 check_sem_state(objs[0], 2, 3);
674 check_mutex_state(objs[1], 3, 123);
675
676 owner = 123;
677 ret = ioctl(objs[1], NTSYNC_IOC_MUTEX_KILL, &owner);
678 EXPECT_EQ(0, ret);
679
680 ret = wait_all(fd, 2, objs, 123, &index);
681 EXPECT_EQ(-1, ret);
682 EXPECT_EQ(EOWNERDEAD, errno);
683 check_sem_state(objs[0], 1, 3);
684 check_mutex_state(objs[1], 1, 123);
685
686 close(objs[1]);
687
688 event_args.manual = true;
689 event_args.signaled = true;
690 objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
691 EXPECT_LE(0, objs[1]);
692
693 ret = wait_all(fd, 2, objs, 123, &index);
694 EXPECT_EQ(0, ret);
695 EXPECT_EQ(0, index);
696 check_sem_state(objs[0], 0, 3);
697 check_event_state(objs[1], 1, 1);
698
699 close(objs[1]);
700
701 /* test waiting on the same object twice */
702 objs[1] = objs[0];
703 ret = wait_all(fd, 2, objs, 123, &index);
704 EXPECT_EQ(-1, ret);
705 EXPECT_EQ(EINVAL, errno);
706
707 close(objs[0]);
708
709 close(fd);
710}
711
712struct wake_args {
713 int fd;
714 int obj;
715};
716
717struct wait_args {
718 int fd;
719 unsigned long request;
720 struct ntsync_wait_args *args;
721 int ret;
722 int err;
723};
724
725static void *wait_thread(void *arg)
726{
727 struct wait_args *args = arg;
728
729 args->ret = ioctl(args->fd, args->request, args->args);
730 args->err = errno;
731 return NULL;
732}
733
734static __u64 get_abs_timeout(unsigned int ms)
735{
736 struct timespec timeout;
737 clock_gettime(CLOCK_MONOTONIC, &timeout);
738 return (timeout.tv_sec * 1000000000) + timeout.tv_nsec + (ms * 1000000);
739}
740
741static int wait_for_thread(pthread_t thread, unsigned int ms)
742{
743 struct timespec timeout;
744
745 clock_gettime(CLOCK_REALTIME, &timeout);
746 timeout.tv_nsec += ms * 1000000;
747 timeout.tv_sec += (timeout.tv_nsec / 1000000000);
748 timeout.tv_nsec %= 1000000000;
749 return pthread_timedjoin_np(thread, NULL, &timeout);
750}
751
752TEST(wake_any)
753{
754 struct ntsync_event_args event_args = {0};
755 struct ntsync_mutex_args mutex_args = {0};
756 struct ntsync_wait_args wait_args = {0};
757 struct ntsync_sem_args sem_args = {0};
758 struct wait_args thread_args;
759 __u32 count, index, signaled;
760 int objs[2], fd, ret;
761 pthread_t thread;
762
763 fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
764 ASSERT_LE(0, fd);
765
766 sem_args.count = 0;
767 sem_args.max = 3;
768 objs[0] = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
769 EXPECT_LE(0, objs[0]);
770
771 mutex_args.owner = 123;
772 mutex_args.count = 1;
773 objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
774 EXPECT_LE(0, objs[1]);
775
776 /* test waking the semaphore */
777
778 wait_args.timeout = get_abs_timeout(1000);
779 wait_args.objs = (uintptr_t)objs;
780 wait_args.count = 2;
781 wait_args.owner = 456;
782 wait_args.index = 0xdeadbeef;
783 thread_args.fd = fd;
784 thread_args.args = &wait_args;
785 thread_args.request = NTSYNC_IOC_WAIT_ANY;
786 ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
787 EXPECT_EQ(0, ret);
788
789 ret = wait_for_thread(thread, 100);
790 EXPECT_EQ(ETIMEDOUT, ret);
791
792 count = 1;
793 ret = release_sem(objs[0], &count);
794 EXPECT_EQ(0, ret);
795 EXPECT_EQ(0, count);
796 check_sem_state(objs[0], 0, 3);
797
798 ret = wait_for_thread(thread, 100);
799 EXPECT_EQ(0, ret);
800 EXPECT_EQ(0, thread_args.ret);
801 EXPECT_EQ(0, wait_args.index);
802
803 /* test waking the mutex */
804
805 /* first grab it again for owner 123 */
806 ret = wait_any(fd, 1, &objs[1], 123, &index);
807 EXPECT_EQ(0, ret);
808 EXPECT_EQ(0, index);
809
810 wait_args.timeout = get_abs_timeout(1000);
811 wait_args.owner = 456;
812 ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
813 EXPECT_EQ(0, ret);
814
815 ret = wait_for_thread(thread, 100);
816 EXPECT_EQ(ETIMEDOUT, ret);
817
818 ret = unlock_mutex(objs[1], 123, &count);
819 EXPECT_EQ(0, ret);
820 EXPECT_EQ(2, count);
821
822 ret = pthread_tryjoin_np(thread, NULL);
823 EXPECT_EQ(EBUSY, ret);
824
825 ret = unlock_mutex(objs[1], 123, &count);
826 EXPECT_EQ(0, ret);
827 EXPECT_EQ(1, mutex_args.count);
828 check_mutex_state(objs[1], 1, 456);
829
830 ret = wait_for_thread(thread, 100);
831 EXPECT_EQ(0, ret);
832 EXPECT_EQ(0, thread_args.ret);
833 EXPECT_EQ(1, wait_args.index);
834
835 close(objs[1]);
836
837 /* test waking events */
838
839 event_args.manual = false;
840 event_args.signaled = false;
841 objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
842 EXPECT_LE(0, objs[1]);
843
844 wait_args.timeout = get_abs_timeout(1000);
845 ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
846 EXPECT_EQ(0, ret);
847
848 ret = wait_for_thread(thread, 100);
849 EXPECT_EQ(ETIMEDOUT, ret);
850
851 ret = ioctl(objs[1], NTSYNC_IOC_EVENT_SET, &signaled);
852 EXPECT_EQ(0, ret);
853 EXPECT_EQ(0, signaled);
854 check_event_state(objs[1], 0, 0);
855
856 ret = wait_for_thread(thread, 100);
857 EXPECT_EQ(0, ret);
858 EXPECT_EQ(0, thread_args.ret);
859 EXPECT_EQ(1, wait_args.index);
860
861 wait_args.timeout = get_abs_timeout(1000);
862 ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
863 EXPECT_EQ(0, ret);
864
865 ret = wait_for_thread(thread, 100);
866 EXPECT_EQ(ETIMEDOUT, ret);
867
868 ret = ioctl(objs[1], NTSYNC_IOC_EVENT_PULSE, &signaled);
869 EXPECT_EQ(0, ret);
870 EXPECT_EQ(0, signaled);
871 check_event_state(objs[1], 0, 0);
872
873 ret = wait_for_thread(thread, 100);
874 EXPECT_EQ(0, ret);
875 EXPECT_EQ(0, thread_args.ret);
876 EXPECT_EQ(1, wait_args.index);
877
878 close(objs[1]);
879
880 event_args.manual = true;
881 event_args.signaled = false;
882 objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
883 EXPECT_LE(0, objs[1]);
884
885 wait_args.timeout = get_abs_timeout(1000);
886 ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
887 EXPECT_EQ(0, ret);
888
889 ret = wait_for_thread(thread, 100);
890 EXPECT_EQ(ETIMEDOUT, ret);
891
892 ret = ioctl(objs[1], NTSYNC_IOC_EVENT_SET, &signaled);
893 EXPECT_EQ(0, ret);
894 EXPECT_EQ(0, signaled);
895 check_event_state(objs[1], 1, 1);
896
897 ret = wait_for_thread(thread, 100);
898 EXPECT_EQ(0, ret);
899 EXPECT_EQ(0, thread_args.ret);
900 EXPECT_EQ(1, wait_args.index);
901
902 ret = ioctl(objs[1], NTSYNC_IOC_EVENT_RESET, &signaled);
903 EXPECT_EQ(0, ret);
904 EXPECT_EQ(1, signaled);
905
906 wait_args.timeout = get_abs_timeout(1000);
907 ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
908 EXPECT_EQ(0, ret);
909
910 ret = wait_for_thread(thread, 100);
911 EXPECT_EQ(ETIMEDOUT, ret);
912
913 ret = ioctl(objs[1], NTSYNC_IOC_EVENT_PULSE, &signaled);
914 EXPECT_EQ(0, ret);
915 EXPECT_EQ(0, signaled);
916 check_event_state(objs[1], 0, 1);
917
918 ret = wait_for_thread(thread, 100);
919 EXPECT_EQ(0, ret);
920 EXPECT_EQ(0, thread_args.ret);
921 EXPECT_EQ(1, wait_args.index);
922
923 /* delete an object while it's being waited on */
924
925 wait_args.timeout = get_abs_timeout(200);
926 wait_args.owner = 123;
927 ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
928 EXPECT_EQ(0, ret);
929
930 ret = wait_for_thread(thread, 100);
931 EXPECT_EQ(ETIMEDOUT, ret);
932
933 close(objs[0]);
934 close(objs[1]);
935
936 ret = wait_for_thread(thread, 200);
937 EXPECT_EQ(0, ret);
938 EXPECT_EQ(-1, thread_args.ret);
939 EXPECT_EQ(ETIMEDOUT, thread_args.err);
940
941 close(fd);
942}
943
944TEST(wake_all)
945{
946 struct ntsync_event_args manual_event_args = {0};
947 struct ntsync_event_args auto_event_args = {0};
948 struct ntsync_mutex_args mutex_args = {0};
949 struct ntsync_wait_args wait_args = {0};
950 struct ntsync_sem_args sem_args = {0};
951 struct wait_args thread_args;
952 __u32 count, index, signaled;
953 int objs[4], fd, ret;
954 pthread_t thread;
955
956 fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
957 ASSERT_LE(0, fd);
958
959 sem_args.count = 0;
960 sem_args.max = 3;
961 objs[0] = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
962 EXPECT_LE(0, objs[0]);
963
964 mutex_args.owner = 123;
965 mutex_args.count = 1;
966 objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
967 EXPECT_LE(0, objs[1]);
968
969 manual_event_args.manual = true;
970 manual_event_args.signaled = true;
971 objs[2] = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &manual_event_args);
972 EXPECT_LE(0, objs[2]);
973
974 auto_event_args.manual = false;
975 auto_event_args.signaled = true;
976 objs[3] = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &auto_event_args);
977 EXPECT_LE(0, objs[3]);
978
979 wait_args.timeout = get_abs_timeout(1000);
980 wait_args.objs = (uintptr_t)objs;
981 wait_args.count = 4;
982 wait_args.owner = 456;
983 thread_args.fd = fd;
984 thread_args.args = &wait_args;
985 thread_args.request = NTSYNC_IOC_WAIT_ALL;
986 ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
987 EXPECT_EQ(0, ret);
988
989 ret = wait_for_thread(thread, 100);
990 EXPECT_EQ(ETIMEDOUT, ret);
991
992 count = 1;
993 ret = release_sem(objs[0], &count);
994 EXPECT_EQ(0, ret);
995 EXPECT_EQ(0, count);
996
997 ret = pthread_tryjoin_np(thread, NULL);
998 EXPECT_EQ(EBUSY, ret);
999
1000 check_sem_state(objs[0], 1, 3);
1001
1002 ret = wait_any(fd, 1, &objs[0], 123, &index);
1003 EXPECT_EQ(0, ret);
1004 EXPECT_EQ(0, index);
1005
1006 ret = unlock_mutex(objs[1], 123, &count);
1007 EXPECT_EQ(0, ret);
1008 EXPECT_EQ(1, count);
1009
1010 ret = pthread_tryjoin_np(thread, NULL);
1011 EXPECT_EQ(EBUSY, ret);
1012
1013 check_mutex_state(objs[1], 0, 0);
1014
1015 ret = ioctl(objs[2], NTSYNC_IOC_EVENT_RESET, &signaled);
1016 EXPECT_EQ(0, ret);
1017 EXPECT_EQ(1, signaled);
1018
1019 count = 2;
1020 ret = release_sem(objs[0], &count);
1021 EXPECT_EQ(0, ret);
1022 EXPECT_EQ(0, count);
1023 check_sem_state(objs[0], 2, 3);
1024
1025 ret = ioctl(objs[3], NTSYNC_IOC_EVENT_RESET, &signaled);
1026 EXPECT_EQ(0, ret);
1027 EXPECT_EQ(1, signaled);
1028
1029 ret = ioctl(objs[2], NTSYNC_IOC_EVENT_SET, &signaled);
1030 EXPECT_EQ(0, ret);
1031 EXPECT_EQ(0, signaled);
1032
1033 ret = ioctl(objs[3], NTSYNC_IOC_EVENT_SET, &signaled);
1034 EXPECT_EQ(0, ret);
1035 EXPECT_EQ(0, signaled);
1036
1037 check_sem_state(objs[0], 1, 3);
1038 check_mutex_state(objs[1], 1, 456);
1039 check_event_state(objs[2], 1, 1);
1040 check_event_state(objs[3], 0, 0);
1041
1042 ret = wait_for_thread(thread, 100);
1043 EXPECT_EQ(0, ret);
1044 EXPECT_EQ(0, thread_args.ret);
1045
1046 /* delete an object while it's being waited on */
1047
1048 wait_args.timeout = get_abs_timeout(200);
1049 wait_args.owner = 123;
1050 ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
1051 EXPECT_EQ(0, ret);
1052
1053 ret = wait_for_thread(thread, 100);
1054 EXPECT_EQ(ETIMEDOUT, ret);
1055
1056 close(objs[0]);
1057 close(objs[1]);
1058 close(objs[2]);
1059 close(objs[3]);
1060
1061 ret = wait_for_thread(thread, 200);
1062 EXPECT_EQ(0, ret);
1063 EXPECT_EQ(-1, thread_args.ret);
1064 EXPECT_EQ(ETIMEDOUT, thread_args.err);
1065
1066 close(fd);
1067}
1068
1069TEST(alert_any)
1070{
1071 struct ntsync_event_args event_args = {0};
1072 struct ntsync_wait_args wait_args = {0};
1073 struct ntsync_sem_args sem_args = {0};
1074 __u32 index, count, signaled;
1075 struct wait_args thread_args;
1076 int objs[2], event, fd, ret;
1077 pthread_t thread;
1078
1079 fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
1080 ASSERT_LE(0, fd);
1081
1082 sem_args.count = 0;
1083 sem_args.max = 2;
1084 objs[0] = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
1085 EXPECT_LE(0, objs[0]);
1086
1087 sem_args.count = 1;
1088 sem_args.max = 2;
1089 objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
1090 EXPECT_LE(0, objs[1]);
1091
1092 event_args.manual = true;
1093 event_args.signaled = true;
1094 event = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
1095 EXPECT_LE(0, event);
1096
1097 ret = wait_any_alert(fd, 0, NULL, 123, event, &index);
1098 EXPECT_EQ(0, ret);
1099 EXPECT_EQ(0, index);
1100
1101 ret = ioctl(event, NTSYNC_IOC_EVENT_RESET, &signaled);
1102 EXPECT_EQ(0, ret);
1103
1104 ret = wait_any_alert(fd, 0, NULL, 123, event, &index);
1105 EXPECT_EQ(-1, ret);
1106 EXPECT_EQ(ETIMEDOUT, errno);
1107
1108 ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled);
1109 EXPECT_EQ(0, ret);
1110
1111 ret = wait_any_alert(fd, 2, objs, 123, event, &index);
1112 EXPECT_EQ(0, ret);
1113 EXPECT_EQ(1, index);
1114
1115 ret = wait_any_alert(fd, 2, objs, 123, event, &index);
1116 EXPECT_EQ(0, ret);
1117 EXPECT_EQ(2, index);
1118
1119 /* test wakeup via alert */
1120
1121 ret = ioctl(event, NTSYNC_IOC_EVENT_RESET, &signaled);
1122 EXPECT_EQ(0, ret);
1123
1124 wait_args.timeout = get_abs_timeout(1000);
1125 wait_args.objs = (uintptr_t)objs;
1126 wait_args.count = 2;
1127 wait_args.owner = 123;
1128 wait_args.index = 0xdeadbeef;
1129 wait_args.alert = event;
1130 thread_args.fd = fd;
1131 thread_args.args = &wait_args;
1132 thread_args.request = NTSYNC_IOC_WAIT_ANY;
1133 ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
1134 EXPECT_EQ(0, ret);
1135
1136 ret = wait_for_thread(thread, 100);
1137 EXPECT_EQ(ETIMEDOUT, ret);
1138
1139 ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled);
1140 EXPECT_EQ(0, ret);
1141
1142 ret = wait_for_thread(thread, 100);
1143 EXPECT_EQ(0, ret);
1144 EXPECT_EQ(0, thread_args.ret);
1145 EXPECT_EQ(2, wait_args.index);
1146
1147 close(event);
1148
1149 /* test with an auto-reset event */
1150
1151 event_args.manual = false;
1152 event_args.signaled = true;
1153 event = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
1154 EXPECT_LE(0, event);
1155
1156 count = 1;
1157 ret = release_sem(objs[0], &count);
1158 EXPECT_EQ(0, ret);
1159
1160 ret = wait_any_alert(fd, 2, objs, 123, event, &index);
1161 EXPECT_EQ(0, ret);
1162 EXPECT_EQ(0, index);
1163
1164 ret = wait_any_alert(fd, 2, objs, 123, event, &index);
1165 EXPECT_EQ(0, ret);
1166 EXPECT_EQ(2, index);
1167
1168 ret = wait_any_alert(fd, 2, objs, 123, event, &index);
1169 EXPECT_EQ(-1, ret);
1170 EXPECT_EQ(ETIMEDOUT, errno);
1171
1172 close(event);
1173
1174 close(objs[0]);
1175 close(objs[1]);
1176
1177 close(fd);
1178}
1179
1180TEST(alert_all)
1181{
1182 struct ntsync_event_args event_args = {0};
1183 struct ntsync_wait_args wait_args = {0};
1184 struct ntsync_sem_args sem_args = {0};
1185 struct wait_args thread_args;
1186 __u32 index, count, signaled;
1187 int objs[2], event, fd, ret;
1188 pthread_t thread;
1189
1190 fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
1191 ASSERT_LE(0, fd);
1192
1193 sem_args.count = 2;
1194 sem_args.max = 2;
1195 objs[0] = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
1196 EXPECT_LE(0, objs[0]);
1197
1198 sem_args.count = 1;
1199 sem_args.max = 2;
1200 objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
1201 EXPECT_LE(0, objs[1]);
1202
1203 event_args.manual = true;
1204 event_args.signaled = true;
1205 event = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
1206 EXPECT_LE(0, event);
1207
1208 ret = wait_all_alert(fd, 2, objs, 123, event, &index);
1209 EXPECT_EQ(0, ret);
1210 EXPECT_EQ(0, index);
1211
1212 ret = wait_all_alert(fd, 2, objs, 123, event, &index);
1213 EXPECT_EQ(0, ret);
1214 EXPECT_EQ(2, index);
1215
1216 /* test wakeup via alert */
1217
1218 ret = ioctl(event, NTSYNC_IOC_EVENT_RESET, &signaled);
1219 EXPECT_EQ(0, ret);
1220
1221 wait_args.timeout = get_abs_timeout(1000);
1222 wait_args.objs = (uintptr_t)objs;
1223 wait_args.count = 2;
1224 wait_args.owner = 123;
1225 wait_args.index = 0xdeadbeef;
1226 wait_args.alert = event;
1227 thread_args.fd = fd;
1228 thread_args.args = &wait_args;
1229 thread_args.request = NTSYNC_IOC_WAIT_ALL;
1230 ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
1231 EXPECT_EQ(0, ret);
1232
1233 ret = wait_for_thread(thread, 100);
1234 EXPECT_EQ(ETIMEDOUT, ret);
1235
1236 ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled);
1237 EXPECT_EQ(0, ret);
1238
1239 ret = wait_for_thread(thread, 100);
1240 EXPECT_EQ(0, ret);
1241 EXPECT_EQ(0, thread_args.ret);
1242 EXPECT_EQ(2, wait_args.index);
1243
1244 close(event);
1245
1246 /* test with an auto-reset event */
1247
1248 event_args.manual = false;
1249 event_args.signaled = true;
1250 event = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
1251 EXPECT_LE(0, event);
1252
1253 count = 2;
1254 ret = release_sem(objs[1], &count);
1255 EXPECT_EQ(0, ret);
1256
1257 ret = wait_all_alert(fd, 2, objs, 123, event, &index);
1258 EXPECT_EQ(0, ret);
1259 EXPECT_EQ(0, index);
1260
1261 ret = wait_all_alert(fd, 2, objs, 123, event, &index);
1262 EXPECT_EQ(0, ret);
1263 EXPECT_EQ(2, index);
1264
1265 ret = wait_all_alert(fd, 2, objs, 123, event, &index);
1266 EXPECT_EQ(-1, ret);
1267 EXPECT_EQ(ETIMEDOUT, errno);
1268
1269 close(event);
1270
1271 close(objs[0]);
1272 close(objs[1]);
1273
1274 close(fd);
1275}
1276
1277#define STRESS_LOOPS 10000
1278#define STRESS_THREADS 4
1279
1280static unsigned int stress_counter;
1281static int stress_device, stress_start_event, stress_mutex;
1282
1283static void *stress_thread(void *arg)
1284{
1285 struct ntsync_wait_args wait_args = {0};
1286 __u32 index, count, i;
1287 int ret;
1288
1289 wait_args.timeout = UINT64_MAX;
1290 wait_args.count = 1;
1291 wait_args.objs = (uintptr_t)&stress_start_event;
1292 wait_args.owner = gettid();
1293 wait_args.index = 0xdeadbeef;
1294
1295 ioctl(stress_device, NTSYNC_IOC_WAIT_ANY, &wait_args);
1296
1297 wait_args.objs = (uintptr_t)&stress_mutex;
1298
1299 for (i = 0; i < STRESS_LOOPS; ++i) {
1300 ioctl(stress_device, NTSYNC_IOC_WAIT_ANY, &wait_args);
1301
1302 ++stress_counter;
1303
1304 unlock_mutex(stress_mutex, wait_args.owner, &count);
1305 }
1306
1307 return NULL;
1308}
1309
1310TEST(stress_wait)
1311{
1312 struct ntsync_event_args event_args;
1313 struct ntsync_mutex_args mutex_args;
1314 pthread_t threads[STRESS_THREADS];
1315 __u32 signaled, i;
1316 int ret;
1317
1318 stress_device = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
1319 ASSERT_LE(0, stress_device);
1320
1321 mutex_args.owner = 0;
1322 mutex_args.count = 0;
1323 stress_mutex = ioctl(stress_device, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
1324 EXPECT_LE(0, stress_mutex);
1325
1326 event_args.manual = 1;
1327 event_args.signaled = 0;
1328 stress_start_event = ioctl(stress_device, NTSYNC_IOC_CREATE_EVENT, &event_args);
1329 EXPECT_LE(0, stress_start_event);
1330
1331 for (i = 0; i < STRESS_THREADS; ++i)
1332 pthread_create(&threads[i], NULL, stress_thread, NULL);
1333
1334 ret = ioctl(stress_start_event, NTSYNC_IOC_EVENT_SET, &signaled);
1335 EXPECT_EQ(0, ret);
1336
1337 for (i = 0; i < STRESS_THREADS; ++i) {
1338 ret = pthread_join(threads[i], NULL);
1339 EXPECT_EQ(0, ret);
1340 }
1341
1342 EXPECT_EQ(STRESS_LOOPS * STRESS_THREADS, stress_counter);
1343
1344 close(stress_start_event);
1345 close(stress_mutex);
1346 close(stress_device);
1347}
1348
1349TEST(wait_args_validation)
1350{
1351 struct ntsync_sem_args sem_args = { .count = 1, .max = 1 };
1352 struct ntsync_wait_args wait_args = {0};
1353 struct timespec timeout;
1354 int fd, fd2, sem, ret;
1355 __u32 index;
1356
1357 fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
1358 ASSERT_GE(fd, 0);
1359
1360 fd2 = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
1361 ASSERT_GE(fd2, 0);
1362
1363 sem = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
1364 EXPECT_GE(sem, 0);
1365
1366 ret = wait_any(fd, 1, &sem, 0, &index);
1367 EXPECT_EQ(-1, ret);
1368 EXPECT_EQ(EINVAL, errno);
1369
1370 ret = wait_all(fd, 1, &sem, 0, &index);
1371 EXPECT_EQ(-1, ret);
1372 EXPECT_EQ(EINVAL, errno);
1373
1374 clock_gettime(CLOCK_MONOTONIC, &timeout);
1375 wait_args.timeout = timeout.tv_sec * 1000000000ULL + timeout.tv_nsec;
1376 wait_args.count = 0;
1377 wait_args.objs = 0;
1378 wait_args.owner = 123;
1379 wait_args.pad = 1;
1380 ret = ioctl(fd, NTSYNC_IOC_WAIT_ANY, &wait_args);
1381 EXPECT_EQ(-1, ret);
1382 EXPECT_EQ(EINVAL, errno);
1383
1384 ret = wait_any(fd2, 1, &sem, 123, &index);
1385 EXPECT_EQ(-1, ret);
1386 EXPECT_EQ(EINVAL, errno);
1387
1388 close(sem);
1389 close(fd2);
1390 close(fd);
1391}
1392
1393/*
1394 * Absolute MONOTONIC timeouts must honour the caller's time namespace.
1395 * With a negative monotonic offset, a 100 ms wait must still take ~100 ms
1396 * of namespace time (not return immediately against the host clock).
1397 */
1398TEST(wait_any_monotonic_timens)
1399{
1400 struct ntsync_sem_args sem_args = {0};
1401 struct ntsync_wait_args wait_args = {0};
1402 struct timespec start, end;
1403 char buf[64];
1404 __u64 elapsed_ns;
1405 int fd, offset_fd, sem, ret, status, len;
1406 pid_t pid;
1407
1408 if (access("/proc/self/ns/time", F_OK))
1409 SKIP(return, "Time namespaces are not supported");
1410
1411 fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
1412 if (fd < 0)
1413 SKIP(return, "/dev/ntsync is not available");
1414
1415 ret = unshare(CLONE_NEWTIME);
1416 if (ret) {
1417 close(fd);
1418 if (errno == EPERM)
1419 SKIP(return, "need CAP_SYS_ADMIN for CLONE_NEWTIME");
1420 ASSERT_EQ(0, ret);
1421 }
1422
1423 len = snprintf(buf, sizeof(buf), "%d %d 0", CLOCK_MONOTONIC, -10);
1424 offset_fd = open("/proc/self/timens_offsets", O_WRONLY);
1425 ASSERT_LE(0, offset_fd);
1426 ASSERT_EQ(len, write(offset_fd, buf, len));
1427 close(offset_fd);
1428
1429 pid = fork();
1430 ASSERT_LE(0, pid);
1431 if (!pid) {
1432 int obj;
1433
1434 sem_args.count = 0;
1435 sem_args.max = 1;
1436 sem = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
1437 if (sem < 0)
1438 _exit(1);
1439
1440 obj = sem;
1441 wait_args.timeout = get_abs_timeout(100);
1442 wait_args.objs = (uintptr_t)&obj;
1443 wait_args.count = 1;
1444 wait_args.owner = 123;
1445 wait_args.index = 0xdeadbeef;
1446
1447 if (clock_gettime(CLOCK_MONOTONIC, &start))
1448 _exit(2);
1449 ret = ioctl(fd, NTSYNC_IOC_WAIT_ANY, &wait_args);
1450 if (clock_gettime(CLOCK_MONOTONIC, &end))
1451 _exit(2);
1452
1453 if (ret != -1 || errno != ETIMEDOUT)
1454 _exit(3);
1455
1456 elapsed_ns = (end.tv_sec - start.tv_sec) * 1000000000ULL +
1457 (end.tv_nsec - start.tv_nsec);
1458 /* Without timens conversion this returns in ~0 ms. */
1459 if (elapsed_ns < 50 * 1000000ULL)
1460 _exit(4);
1461 if (elapsed_ns > 1000 * 1000000ULL)
1462 _exit(5);
1463
1464 _exit(0);
1465 }
1466
1467 ASSERT_EQ(pid, waitpid(pid, &status, 0));
1468 EXPECT_TRUE(WIFEXITED(status));
1469 EXPECT_EQ(0, WEXITSTATUS(status));
1470
1471 close(fd);
1472}
1473
1474TEST_HARNESS_MAIN