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