2 * mach eventlink: Tests mach eventlink kernel synchronization primitive.
5 #include <darwintest.h>
6 #include <darwintest_multiprocess.h>
10 #include <mach/mach.h>
11 #include <mach/message.h>
12 #include <mach/mach_voucher.h>
13 #include <pthread/workqueue_private.h>
14 #include <voucher/ipc_pthread_priority_types.h>
15 #include <servers/bootstrap.h>
17 #include <sys/event.h>
19 #include <crt_externs.h>
21 #include <sys/types.h>
22 #include <sys/sysctl.h>
23 #include <libkern/OSAtomic.h>
26 #include <spawn_private.h>
27 #include <mach/mach_eventlink.h>
29 T_GLOBAL_META(T_META_NAMESPACE("xnu.mach_eventlink"),
30 T_META_RUN_CONCURRENTLY(true));
33 test_eventlink_create(mach_port_t
*port_pair
)
37 kr
= mach_eventlink_create(mach_task_self(), MELC_OPTION_NO_COPYIN
, port_pair
);
38 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_create");
44 thread_create_for_test(void * (*function
)(void *), void *arg
)
49 pthread_attr_init(&attr
);
50 pthread_create(&pthread
, &attr
, function
, arg
);
52 T_LOG("pthread created\n");
67 test_eventlink_wait_with_timeout(void *arg
)
70 mach_port_t eventlink_port
= (mach_port_t
) (uintptr_t)arg
;
71 mach_port_t self
= mach_thread_self();
72 uint64_t ticks
= mach_absolute_time();
75 /* Associate thread with eventlink port */
76 kr
= mach_eventlink_associate(eventlink_port
, self
, 0, 0, 0, 0, MELA_OPTION_NONE
);
77 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_associate");
79 /* Wait on the eventlink with timeout */
80 kr
= mach_eventlink_wait_until(eventlink_port
, &count
, MELSW_OPTION_NONE
,
81 KERN_CLOCK_MACH_ABSOLUTE_TIME
, ticks
+ 5000);
83 T_EXPECT_MACH_ERROR(kr
, KERN_OPERATION_TIMED_OUT
, "mach_eventlink_wait_until returned expected error");
84 T_EXPECT_EQ(count
, (uint64_t)0, "mach_eventlink_wait_until returned correct count value");
90 test_eventlink_wait_no_wait(void *arg
)
93 mach_port_t eventlink_port
= (mach_port_t
) (uintptr_t)arg
;
94 mach_port_t self
= mach_thread_self();
97 /* Associate thread with eventlink port */
98 kr
= mach_eventlink_associate(eventlink_port
, self
, 0, 0, 0, 0, MELA_OPTION_NONE
);
99 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_associate");
101 /* Wait on the eventlink */
102 kr
= mach_eventlink_wait_until(eventlink_port
, &count
, MELSW_OPTION_NO_WAIT
,
103 KERN_CLOCK_MACH_ABSOLUTE_TIME
, 0);
105 T_EXPECT_MACH_ERROR(kr
, KERN_OPERATION_TIMED_OUT
, "mach_eventlink_wait_until returned expected error");
106 T_EXPECT_EQ(count
, (uint64_t)0, "mach_eventlink_wait_until returned correct count value");
112 test_eventlink_wait_destroy(void *arg
)
115 mach_port_t eventlink_port
= (mach_port_t
) (uintptr_t)arg
;
116 mach_port_t self
= mach_thread_self();
119 /* Associate thread with eventlink port */
120 kr
= mach_eventlink_associate(eventlink_port
, self
, 0, 0, 0, 0, MELA_OPTION_NONE
);
121 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_associate");
123 /* Wait on the eventlink */
124 kr
= mach_eventlink_wait_until(eventlink_port
, &count
, MELSW_OPTION_NONE
,
125 KERN_CLOCK_MACH_ABSOLUTE_TIME
, 0);
127 T_EXPECT_MACH_ERROR(kr
, KERN_TERMINATED
, "mach_eventlink_wait_until returned expected error");
133 test_eventlink_wait_for_signal(void *arg
)
136 mach_port_t eventlink_port
= (mach_port_t
) (uintptr_t)arg
;
137 mach_port_t self
= mach_thread_self();
140 /* Associate thread with eventlink port */
141 kr
= mach_eventlink_associate(eventlink_port
, self
, 0, 0, 0, 0, MELA_OPTION_NONE
);
142 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_associate");
144 /* Wait on the eventlink */
145 kr
= mach_eventlink_wait_until(eventlink_port
, &count
, MELSW_OPTION_NONE
,
146 KERN_CLOCK_MACH_ABSOLUTE_TIME
, 0);
148 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_wait_until");
149 T_EXPECT_EQ(count
, (uint64_t)1, "mach_eventlink_wait_until returned correct count value");
155 test_eventlink_wait_then_signal(void *arg
)
158 mach_port_t eventlink_port
= (mach_port_t
) (uintptr_t)arg
;
159 mach_port_t self
= mach_thread_self();
162 /* Associate thread with eventlink port */
163 kr
= mach_eventlink_associate(eventlink_port
, self
, 0, 0, 0, 0, MELA_OPTION_NONE
);
164 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_associate");
166 /* Wait on the eventlink */
167 kr
= mach_eventlink_wait_until(eventlink_port
, &count
, MELSW_OPTION_NONE
,
168 KERN_CLOCK_MACH_ABSOLUTE_TIME
, 0);
170 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_wait_until");
171 T_EXPECT_EQ(count
, (uint64_t)1, "mach_eventlink_wait_until returned correct count value");
173 /* Signal the eventlink to wakeup other side */
174 kr
= mach_eventlink_signal(eventlink_port
, 0);
175 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_signal");
181 test_eventlink_wait_then_wait_signal_with_no_wait(void *arg
)
184 mach_port_t eventlink_port
= (mach_port_t
) (uintptr_t)arg
;
185 mach_port_t self
= mach_thread_self();
188 /* Associate thread with eventlink port */
189 kr
= mach_eventlink_associate(eventlink_port
, self
, 0, 0, 0, 0, MELA_OPTION_NONE
);
190 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_associate");
192 /* Wait on the eventlink */
193 kr
= mach_eventlink_wait_until(eventlink_port
, &count
, MELSW_OPTION_NONE
,
194 KERN_CLOCK_MACH_ABSOLUTE_TIME
, 0);
196 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_wait_until");
197 T_EXPECT_EQ(count
, (uint64_t)1, "mach_eventlink_wait_until returned correct count value");
199 /* Signal wait the eventlink */
200 kr
= mach_eventlink_signal_wait_until(eventlink_port
, &count
, 0, MELSW_OPTION_NO_WAIT
,
201 KERN_CLOCK_MACH_ABSOLUTE_TIME
, 0);
203 T_EXPECT_MACH_ERROR(kr
, KERN_OPERATION_TIMED_OUT
, "mach_eventlink_wait_until returned expected error");
204 T_EXPECT_EQ(count
, (uint64_t)1, "mach_eventlink_wait_until returned correct count value");
210 test_eventlink_wait_then_wait_signal_with_prepost(void *arg
)
213 mach_port_t eventlink_port
= (mach_port_t
) (uintptr_t)arg
;
214 mach_port_t self
= mach_thread_self();
217 /* Associate thread with eventlink port */
218 kr
= mach_eventlink_associate(eventlink_port
, self
, 0, 0, 0, 0, MELA_OPTION_NONE
);
219 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_associate");
221 /* Wait on the eventlink */
222 kr
= mach_eventlink_wait_until(eventlink_port
, &count
, MELSW_OPTION_NONE
,
223 KERN_CLOCK_MACH_ABSOLUTE_TIME
, 0);
225 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_wait_until");
226 T_EXPECT_EQ(count
, (uint64_t)1, "mach_eventlink_wait_until returned correct count value");
228 /* Signal wait the eventlink with stale counter value */
230 kr
= mach_eventlink_signal_wait_until(eventlink_port
, &count
, 0, MELSW_OPTION_NONE
,
231 KERN_CLOCK_MACH_ABSOLUTE_TIME
, 0);
233 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_signal_wait_until");
234 T_EXPECT_EQ(count
, (uint64_t)1, "mach_eventlink_wait_until returned correct count value");
240 test_eventlink_wait_then_signal_loop(void *arg
)
243 mach_port_t eventlink_port
= (mach_port_t
) (uintptr_t)arg
;
244 mach_port_t self
= mach_thread_self();
248 /* Associate thread with eventlink port */
249 kr
= mach_eventlink_associate(eventlink_port
, self
, 0, 0, 0, 0, MELA_OPTION_NONE
);
250 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_associate");
252 /* Wait on the eventlink */
253 kr
= mach_eventlink_wait_until(eventlink_port
, &count
, MELSW_OPTION_NONE
,
254 KERN_CLOCK_MACH_ABSOLUTE_TIME
, 0);
256 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_wait_until");
257 T_EXPECT_EQ(count
, (uint64_t)1, "mach_eventlink_wait_until returned correct count value");
259 for (i
= 1; i
< 100; i
++) {
260 /* Signal wait the eventlink */
261 kr
= mach_eventlink_signal_wait_until(eventlink_port
, &count
, 0, MELSW_OPTION_NONE
,
262 KERN_CLOCK_MACH_ABSOLUTE_TIME
, 0);
264 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_signal_wait_until");
265 T_EXPECT_EQ(count
, (uint64_t)(i
+ 1), "mach_eventlink_wait_until returned correct count value");
268 /* Signal the eventlink to wakeup other side */
269 kr
= mach_eventlink_signal(eventlink_port
, 0);
270 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_signal");
276 * Test 1: Create ipc eventlink kernel object.
278 * Calls eventlink creates which returns a pair of eventlink port objects.
280 T_DECL(test_eventlink_create
, "eventlink create test", T_META_ASROOT(YES
))
283 mach_port_t port_pair
[2];
285 kr
= test_eventlink_create(port_pair
);
286 if (kr
!= KERN_SUCCESS
) {
290 mach_port_deallocate(mach_task_self(), port_pair
[0]);
291 mach_port_deallocate(mach_task_self(), port_pair
[1]);
295 * Test 2: Create ipc eventlink kernel object and call eventlink destroy
297 * Calls eventlink creates which returns a pair of eventlink port objects.
298 * Calls eventlink destroy on eventlink port pair.
300 T_DECL(test_eventlink_destroy
, "eventlink destroy test", T_META_ASROOT(YES
))
303 mach_port_t port_pair
[2];
305 kr
= test_eventlink_create(port_pair
);
306 if (kr
!= KERN_SUCCESS
) {
310 kr
= mach_eventlink_destroy(port_pair
[0]);
311 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_destroy");
312 kr
= mach_eventlink_destroy(port_pair
[1]);
313 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_destroy");
317 * Test 3: Associate threads to eventlink object.
319 * Create eventlink object pair and associate threads to each side and then
320 * disassociate threads and check for error conditions.
322 T_DECL(test_eventlink_associate
, "eventlink associate test", T_META_ASROOT(YES
))
325 mach_port_t port_pair
[2];
326 mach_port_t self
= mach_thread_self();
327 mach_port_t other_thread
= MACH_PORT_NULL
;
330 /* eventlink associate to NULL eventlink object */
331 kr
= mach_eventlink_associate(MACH_PORT_NULL
, self
, 0, 0, 0, 0, MELA_OPTION_NONE
);
332 T_EXPECT_MACH_ERROR(kr
, MACH_SEND_INVALID_DEST
, "mach_eventlink_associate with null eventlink returned expected error");
334 /* eventlink disassociate to NULL eventlink object */
335 kr
= mach_eventlink_disassociate(MACH_PORT_NULL
, MELD_OPTION_NONE
);
336 T_EXPECT_MACH_ERROR(kr
, MACH_SEND_INVALID_DEST
, "mach_eventlink_disassociate with null eventlink returned expected error");
338 /* Create an eventlink and associate threads to it */
339 kr
= test_eventlink_create(port_pair
);
340 if (kr
!= KERN_SUCCESS
) {
344 pthread
= thread_create_for_test(while1loop
, NULL
);
345 other_thread
= pthread_mach_thread_np(pthread
);
347 for (int i
= 0; i
< 3; i
++) {
348 /* Associate thread to eventlink objects */
349 kr
= mach_eventlink_associate(port_pair
[0], self
, 0, 0, 0, 0, MELA_OPTION_NONE
);
350 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_associate for object 1");
352 kr
= mach_eventlink_associate(port_pair
[1], other_thread
, 0, 0, 0, 0, MELA_OPTION_NONE
);
353 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_associate for object 2");
355 /* Try to associate again with diff threads, expect failure */
356 kr
= mach_eventlink_associate(port_pair
[0], other_thread
, 0, 0, 0, 0, MELA_OPTION_NONE
);
357 T_EXPECT_MACH_ERROR(kr
, KERN_NAME_EXISTS
, "mach_eventlink_associate for associated "
358 "objects returned expected error");
360 kr
= mach_eventlink_associate(port_pair
[1], self
, 0, 0, 0, 0, MELA_OPTION_NONE
);
361 T_EXPECT_MACH_ERROR(kr
, KERN_NAME_EXISTS
, "mach_eventlink_associate for associated "
362 "objects return expected error");
364 /* Try to disassociate the threads */
365 kr
= mach_eventlink_disassociate(port_pair
[0], MELD_OPTION_NONE
);
366 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_disassociate for object 1");
368 kr
= mach_eventlink_disassociate(port_pair
[1], MELD_OPTION_NONE
);
369 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_disassociate for object 2");
371 /* Try to disassociate the threads again, expect failure */
372 kr
= mach_eventlink_disassociate(port_pair
[0], MELD_OPTION_NONE
);
373 T_EXPECT_MACH_ERROR(kr
, KERN_INVALID_ARGUMENT
, "mach_eventlink_disassociate for "
374 "disassociated objects returned expected error");
376 kr
= mach_eventlink_disassociate(port_pair
[1], MELD_OPTION_NONE
);
377 T_EXPECT_MACH_ERROR(kr
, KERN_INVALID_ARGUMENT
, "mach_eventlink_disassociate for "
378 "disassociated objects returned expected error");
381 kr
= mach_eventlink_destroy(port_pair
[0]);
382 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_destroy");
384 /* Try disassociate on other end of destoryed eventlink pair */
385 kr
= mach_eventlink_disassociate(port_pair
[1], MELD_OPTION_NONE
);
386 T_EXPECT_MACH_ERROR(kr
, KERN_TERMINATED
, "mach_eventlink_disassociate for "
387 "terminated object returned expected error");
389 kr
= mach_eventlink_destroy(port_pair
[1]);
390 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_destroy");
394 * Test 4: Test eventlink wait with timeout.
396 * Create an eventlink object, associate threads and test eventlink wait with timeout.
398 T_DECL(test_eventlink_wait_timeout
, "eventlink wait timeout test", T_META_ASROOT(YES
))
401 mach_port_t port_pair
[2];
404 /* Create an eventlink and associate threads to it */
405 kr
= test_eventlink_create(port_pair
);
406 if (kr
!= KERN_SUCCESS
) {
410 pthread
= thread_create_for_test(test_eventlink_wait_with_timeout
, (void *)(uintptr_t)port_pair
[0]);
413 /* destroy the eventlink object, the wake status of thread will check if the test passsed or failed */
414 mach_port_deallocate(mach_task_self(), port_pair
[0]);
415 mach_port_deallocate(mach_task_self(), port_pair
[1]);
417 pthread_join(pthread
, NULL
);
421 * Test 5: Test eventlink wait with no wait.
423 * Create an eventlink object, associate threads and test eventlink wait with no wait flag.
425 T_DECL(test_eventlink_wait_no_wait
, "eventlink wait no wait test", T_META_ASROOT(YES
))
428 mach_port_t port_pair
[2];
431 /* Create an eventlink and associate threads to it */
432 kr
= test_eventlink_create(port_pair
);
433 if (kr
!= KERN_SUCCESS
) {
437 pthread
= thread_create_for_test(test_eventlink_wait_no_wait
, (void *)(uintptr_t)port_pair
[0]);
438 pthread_join(pthread
, NULL
);
440 mach_port_deallocate(mach_task_self(), port_pair
[0]);
441 mach_port_deallocate(mach_task_self(), port_pair
[1]);
445 * Test 6: Test eventlink wait and destroy.
447 * Create an eventlink object, associate threads and destroy the port.
449 T_DECL(test_eventlink_wait_and_destroy
, "eventlink wait and destroy", T_META_ASROOT(YES
))
452 mach_port_t port_pair
[2];
455 /* Create an eventlink and associate threads to it */
456 kr
= test_eventlink_create(port_pair
);
457 if (kr
!= KERN_SUCCESS
) {
461 pthread
= thread_create_for_test(test_eventlink_wait_destroy
, (void *)(uintptr_t)port_pair
[0]);
465 /* Increase the send right count for port before destroy to make sure no sender does not fire on destroy */
466 kr
= mach_port_mod_refs(mach_task_self(), port_pair
[0], MACH_PORT_RIGHT_SEND
, 2);
467 T_ASSERT_MACH_SUCCESS(kr
, "mach_port_mod_refs");
469 /* Destroy the port for thread to wakeup */
470 kr
= mach_eventlink_destroy(port_pair
[0]);
471 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_destroy");
473 pthread_join(pthread
, NULL
);
474 mach_port_deallocate(mach_task_self(), port_pair
[1]);
479 * Test 7: Test eventlink wait and destroy remote side.
481 * Create an eventlink object, associate threads, wait and destroy the remote eventlink port.
483 T_DECL(test_eventlink_wait_and_destroy_remote
, "eventlink wait and remote destroy", T_META_ASROOT(YES
))
486 mach_port_t port_pair
[2];
489 /* Create an eventlink and associate threads to it */
490 kr
= test_eventlink_create(port_pair
);
491 if (kr
!= KERN_SUCCESS
) {
495 pthread
= thread_create_for_test(test_eventlink_wait_destroy
, (void *)(uintptr_t)port_pair
[0]);
499 /* Increase the send right count for port before destroy to make sure no sender does not fire on destroy */
500 kr
= mach_port_mod_refs(mach_task_self(), port_pair
[1], MACH_PORT_RIGHT_SEND
, 2);
501 T_ASSERT_MACH_SUCCESS(kr
, "mach_port_mod_refs");
503 /* Destroy the port for thread to wakeup */
504 kr
= mach_eventlink_destroy(port_pair
[1]);
505 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_destroy");
507 pthread_join(pthread
, NULL
);
508 mach_port_deallocate(mach_task_self(), port_pair
[0]);
512 * Test 8: Test eventlink wait and deallocate port.
514 * Create an eventlink object, associate threads, wait and deallocate the eventlink port.
516 T_DECL(test_eventlink_wait_and_deallocate
, "eventlink wait and deallocate", T_META_ASROOT(YES
))
519 mach_port_t port_pair
[2];
522 /* Create an eventlink and associate threads to it */
523 kr
= test_eventlink_create(port_pair
);
524 if (kr
!= KERN_SUCCESS
) {
528 pthread
= thread_create_for_test(test_eventlink_wait_destroy
, (void *)(uintptr_t)port_pair
[0]);
532 /* Destroy the port for thread to wakeup */
533 mach_port_deallocate(mach_task_self(), port_pair
[0]);
535 pthread_join(pthread
, NULL
);
536 mach_port_deallocate(mach_task_self(), port_pair
[1]);
540 * Test 9: Test eventlink wait and disassociate.
542 * Create an eventlink object, associate threads, wait and disassociate thread from the eventlink port.
544 T_DECL(test_eventlink_wait_and_disassociate
, "eventlink wait and disassociate", T_META_ASROOT(YES
))
547 mach_port_t port_pair
[2];
550 /* Create an eventlink and associate threads to it */
551 kr
= test_eventlink_create(port_pair
);
552 if (kr
!= KERN_SUCCESS
) {
556 pthread
= thread_create_for_test(test_eventlink_wait_destroy
, (void *)(uintptr_t)port_pair
[0]);
560 /* Disassociate thread from eventlink for thread to wakeup */
561 kr
= mach_eventlink_disassociate(port_pair
[0], MELD_OPTION_NONE
);
562 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_disassociate");
564 pthread_join(pthread
, NULL
);
565 mach_port_deallocate(mach_task_self(), port_pair
[1]);
566 mach_port_deallocate(mach_task_self(), port_pair
[0]);
570 * Test 10: Test eventlink wait and signal.
572 * Create an eventlink object, associate threads and test wait signal.
574 T_DECL(test_eventlink_wait_and_signal
, "eventlink wait and signal", T_META_ASROOT(YES
))
577 mach_port_t port_pair
[2];
579 mach_port_t self
= mach_thread_self();
581 /* Create an eventlink and associate threads to it */
582 kr
= test_eventlink_create(port_pair
);
583 if (kr
!= KERN_SUCCESS
) {
587 pthread
= thread_create_for_test(test_eventlink_wait_for_signal
, (void *)(uintptr_t)port_pair
[0]);
591 /* Associate thread and signal the eventlink */
592 kr
= mach_eventlink_associate(port_pair
[1], self
, 0, 0, 0, 0, MELA_OPTION_NONE
);
593 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_associate for object 2");
595 kr
= mach_eventlink_signal(port_pair
[1], 0);
596 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_signal for object 2");
598 pthread_join(pthread
, NULL
);
600 mach_port_deallocate(mach_task_self(), port_pair
[0]);
601 mach_port_deallocate(mach_task_self(), port_pair
[1]);
605 * Test 11: Test eventlink wait_signal.
607 * Create an eventlink object, associate threads and test wait_signal.
609 T_DECL(test_eventlink_wait_signal
, "eventlink wait_signal", T_META_ASROOT(YES
))
612 mach_port_t port_pair
[2];
614 mach_port_t self
= mach_thread_self();
617 /* Create an eventlink and associate threads to it */
618 kr
= test_eventlink_create(port_pair
);
619 if (kr
!= KERN_SUCCESS
) {
623 pthread
= thread_create_for_test(test_eventlink_wait_then_signal
, (void *)(uintptr_t)port_pair
[0]);
627 /* Associate thread and wait_signal the eventlink */
628 kr
= mach_eventlink_associate(port_pair
[1], self
, 0, 0, 0, 0, MELA_OPTION_NONE
);
629 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_associate for object 2");
631 /* Wait on the eventlink with timeout */
632 kr
= mach_eventlink_signal_wait_until(port_pair
[1], &count
, 0, MELSW_OPTION_NONE
,
633 KERN_CLOCK_MACH_ABSOLUTE_TIME
, 0);
635 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_signal_wait_until");
636 T_EXPECT_EQ(count
, (uint64_t)1, "mach_eventlink_signal_wait_until returned correct count value");
638 pthread_join(pthread
, NULL
);
640 mach_port_deallocate(mach_task_self(), port_pair
[0]);
641 mach_port_deallocate(mach_task_self(), port_pair
[1]);
645 * Test 12: Test eventlink wait_signal with no wait.
647 * Create an eventlink object, associate threads and test wait_signal with no wait.
649 T_DECL(test_eventlink_wait_signal_no_wait
, "eventlink wait_signal with no wait", T_META_ASROOT(YES
))
652 mach_port_t port_pair
[2];
654 mach_port_t self
= mach_thread_self();
657 /* Create an eventlink and associate threads to it */
658 kr
= test_eventlink_create(port_pair
);
659 if (kr
!= KERN_SUCCESS
) {
663 pthread
= thread_create_for_test(test_eventlink_wait_then_wait_signal_with_no_wait
, (void *)(uintptr_t)port_pair
[0]);
667 /* Associate thread and wait_signal the eventlink */
668 kr
= mach_eventlink_associate(port_pair
[1], self
, 0, 0, 0, 0, MELA_OPTION_NONE
);
669 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_associate for object 2");
671 /* Wait on the eventlink with timeout */
672 kr
= mach_eventlink_signal_wait_until(port_pair
[1], &count
, 0, MELSW_OPTION_NONE
,
673 KERN_CLOCK_MACH_ABSOLUTE_TIME
, 0);
675 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_signal_wait_until");
676 T_EXPECT_EQ(count
, (uint64_t)1, "mach_eventlink_signal_wait_until returned correct count value");
678 pthread_join(pthread
, NULL
);
680 mach_port_deallocate(mach_task_self(), port_pair
[0]);
681 mach_port_deallocate(mach_task_self(), port_pair
[1]);
685 * Test 13: Test eventlink wait_signal with prepost.
687 * Create an eventlink object, associate threads and test wait_signal with prepost.
689 T_DECL(test_eventlink_wait_signal_prepost
, "eventlink wait_signal with prepost", T_META_ASROOT(YES
))
692 mach_port_t port_pair
[2];
694 mach_port_t self
= mach_thread_self();
697 /* Create an eventlink and associate threads to it */
698 kr
= test_eventlink_create(port_pair
);
699 if (kr
!= KERN_SUCCESS
) {
703 pthread
= thread_create_for_test(test_eventlink_wait_then_wait_signal_with_prepost
, (void *)(uintptr_t)port_pair
[0]);
707 /* Associate thread and wait_signal the eventlink */
708 kr
= mach_eventlink_associate(port_pair
[1], self
, 0, 0, 0, 0, MELA_OPTION_NONE
);
709 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_associate for object 2");
711 /* Wait on the eventlink with timeout */
712 kr
= mach_eventlink_signal_wait_until(port_pair
[1], &count
, 0, MELSW_OPTION_NONE
,
713 KERN_CLOCK_MACH_ABSOLUTE_TIME
, 0);
715 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_signal_wait_until");
716 T_EXPECT_EQ(count
, (uint64_t)1, "mach_eventlink_signal_wait_until returned correct count value");
718 pthread_join(pthread
, NULL
);
720 mach_port_deallocate(mach_task_self(), port_pair
[0]);
721 mach_port_deallocate(mach_task_self(), port_pair
[1]);
725 * Test 14: Test eventlink wait_signal with associate on wait option.
727 * Create an eventlink object, set associate on wait on one side and test wait_signal.
729 T_DECL(test_eventlink_wait_signal_associate_on_wait
, "eventlink wait_signal associate on wait", T_META_ASROOT(YES
))
732 mach_port_t port_pair
[2];
736 /* Create an eventlink and associate threads to it */
737 kr
= test_eventlink_create(port_pair
);
738 if (kr
!= KERN_SUCCESS
) {
742 pthread
= thread_create_for_test(test_eventlink_wait_then_signal
, (void *)(uintptr_t)port_pair
[0]);
746 /* Set associate on wait and wait_signal the eventlink */
747 kr
= mach_eventlink_associate(port_pair
[1], MACH_PORT_NULL
, 0, 0, 0, 0, MELA_OPTION_ASSOCIATE_ON_WAIT
);
748 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_associate with associate on wait for object 2");
750 /* Wait on the eventlink with timeout */
751 kr
= mach_eventlink_signal_wait_until(port_pair
[1], &count
, 0, MELSW_OPTION_NONE
,
752 KERN_CLOCK_MACH_ABSOLUTE_TIME
, 0);
754 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_signal_wait_until");
755 T_EXPECT_EQ(count
, (uint64_t)1, "mach_eventlink_signal_wait_until returned correct count value");
757 /* Remove associate on wait option */
758 kr
= mach_eventlink_disassociate(port_pair
[1], MELD_OPTION_NONE
);
759 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_disassociate");
761 /* Wait on the eventlink with timeout */
762 kr
= mach_eventlink_signal_wait_until(port_pair
[1], &count
, 0, MELSW_OPTION_NONE
,
763 KERN_CLOCK_MACH_ABSOLUTE_TIME
, 0);
765 T_EXPECT_MACH_ERROR(kr
, KERN_INVALID_ARGUMENT
, "mach_eventlink_wait_until returned expected error");
767 pthread_join(pthread
, NULL
);
769 mach_port_deallocate(mach_task_self(), port_pair
[0]);
770 mach_port_deallocate(mach_task_self(), port_pair
[1]);
774 * Test 15: Test eventlink wait_signal_loop.
776 * Create an eventlink object, associate threads and test wait_signal in a loop.
778 T_DECL(test_eventlink_wait_signal_loop
, "eventlink wait_signal in loop", T_META_ASROOT(YES
))
781 mach_port_t port_pair
[2];
783 mach_port_t self
= mach_thread_self();
787 /* Create an eventlink and associate threads to it */
788 kr
= test_eventlink_create(port_pair
);
789 if (kr
!= KERN_SUCCESS
) {
793 pthread
= thread_create_for_test(test_eventlink_wait_then_signal_loop
, (void *)(uintptr_t)port_pair
[0]);
795 /* Associate thread and wait_signal the eventlink */
796 kr
= mach_eventlink_associate(port_pair
[1], self
, 0, 0, 0, 0, MELA_OPTION_NONE
);
797 T_ASSERT_MACH_SUCCESS(kr
, "mach_eventlink_associate for object 2");
799 for (i
= 0; i
< 100; i
++) {
800 /* Wait on the eventlink with timeout */
801 kr
= mach_eventlink_signal_wait_until(port_pair
[1], &count
, 0, MELSW_OPTION_NONE
,
802 KERN_CLOCK_MACH_ABSOLUTE_TIME
, 0);
804 T_ASSERT_MACH_SUCCESS(kr
, "main thread: mach_eventlink_signal_wait_until");
805 T_EXPECT_EQ(count
, (uint64_t)(i
+ 1), "main thread: mach_eventlink_signal_wait_until returned correct count value");
808 pthread_join(pthread
, NULL
);
810 mach_port_deallocate(mach_task_self(), port_pair
[0]);
811 mach_port_deallocate(mach_task_self(), port_pair
[1]);