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 <zfigura@codeweavers.com> 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 23 static 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 44 static int release_sem(int sem, __u32 *count) 45 { 46 return ioctl(sem, NTSYNC_IOC_SEM_RELEASE, count); 47 } 48 49 static 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 70 static 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 82 static 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 103 static 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 123 static 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 128 static 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 133 static 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 140 static 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 147 TEST(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 231 TEST(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 385 TEST(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 450 TEST(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 506 TEST(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 620 TEST(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 712 struct wake_args { 713 int fd; 714 int obj; 715 }; 716 717 struct wait_args { 718 int fd; 719 unsigned long request; 720 struct ntsync_wait_args *args; 721 int ret; 722 int err; 723 }; 724 725 static 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 734 static __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 741 static 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 752 TEST(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 944 TEST(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 1069 TEST(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 1180 TEST(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 1280 static unsigned int stress_counter; 1281 static int stress_device, stress_start_event, stress_mutex; 1282 1283 static 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 1310 TEST(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 1349 TEST(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 */ 1398 TEST(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 1474 TEST_HARNESS_MAIN 1475