1*4f1223e8SApple OSS Distributions /*
2*4f1223e8SApple OSS Distributions * mach eventlink: Tests mach eventlink kernel synchronization primitive.
3*4f1223e8SApple OSS Distributions */
4*4f1223e8SApple OSS Distributions
5*4f1223e8SApple OSS Distributions #include <darwintest.h>
6*4f1223e8SApple OSS Distributions #include <darwintest_multiprocess.h>
7*4f1223e8SApple OSS Distributions
8*4f1223e8SApple OSS Distributions #include <pthread.h>
9*4f1223e8SApple OSS Distributions #include <launch.h>
10*4f1223e8SApple OSS Distributions #include <mach/mach.h>
11*4f1223e8SApple OSS Distributions #include <mach/message.h>
12*4f1223e8SApple OSS Distributions #include <mach/mach_voucher.h>
13*4f1223e8SApple OSS Distributions #include <pthread/workqueue_private.h>
14*4f1223e8SApple OSS Distributions #include <voucher/ipc_pthread_priority_types.h>
15*4f1223e8SApple OSS Distributions #include <servers/bootstrap.h>
16*4f1223e8SApple OSS Distributions #include <stdlib.h>
17*4f1223e8SApple OSS Distributions #include <sys/event.h>
18*4f1223e8SApple OSS Distributions #include <unistd.h>
19*4f1223e8SApple OSS Distributions #include <crt_externs.h>
20*4f1223e8SApple OSS Distributions #include <signal.h>
21*4f1223e8SApple OSS Distributions #include <sys/types.h>
22*4f1223e8SApple OSS Distributions #include <sys/sysctl.h>
23*4f1223e8SApple OSS Distributions #include <libkern/OSAtomic.h>
24*4f1223e8SApple OSS Distributions #include <sys/wait.h>
25*4f1223e8SApple OSS Distributions #include <spawn.h>
26*4f1223e8SApple OSS Distributions #include <spawn_private.h>
27*4f1223e8SApple OSS Distributions #include <mach/mach_eventlink.h>
28*4f1223e8SApple OSS Distributions #include <os/atomic_private.h>
29*4f1223e8SApple OSS Distributions
30*4f1223e8SApple OSS Distributions T_GLOBAL_META(T_META_NAMESPACE("xnu.mach_eventlink"),
31*4f1223e8SApple OSS Distributions T_META_RUN_CONCURRENTLY(true));
32*4f1223e8SApple OSS Distributions
33*4f1223e8SApple OSS Distributions static int g_loop_iterations = 100000;
34*4f1223e8SApple OSS Distributions
35*4f1223e8SApple OSS Distributions static kern_return_t
test_eventlink_create(mach_port_t * port_pair)36*4f1223e8SApple OSS Distributions test_eventlink_create(mach_port_t *port_pair)
37*4f1223e8SApple OSS Distributions {
38*4f1223e8SApple OSS Distributions kern_return_t kr;
39*4f1223e8SApple OSS Distributions
40*4f1223e8SApple OSS Distributions kr = mach_eventlink_create(mach_task_self(), MELC_OPTION_NO_COPYIN, port_pair);
41*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_create");
42*4f1223e8SApple OSS Distributions
43*4f1223e8SApple OSS Distributions return kr;
44*4f1223e8SApple OSS Distributions }
45*4f1223e8SApple OSS Distributions
46*4f1223e8SApple OSS Distributions static pthread_t
thread_create_for_test(void * (* function)(void *),void * arg)47*4f1223e8SApple OSS Distributions thread_create_for_test(void * (*function)(void *), void *arg)
48*4f1223e8SApple OSS Distributions {
49*4f1223e8SApple OSS Distributions pthread_t pthread;
50*4f1223e8SApple OSS Distributions pthread_attr_t attr;
51*4f1223e8SApple OSS Distributions
52*4f1223e8SApple OSS Distributions pthread_attr_init(&attr);
53*4f1223e8SApple OSS Distributions pthread_create(&pthread, &attr, function, arg);
54*4f1223e8SApple OSS Distributions
55*4f1223e8SApple OSS Distributions T_LOG("pthread created\n");
56*4f1223e8SApple OSS Distributions return pthread;
57*4f1223e8SApple OSS Distributions }
58*4f1223e8SApple OSS Distributions
59*4f1223e8SApple OSS Distributions static void *
while1loop(__unused void * arg)60*4f1223e8SApple OSS Distributions while1loop(__unused void *arg)
61*4f1223e8SApple OSS Distributions {
62*4f1223e8SApple OSS Distributions while (1) {
63*4f1223e8SApple OSS Distributions ;
64*4f1223e8SApple OSS Distributions }
65*4f1223e8SApple OSS Distributions return NULL;
66*4f1223e8SApple OSS Distributions }
67*4f1223e8SApple OSS Distributions
68*4f1223e8SApple OSS Distributions static void *
test_eventlink_wait_with_timeout(void * arg)69*4f1223e8SApple OSS Distributions test_eventlink_wait_with_timeout(void *arg)
70*4f1223e8SApple OSS Distributions {
71*4f1223e8SApple OSS Distributions kern_return_t kr;
72*4f1223e8SApple OSS Distributions mach_port_t eventlink_port = (mach_port_t) (uintptr_t)arg;
73*4f1223e8SApple OSS Distributions mach_port_t self = mach_thread_self();
74*4f1223e8SApple OSS Distributions uint64_t ticks = mach_absolute_time();
75*4f1223e8SApple OSS Distributions uint64_t count = 1;
76*4f1223e8SApple OSS Distributions
77*4f1223e8SApple OSS Distributions /* Associate thread with eventlink port */
78*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(eventlink_port, self, 0, 0, 0, 0, MELA_OPTION_NONE);
79*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_associate");
80*4f1223e8SApple OSS Distributions
81*4f1223e8SApple OSS Distributions /* Wait on the eventlink with timeout */
82*4f1223e8SApple OSS Distributions kr = mach_eventlink_wait_until(eventlink_port, &count, MELSW_OPTION_NONE,
83*4f1223e8SApple OSS Distributions KERN_CLOCK_MACH_ABSOLUTE_TIME, ticks + 5000);
84*4f1223e8SApple OSS Distributions
85*4f1223e8SApple OSS Distributions T_EXPECT_MACH_ERROR(kr, KERN_OPERATION_TIMED_OUT, "mach_eventlink_wait_until returned expected error");
86*4f1223e8SApple OSS Distributions T_EXPECT_EQ(count, (uint64_t)0, "mach_eventlink_wait_until returned correct count value");
87*4f1223e8SApple OSS Distributions
88*4f1223e8SApple OSS Distributions return NULL;
89*4f1223e8SApple OSS Distributions }
90*4f1223e8SApple OSS Distributions
91*4f1223e8SApple OSS Distributions static void *
test_eventlink_wait_no_wait(void * arg)92*4f1223e8SApple OSS Distributions test_eventlink_wait_no_wait(void *arg)
93*4f1223e8SApple OSS Distributions {
94*4f1223e8SApple OSS Distributions kern_return_t kr;
95*4f1223e8SApple OSS Distributions mach_port_t eventlink_port = (mach_port_t) (uintptr_t)arg;
96*4f1223e8SApple OSS Distributions mach_port_t self = mach_thread_self();
97*4f1223e8SApple OSS Distributions uint64_t count = 1;
98*4f1223e8SApple OSS Distributions
99*4f1223e8SApple OSS Distributions /* Associate thread with eventlink port */
100*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(eventlink_port, self, 0, 0, 0, 0, MELA_OPTION_NONE);
101*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_associate");
102*4f1223e8SApple OSS Distributions
103*4f1223e8SApple OSS Distributions /* Wait on the eventlink */
104*4f1223e8SApple OSS Distributions kr = mach_eventlink_wait_until(eventlink_port, &count, MELSW_OPTION_NO_WAIT,
105*4f1223e8SApple OSS Distributions KERN_CLOCK_MACH_ABSOLUTE_TIME, 0);
106*4f1223e8SApple OSS Distributions
107*4f1223e8SApple OSS Distributions T_EXPECT_MACH_ERROR(kr, KERN_OPERATION_TIMED_OUT, "mach_eventlink_wait_until returned expected error");
108*4f1223e8SApple OSS Distributions T_EXPECT_EQ(count, (uint64_t)0, "mach_eventlink_wait_until returned correct count value");
109*4f1223e8SApple OSS Distributions
110*4f1223e8SApple OSS Distributions return NULL;
111*4f1223e8SApple OSS Distributions }
112*4f1223e8SApple OSS Distributions
113*4f1223e8SApple OSS Distributions static void *
test_eventlink_wait_destroy(void * arg)114*4f1223e8SApple OSS Distributions test_eventlink_wait_destroy(void *arg)
115*4f1223e8SApple OSS Distributions {
116*4f1223e8SApple OSS Distributions kern_return_t kr;
117*4f1223e8SApple OSS Distributions mach_port_t eventlink_port = (mach_port_t) (uintptr_t)arg;
118*4f1223e8SApple OSS Distributions mach_port_t self = mach_thread_self();
119*4f1223e8SApple OSS Distributions uint64_t count = 1;
120*4f1223e8SApple OSS Distributions
121*4f1223e8SApple OSS Distributions /* Associate thread with eventlink port */
122*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(eventlink_port, self, 0, 0, 0, 0, MELA_OPTION_NONE);
123*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_associate");
124*4f1223e8SApple OSS Distributions
125*4f1223e8SApple OSS Distributions /* Wait on the eventlink */
126*4f1223e8SApple OSS Distributions kr = mach_eventlink_wait_until(eventlink_port, &count, MELSW_OPTION_NONE,
127*4f1223e8SApple OSS Distributions KERN_CLOCK_MACH_ABSOLUTE_TIME, 0);
128*4f1223e8SApple OSS Distributions
129*4f1223e8SApple OSS Distributions T_EXPECT_MACH_ERROR(kr, KERN_TERMINATED, "mach_eventlink_wait_until returned expected error");
130*4f1223e8SApple OSS Distributions
131*4f1223e8SApple OSS Distributions return NULL;
132*4f1223e8SApple OSS Distributions }
133*4f1223e8SApple OSS Distributions
134*4f1223e8SApple OSS Distributions static void *
test_eventlink_wait_for_signal(void * arg)135*4f1223e8SApple OSS Distributions test_eventlink_wait_for_signal(void *arg)
136*4f1223e8SApple OSS Distributions {
137*4f1223e8SApple OSS Distributions kern_return_t kr;
138*4f1223e8SApple OSS Distributions mach_port_t eventlink_port = (mach_port_t) (uintptr_t)arg;
139*4f1223e8SApple OSS Distributions mach_port_t self = mach_thread_self();
140*4f1223e8SApple OSS Distributions uint64_t count = 0;
141*4f1223e8SApple OSS Distributions
142*4f1223e8SApple OSS Distributions /* Associate thread with eventlink port */
143*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(eventlink_port, self, 0, 0, 0, 0, MELA_OPTION_NONE);
144*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_associate");
145*4f1223e8SApple OSS Distributions
146*4f1223e8SApple OSS Distributions /* Wait on the eventlink */
147*4f1223e8SApple OSS Distributions kr = mach_eventlink_wait_until(eventlink_port, &count, MELSW_OPTION_NONE,
148*4f1223e8SApple OSS Distributions KERN_CLOCK_MACH_ABSOLUTE_TIME, 0);
149*4f1223e8SApple OSS Distributions
150*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_wait_until");
151*4f1223e8SApple OSS Distributions T_EXPECT_EQ(count, (uint64_t)1, "mach_eventlink_wait_until returned correct count value");
152*4f1223e8SApple OSS Distributions
153*4f1223e8SApple OSS Distributions return NULL;
154*4f1223e8SApple OSS Distributions }
155*4f1223e8SApple OSS Distributions
156*4f1223e8SApple OSS Distributions static void *
test_eventlink_wait_then_signal(void * arg)157*4f1223e8SApple OSS Distributions test_eventlink_wait_then_signal(void *arg)
158*4f1223e8SApple OSS Distributions {
159*4f1223e8SApple OSS Distributions kern_return_t kr;
160*4f1223e8SApple OSS Distributions mach_port_t eventlink_port = (mach_port_t) (uintptr_t)arg;
161*4f1223e8SApple OSS Distributions mach_port_t self = mach_thread_self();
162*4f1223e8SApple OSS Distributions uint64_t count = 0;
163*4f1223e8SApple OSS Distributions
164*4f1223e8SApple OSS Distributions /* Associate thread with eventlink port */
165*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(eventlink_port, self, 0, 0, 0, 0, MELA_OPTION_NONE);
166*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_associate");
167*4f1223e8SApple OSS Distributions
168*4f1223e8SApple OSS Distributions /* Wait on the eventlink */
169*4f1223e8SApple OSS Distributions kr = mach_eventlink_wait_until(eventlink_port, &count, MELSW_OPTION_NONE,
170*4f1223e8SApple OSS Distributions KERN_CLOCK_MACH_ABSOLUTE_TIME, 0);
171*4f1223e8SApple OSS Distributions
172*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_wait_until");
173*4f1223e8SApple OSS Distributions T_EXPECT_EQ(count, (uint64_t)1, "mach_eventlink_wait_until returned correct count value");
174*4f1223e8SApple OSS Distributions
175*4f1223e8SApple OSS Distributions /* Signal the eventlink to wakeup other side */
176*4f1223e8SApple OSS Distributions kr = mach_eventlink_signal(eventlink_port, 0);
177*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_signal");
178*4f1223e8SApple OSS Distributions
179*4f1223e8SApple OSS Distributions return NULL;
180*4f1223e8SApple OSS Distributions }
181*4f1223e8SApple OSS Distributions
182*4f1223e8SApple OSS Distributions static void *
test_eventlink_wait_then_wait_signal_with_no_wait(void * arg)183*4f1223e8SApple OSS Distributions test_eventlink_wait_then_wait_signal_with_no_wait(void *arg)
184*4f1223e8SApple OSS Distributions {
185*4f1223e8SApple OSS Distributions kern_return_t kr;
186*4f1223e8SApple OSS Distributions mach_port_t eventlink_port = (mach_port_t) (uintptr_t)arg;
187*4f1223e8SApple OSS Distributions mach_port_t self = mach_thread_self();
188*4f1223e8SApple OSS Distributions uint64_t count = 0;
189*4f1223e8SApple OSS Distributions
190*4f1223e8SApple OSS Distributions /* Associate thread with eventlink port */
191*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(eventlink_port, self, 0, 0, 0, 0, MELA_OPTION_NONE);
192*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_associate");
193*4f1223e8SApple OSS Distributions
194*4f1223e8SApple OSS Distributions /* Wait on the eventlink */
195*4f1223e8SApple OSS Distributions kr = mach_eventlink_wait_until(eventlink_port, &count, MELSW_OPTION_NONE,
196*4f1223e8SApple OSS Distributions KERN_CLOCK_MACH_ABSOLUTE_TIME, 0);
197*4f1223e8SApple OSS Distributions
198*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_wait_until");
199*4f1223e8SApple OSS Distributions T_EXPECT_EQ(count, (uint64_t)1, "mach_eventlink_wait_until returned correct count value");
200*4f1223e8SApple OSS Distributions
201*4f1223e8SApple OSS Distributions /* Signal wait the eventlink */
202*4f1223e8SApple OSS Distributions kr = mach_eventlink_signal_wait_until(eventlink_port, &count, 0, MELSW_OPTION_NO_WAIT,
203*4f1223e8SApple OSS Distributions KERN_CLOCK_MACH_ABSOLUTE_TIME, 0);
204*4f1223e8SApple OSS Distributions
205*4f1223e8SApple OSS Distributions T_EXPECT_MACH_ERROR(kr, KERN_OPERATION_TIMED_OUT, "mach_eventlink_wait_until returned expected error");
206*4f1223e8SApple OSS Distributions T_EXPECT_EQ(count, (uint64_t)1, "mach_eventlink_wait_until returned correct count value");
207*4f1223e8SApple OSS Distributions
208*4f1223e8SApple OSS Distributions return NULL;
209*4f1223e8SApple OSS Distributions }
210*4f1223e8SApple OSS Distributions
211*4f1223e8SApple OSS Distributions static void *
test_eventlink_wait_then_wait_signal_with_prepost(void * arg)212*4f1223e8SApple OSS Distributions test_eventlink_wait_then_wait_signal_with_prepost(void *arg)
213*4f1223e8SApple OSS Distributions {
214*4f1223e8SApple OSS Distributions kern_return_t kr;
215*4f1223e8SApple OSS Distributions mach_port_t eventlink_port = (mach_port_t) (uintptr_t)arg;
216*4f1223e8SApple OSS Distributions mach_port_t self = mach_thread_self();
217*4f1223e8SApple OSS Distributions uint64_t count = 0;
218*4f1223e8SApple OSS Distributions
219*4f1223e8SApple OSS Distributions /* Associate thread with eventlink port */
220*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(eventlink_port, self, 0, 0, 0, 0, MELA_OPTION_NONE);
221*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_associate");
222*4f1223e8SApple OSS Distributions
223*4f1223e8SApple OSS Distributions /* Wait on the eventlink */
224*4f1223e8SApple OSS Distributions kr = mach_eventlink_wait_until(eventlink_port, &count, MELSW_OPTION_NONE,
225*4f1223e8SApple OSS Distributions KERN_CLOCK_MACH_ABSOLUTE_TIME, 0);
226*4f1223e8SApple OSS Distributions
227*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_wait_until");
228*4f1223e8SApple OSS Distributions T_EXPECT_EQ(count, (uint64_t)1, "mach_eventlink_wait_until returned correct count value");
229*4f1223e8SApple OSS Distributions
230*4f1223e8SApple OSS Distributions /* Signal wait the eventlink with stale counter value */
231*4f1223e8SApple OSS Distributions count = 0;
232*4f1223e8SApple OSS Distributions kr = mach_eventlink_signal_wait_until(eventlink_port, &count, 0, MELSW_OPTION_NONE,
233*4f1223e8SApple OSS Distributions KERN_CLOCK_MACH_ABSOLUTE_TIME, 0);
234*4f1223e8SApple OSS Distributions
235*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_signal_wait_until");
236*4f1223e8SApple OSS Distributions T_EXPECT_EQ(count, (uint64_t)1, "mach_eventlink_wait_until returned correct count value");
237*4f1223e8SApple OSS Distributions
238*4f1223e8SApple OSS Distributions return NULL;
239*4f1223e8SApple OSS Distributions }
240*4f1223e8SApple OSS Distributions
241*4f1223e8SApple OSS Distributions static void *
test_eventlink_wait_then_signal_loop(void * arg)242*4f1223e8SApple OSS Distributions test_eventlink_wait_then_signal_loop(void *arg)
243*4f1223e8SApple OSS Distributions {
244*4f1223e8SApple OSS Distributions kern_return_t kr;
245*4f1223e8SApple OSS Distributions mach_port_t eventlink_port = (mach_port_t) (uintptr_t)arg;
246*4f1223e8SApple OSS Distributions mach_port_t self = mach_thread_self();
247*4f1223e8SApple OSS Distributions uint64_t count = 0;
248*4f1223e8SApple OSS Distributions int i;
249*4f1223e8SApple OSS Distributions
250*4f1223e8SApple OSS Distributions /* Associate thread with eventlink port */
251*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(eventlink_port, self, 0, 0, 0, 0, MELA_OPTION_NONE);
252*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_associate");
253*4f1223e8SApple OSS Distributions
254*4f1223e8SApple OSS Distributions /* Wait on the eventlink */
255*4f1223e8SApple OSS Distributions kr = mach_eventlink_wait_until(eventlink_port, &count, MELSW_OPTION_NONE,
256*4f1223e8SApple OSS Distributions KERN_CLOCK_MACH_ABSOLUTE_TIME, 0);
257*4f1223e8SApple OSS Distributions
258*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_wait_until");
259*4f1223e8SApple OSS Distributions T_EXPECT_EQ(count, (uint64_t)1, "mach_eventlink_wait_until returned correct count value");
260*4f1223e8SApple OSS Distributions
261*4f1223e8SApple OSS Distributions for (i = 1; i < g_loop_iterations; i++) {
262*4f1223e8SApple OSS Distributions /* Signal wait the eventlink */
263*4f1223e8SApple OSS Distributions kr = mach_eventlink_signal_wait_until(eventlink_port, &count, 0, MELSW_OPTION_NONE,
264*4f1223e8SApple OSS Distributions KERN_CLOCK_MACH_ABSOLUTE_TIME, 0);
265*4f1223e8SApple OSS Distributions
266*4f1223e8SApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_signal_wait_until");
267*4f1223e8SApple OSS Distributions T_QUIET; T_EXPECT_EQ(count, (uint64_t)(i + 1), "mach_eventlink_wait_until returned correct count value");
268*4f1223e8SApple OSS Distributions }
269*4f1223e8SApple OSS Distributions
270*4f1223e8SApple OSS Distributions /* Signal the eventlink to wakeup other side */
271*4f1223e8SApple OSS Distributions kr = mach_eventlink_signal(eventlink_port, 0);
272*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_signal");
273*4f1223e8SApple OSS Distributions
274*4f1223e8SApple OSS Distributions return NULL;
275*4f1223e8SApple OSS Distributions }
276*4f1223e8SApple OSS Distributions
277*4f1223e8SApple OSS Distributions /*
278*4f1223e8SApple OSS Distributions * Test 1: Create ipc eventlink kernel object.
279*4f1223e8SApple OSS Distributions *
280*4f1223e8SApple OSS Distributions * Calls eventlink creates which returns a pair of eventlink port objects.
281*4f1223e8SApple OSS Distributions */
282*4f1223e8SApple OSS Distributions T_DECL(test_eventlink_create, "eventlink create test", T_META_ASROOT(YES), T_META_TAG_VM_PREFERRED)
283*4f1223e8SApple OSS Distributions {
284*4f1223e8SApple OSS Distributions kern_return_t kr;
285*4f1223e8SApple OSS Distributions mach_port_t port_pair[2];
286*4f1223e8SApple OSS Distributions
287*4f1223e8SApple OSS Distributions kr = test_eventlink_create(port_pair);
288*4f1223e8SApple OSS Distributions if (kr != KERN_SUCCESS) {
289*4f1223e8SApple OSS Distributions return;
290*4f1223e8SApple OSS Distributions }
291*4f1223e8SApple OSS Distributions
292*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[0]);
293*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[1]);
294*4f1223e8SApple OSS Distributions }
295*4f1223e8SApple OSS Distributions
296*4f1223e8SApple OSS Distributions /*
297*4f1223e8SApple OSS Distributions * Test 2: Create ipc eventlink kernel object and call eventlink destroy
298*4f1223e8SApple OSS Distributions *
299*4f1223e8SApple OSS Distributions * Calls eventlink creates which returns a pair of eventlink port objects.
300*4f1223e8SApple OSS Distributions * Calls eventlink destroy on eventlink port pair.
301*4f1223e8SApple OSS Distributions */
302*4f1223e8SApple OSS Distributions T_DECL(test_eventlink_destroy, "eventlink destroy test", T_META_ASROOT(YES), T_META_TAG_VM_PREFERRED)
303*4f1223e8SApple OSS Distributions {
304*4f1223e8SApple OSS Distributions kern_return_t kr;
305*4f1223e8SApple OSS Distributions mach_port_t port_pair[2];
306*4f1223e8SApple OSS Distributions
307*4f1223e8SApple OSS Distributions kr = test_eventlink_create(port_pair);
308*4f1223e8SApple OSS Distributions if (kr != KERN_SUCCESS) {
309*4f1223e8SApple OSS Distributions return;
310*4f1223e8SApple OSS Distributions }
311*4f1223e8SApple OSS Distributions
312*4f1223e8SApple OSS Distributions kr = mach_eventlink_destroy(port_pair[0]);
313*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_destroy");
314*4f1223e8SApple OSS Distributions kr = mach_eventlink_destroy(port_pair[1]);
315*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_destroy");
316*4f1223e8SApple OSS Distributions }
317*4f1223e8SApple OSS Distributions
318*4f1223e8SApple OSS Distributions /*
319*4f1223e8SApple OSS Distributions * Test 3: Associate threads to eventlink object.
320*4f1223e8SApple OSS Distributions *
321*4f1223e8SApple OSS Distributions * Create eventlink object pair and associate threads to each side and then
322*4f1223e8SApple OSS Distributions * disassociate threads and check for error conditions.
323*4f1223e8SApple OSS Distributions */
324*4f1223e8SApple OSS Distributions T_DECL(test_eventlink_associate, "eventlink associate test", T_META_ASROOT(YES), T_META_TAG_VM_PREFERRED)
325*4f1223e8SApple OSS Distributions {
326*4f1223e8SApple OSS Distributions kern_return_t kr;
327*4f1223e8SApple OSS Distributions mach_port_t port_pair[2];
328*4f1223e8SApple OSS Distributions mach_port_t self = mach_thread_self();
329*4f1223e8SApple OSS Distributions mach_port_t other_thread = MACH_PORT_NULL;
330*4f1223e8SApple OSS Distributions pthread_t pthread;
331*4f1223e8SApple OSS Distributions
332*4f1223e8SApple OSS Distributions /* eventlink associate to NULL eventlink object */
333*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(MACH_PORT_NULL, self, 0, 0, 0, 0, MELA_OPTION_NONE);
334*4f1223e8SApple OSS Distributions T_EXPECT_MACH_ERROR(kr, MACH_SEND_INVALID_DEST, "mach_eventlink_associate with null eventlink returned expected error");
335*4f1223e8SApple OSS Distributions
336*4f1223e8SApple OSS Distributions /* eventlink disassociate to NULL eventlink object */
337*4f1223e8SApple OSS Distributions kr = mach_eventlink_disassociate(MACH_PORT_NULL, MELD_OPTION_NONE);
338*4f1223e8SApple OSS Distributions T_EXPECT_MACH_ERROR(kr, MACH_SEND_INVALID_DEST, "mach_eventlink_disassociate with null eventlink returned expected error");
339*4f1223e8SApple OSS Distributions
340*4f1223e8SApple OSS Distributions /* Create an eventlink and associate threads to it */
341*4f1223e8SApple OSS Distributions kr = test_eventlink_create(port_pair);
342*4f1223e8SApple OSS Distributions if (kr != KERN_SUCCESS) {
343*4f1223e8SApple OSS Distributions return;
344*4f1223e8SApple OSS Distributions }
345*4f1223e8SApple OSS Distributions
346*4f1223e8SApple OSS Distributions pthread = thread_create_for_test(while1loop, NULL);
347*4f1223e8SApple OSS Distributions other_thread = pthread_mach_thread_np(pthread);
348*4f1223e8SApple OSS Distributions
349*4f1223e8SApple OSS Distributions for (int i = 0; i < 3; i++) {
350*4f1223e8SApple OSS Distributions /* Associate thread to eventlink objects */
351*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(port_pair[0], self, 0, 0, 0, 0, MELA_OPTION_NONE);
352*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_associate for object 1");
353*4f1223e8SApple OSS Distributions
354*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(port_pair[1], other_thread, 0, 0, 0, 0, MELA_OPTION_NONE);
355*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_associate for object 2");
356*4f1223e8SApple OSS Distributions
357*4f1223e8SApple OSS Distributions /* Try to associate again with diff threads, expect failure */
358*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(port_pair[0], other_thread, 0, 0, 0, 0, MELA_OPTION_NONE);
359*4f1223e8SApple OSS Distributions T_EXPECT_MACH_ERROR(kr, KERN_NAME_EXISTS, "mach_eventlink_associate for associated "
360*4f1223e8SApple OSS Distributions "objects returned expected error");
361*4f1223e8SApple OSS Distributions
362*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(port_pair[1], self, 0, 0, 0, 0, MELA_OPTION_NONE);
363*4f1223e8SApple OSS Distributions T_EXPECT_MACH_ERROR(kr, KERN_NAME_EXISTS, "mach_eventlink_associate for associated "
364*4f1223e8SApple OSS Distributions "objects return expected error");
365*4f1223e8SApple OSS Distributions
366*4f1223e8SApple OSS Distributions /* Try to disassociate the threads */
367*4f1223e8SApple OSS Distributions kr = mach_eventlink_disassociate(port_pair[0], MELD_OPTION_NONE);
368*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_disassociate for object 1");
369*4f1223e8SApple OSS Distributions
370*4f1223e8SApple OSS Distributions kr = mach_eventlink_disassociate(port_pair[1], MELD_OPTION_NONE);
371*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_disassociate for object 2");
372*4f1223e8SApple OSS Distributions
373*4f1223e8SApple OSS Distributions /* Try to disassociate the threads again, expect failure */
374*4f1223e8SApple OSS Distributions kr = mach_eventlink_disassociate(port_pair[0], MELD_OPTION_NONE);
375*4f1223e8SApple OSS Distributions T_EXPECT_MACH_ERROR(kr, KERN_INVALID_ARGUMENT, "mach_eventlink_disassociate for "
376*4f1223e8SApple OSS Distributions "disassociated objects returned expected error");
377*4f1223e8SApple OSS Distributions
378*4f1223e8SApple OSS Distributions kr = mach_eventlink_disassociate(port_pair[1], MELD_OPTION_NONE);
379*4f1223e8SApple OSS Distributions T_EXPECT_MACH_ERROR(kr, KERN_INVALID_ARGUMENT, "mach_eventlink_disassociate for "
380*4f1223e8SApple OSS Distributions "disassociated objects returned expected error");
381*4f1223e8SApple OSS Distributions }
382*4f1223e8SApple OSS Distributions
383*4f1223e8SApple OSS Distributions kr = mach_eventlink_destroy(port_pair[0]);
384*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_destroy");
385*4f1223e8SApple OSS Distributions
386*4f1223e8SApple OSS Distributions /* Try disassociate on other end of destoryed eventlink pair */
387*4f1223e8SApple OSS Distributions kr = mach_eventlink_disassociate(port_pair[1], MELD_OPTION_NONE);
388*4f1223e8SApple OSS Distributions T_EXPECT_MACH_ERROR(kr, KERN_TERMINATED, "mach_eventlink_disassociate for "
389*4f1223e8SApple OSS Distributions "terminated object returned expected error");
390*4f1223e8SApple OSS Distributions
391*4f1223e8SApple OSS Distributions kr = mach_eventlink_destroy(port_pair[1]);
392*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_destroy");
393*4f1223e8SApple OSS Distributions }
394*4f1223e8SApple OSS Distributions
395*4f1223e8SApple OSS Distributions /*
396*4f1223e8SApple OSS Distributions * Test 4: Test eventlink wait with timeout.
397*4f1223e8SApple OSS Distributions *
398*4f1223e8SApple OSS Distributions * Create an eventlink object, associate threads and test eventlink wait with timeout.
399*4f1223e8SApple OSS Distributions */
400*4f1223e8SApple OSS Distributions T_DECL(test_eventlink_wait_timeout, "eventlink wait timeout test", T_META_ASROOT(YES), T_META_TAG_VM_PREFERRED)
401*4f1223e8SApple OSS Distributions {
402*4f1223e8SApple OSS Distributions kern_return_t kr;
403*4f1223e8SApple OSS Distributions mach_port_t port_pair[2];
404*4f1223e8SApple OSS Distributions pthread_t pthread;
405*4f1223e8SApple OSS Distributions
406*4f1223e8SApple OSS Distributions /* Create an eventlink and associate threads to it */
407*4f1223e8SApple OSS Distributions kr = test_eventlink_create(port_pair);
408*4f1223e8SApple OSS Distributions if (kr != KERN_SUCCESS) {
409*4f1223e8SApple OSS Distributions return;
410*4f1223e8SApple OSS Distributions }
411*4f1223e8SApple OSS Distributions
412*4f1223e8SApple OSS Distributions pthread = thread_create_for_test(test_eventlink_wait_with_timeout, (void *)(uintptr_t)port_pair[0]);
413*4f1223e8SApple OSS Distributions sleep(10);
414*4f1223e8SApple OSS Distributions
415*4f1223e8SApple OSS Distributions /* destroy the eventlink object, the wake status of thread will check if the test passsed or failed */
416*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[0]);
417*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[1]);
418*4f1223e8SApple OSS Distributions
419*4f1223e8SApple OSS Distributions pthread_join(pthread, NULL);
420*4f1223e8SApple OSS Distributions }
421*4f1223e8SApple OSS Distributions
422*4f1223e8SApple OSS Distributions /*
423*4f1223e8SApple OSS Distributions * Test 5: Test eventlink wait with no wait.
424*4f1223e8SApple OSS Distributions *
425*4f1223e8SApple OSS Distributions * Create an eventlink object, associate threads and test eventlink wait with no wait flag.
426*4f1223e8SApple OSS Distributions */
427*4f1223e8SApple OSS Distributions T_DECL(test_eventlink_wait_no_wait, "eventlink wait no wait test", T_META_ASROOT(YES), T_META_TAG_VM_PREFERRED)
428*4f1223e8SApple OSS Distributions {
429*4f1223e8SApple OSS Distributions kern_return_t kr;
430*4f1223e8SApple OSS Distributions mach_port_t port_pair[2];
431*4f1223e8SApple OSS Distributions pthread_t pthread;
432*4f1223e8SApple OSS Distributions
433*4f1223e8SApple OSS Distributions /* Create an eventlink and associate threads to it */
434*4f1223e8SApple OSS Distributions kr = test_eventlink_create(port_pair);
435*4f1223e8SApple OSS Distributions if (kr != KERN_SUCCESS) {
436*4f1223e8SApple OSS Distributions return;
437*4f1223e8SApple OSS Distributions }
438*4f1223e8SApple OSS Distributions
439*4f1223e8SApple OSS Distributions pthread = thread_create_for_test(test_eventlink_wait_no_wait, (void *)(uintptr_t)port_pair[0]);
440*4f1223e8SApple OSS Distributions pthread_join(pthread, NULL);
441*4f1223e8SApple OSS Distributions
442*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[0]);
443*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[1]);
444*4f1223e8SApple OSS Distributions }
445*4f1223e8SApple OSS Distributions
446*4f1223e8SApple OSS Distributions /*
447*4f1223e8SApple OSS Distributions * Test 6: Test eventlink wait and destroy.
448*4f1223e8SApple OSS Distributions *
449*4f1223e8SApple OSS Distributions * Create an eventlink object, associate threads and destroy the port.
450*4f1223e8SApple OSS Distributions */
451*4f1223e8SApple OSS Distributions T_DECL(test_eventlink_wait_and_destroy, "eventlink wait and destroy", T_META_ASROOT(YES), T_META_TAG_VM_PREFERRED)
452*4f1223e8SApple OSS Distributions {
453*4f1223e8SApple OSS Distributions kern_return_t kr;
454*4f1223e8SApple OSS Distributions mach_port_t port_pair[2];
455*4f1223e8SApple OSS Distributions pthread_t pthread;
456*4f1223e8SApple OSS Distributions
457*4f1223e8SApple OSS Distributions /* Create an eventlink and associate threads to it */
458*4f1223e8SApple OSS Distributions kr = test_eventlink_create(port_pair);
459*4f1223e8SApple OSS Distributions if (kr != KERN_SUCCESS) {
460*4f1223e8SApple OSS Distributions return;
461*4f1223e8SApple OSS Distributions }
462*4f1223e8SApple OSS Distributions
463*4f1223e8SApple OSS Distributions pthread = thread_create_for_test(test_eventlink_wait_destroy, (void *)(uintptr_t)port_pair[0]);
464*4f1223e8SApple OSS Distributions
465*4f1223e8SApple OSS Distributions sleep(5);
466*4f1223e8SApple OSS Distributions
467*4f1223e8SApple OSS Distributions /* Increase the send right count for port before destroy to make sure no sender does not fire on destroy */
468*4f1223e8SApple OSS Distributions kr = mach_port_mod_refs(mach_task_self(), port_pair[0], MACH_PORT_RIGHT_SEND, 2);
469*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_port_mod_refs");
470*4f1223e8SApple OSS Distributions
471*4f1223e8SApple OSS Distributions /* Destroy the port for thread to wakeup */
472*4f1223e8SApple OSS Distributions kr = mach_eventlink_destroy(port_pair[0]);
473*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_destroy");
474*4f1223e8SApple OSS Distributions
475*4f1223e8SApple OSS Distributions pthread_join(pthread, NULL);
476*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[1]);
477*4f1223e8SApple OSS Distributions }
478*4f1223e8SApple OSS Distributions
479*4f1223e8SApple OSS Distributions
480*4f1223e8SApple OSS Distributions /*
481*4f1223e8SApple OSS Distributions * Test 7: Test eventlink wait and destroy remote side.
482*4f1223e8SApple OSS Distributions *
483*4f1223e8SApple OSS Distributions * Create an eventlink object, associate threads, wait and destroy the remote eventlink port.
484*4f1223e8SApple OSS Distributions */
485*4f1223e8SApple OSS Distributions T_DECL(test_eventlink_wait_and_destroy_remote, "eventlink wait and remote destroy", T_META_ASROOT(YES), T_META_TAG_VM_PREFERRED)
486*4f1223e8SApple OSS Distributions {
487*4f1223e8SApple OSS Distributions kern_return_t kr;
488*4f1223e8SApple OSS Distributions mach_port_t port_pair[2];
489*4f1223e8SApple OSS Distributions pthread_t pthread;
490*4f1223e8SApple OSS Distributions
491*4f1223e8SApple OSS Distributions /* Create an eventlink and associate threads to it */
492*4f1223e8SApple OSS Distributions kr = test_eventlink_create(port_pair);
493*4f1223e8SApple OSS Distributions if (kr != KERN_SUCCESS) {
494*4f1223e8SApple OSS Distributions return;
495*4f1223e8SApple OSS Distributions }
496*4f1223e8SApple OSS Distributions
497*4f1223e8SApple OSS Distributions pthread = thread_create_for_test(test_eventlink_wait_destroy, (void *)(uintptr_t)port_pair[0]);
498*4f1223e8SApple OSS Distributions
499*4f1223e8SApple OSS Distributions sleep(5);
500*4f1223e8SApple OSS Distributions
501*4f1223e8SApple OSS Distributions /* Increase the send right count for port before destroy to make sure no sender does not fire on destroy */
502*4f1223e8SApple OSS Distributions kr = mach_port_mod_refs(mach_task_self(), port_pair[1], MACH_PORT_RIGHT_SEND, 2);
503*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_port_mod_refs");
504*4f1223e8SApple OSS Distributions
505*4f1223e8SApple OSS Distributions /* Destroy the port for thread to wakeup */
506*4f1223e8SApple OSS Distributions kr = mach_eventlink_destroy(port_pair[1]);
507*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_destroy");
508*4f1223e8SApple OSS Distributions
509*4f1223e8SApple OSS Distributions pthread_join(pthread, NULL);
510*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[0]);
511*4f1223e8SApple OSS Distributions }
512*4f1223e8SApple OSS Distributions
513*4f1223e8SApple OSS Distributions /*
514*4f1223e8SApple OSS Distributions * Test 8: Test eventlink wait and deallocate port.
515*4f1223e8SApple OSS Distributions *
516*4f1223e8SApple OSS Distributions * Create an eventlink object, associate threads, wait and deallocate the eventlink port.
517*4f1223e8SApple OSS Distributions */
518*4f1223e8SApple OSS Distributions T_DECL(test_eventlink_wait_and_deallocate, "eventlink wait and deallocate", T_META_ASROOT(YES), T_META_TAG_VM_PREFERRED)
519*4f1223e8SApple OSS Distributions {
520*4f1223e8SApple OSS Distributions kern_return_t kr;
521*4f1223e8SApple OSS Distributions mach_port_t port_pair[2];
522*4f1223e8SApple OSS Distributions pthread_t pthread;
523*4f1223e8SApple OSS Distributions
524*4f1223e8SApple OSS Distributions /* Create an eventlink and associate threads to it */
525*4f1223e8SApple OSS Distributions kr = test_eventlink_create(port_pair);
526*4f1223e8SApple OSS Distributions if (kr != KERN_SUCCESS) {
527*4f1223e8SApple OSS Distributions return;
528*4f1223e8SApple OSS Distributions }
529*4f1223e8SApple OSS Distributions
530*4f1223e8SApple OSS Distributions pthread = thread_create_for_test(test_eventlink_wait_destroy, (void *)(uintptr_t)port_pair[0]);
531*4f1223e8SApple OSS Distributions
532*4f1223e8SApple OSS Distributions sleep(5);
533*4f1223e8SApple OSS Distributions
534*4f1223e8SApple OSS Distributions /* Destroy the port for thread to wakeup */
535*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[0]);
536*4f1223e8SApple OSS Distributions
537*4f1223e8SApple OSS Distributions pthread_join(pthread, NULL);
538*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[1]);
539*4f1223e8SApple OSS Distributions }
540*4f1223e8SApple OSS Distributions
541*4f1223e8SApple OSS Distributions /*
542*4f1223e8SApple OSS Distributions * Test 9: Test eventlink wait and disassociate.
543*4f1223e8SApple OSS Distributions *
544*4f1223e8SApple OSS Distributions * Create an eventlink object, associate threads, wait and disassociate thread from the eventlink port.
545*4f1223e8SApple OSS Distributions */
546*4f1223e8SApple OSS Distributions T_DECL(test_eventlink_wait_and_disassociate, "eventlink wait and disassociate", T_META_ASROOT(YES), T_META_TAG_VM_PREFERRED)
547*4f1223e8SApple OSS Distributions {
548*4f1223e8SApple OSS Distributions kern_return_t kr;
549*4f1223e8SApple OSS Distributions mach_port_t port_pair[2];
550*4f1223e8SApple OSS Distributions pthread_t pthread;
551*4f1223e8SApple OSS Distributions
552*4f1223e8SApple OSS Distributions /* Create an eventlink and associate threads to it */
553*4f1223e8SApple OSS Distributions kr = test_eventlink_create(port_pair);
554*4f1223e8SApple OSS Distributions if (kr != KERN_SUCCESS) {
555*4f1223e8SApple OSS Distributions return;
556*4f1223e8SApple OSS Distributions }
557*4f1223e8SApple OSS Distributions
558*4f1223e8SApple OSS Distributions pthread = thread_create_for_test(test_eventlink_wait_destroy, (void *)(uintptr_t)port_pair[0]);
559*4f1223e8SApple OSS Distributions
560*4f1223e8SApple OSS Distributions sleep(5);
561*4f1223e8SApple OSS Distributions
562*4f1223e8SApple OSS Distributions /* Disassociate thread from eventlink for thread to wakeup */
563*4f1223e8SApple OSS Distributions kr = mach_eventlink_disassociate(port_pair[0], MELD_OPTION_NONE);
564*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_disassociate");
565*4f1223e8SApple OSS Distributions
566*4f1223e8SApple OSS Distributions pthread_join(pthread, NULL);
567*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[1]);
568*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[0]);
569*4f1223e8SApple OSS Distributions }
570*4f1223e8SApple OSS Distributions
571*4f1223e8SApple OSS Distributions /*
572*4f1223e8SApple OSS Distributions * Test 10: Test eventlink wait and signal.
573*4f1223e8SApple OSS Distributions *
574*4f1223e8SApple OSS Distributions * Create an eventlink object, associate threads and test wait signal.
575*4f1223e8SApple OSS Distributions */
576*4f1223e8SApple OSS Distributions T_DECL(test_eventlink_wait_and_signal, "eventlink wait and signal", T_META_ASROOT(YES), T_META_TAG_VM_PREFERRED)
577*4f1223e8SApple OSS Distributions {
578*4f1223e8SApple OSS Distributions kern_return_t kr;
579*4f1223e8SApple OSS Distributions mach_port_t port_pair[2];
580*4f1223e8SApple OSS Distributions pthread_t pthread;
581*4f1223e8SApple OSS Distributions mach_port_t self = mach_thread_self();
582*4f1223e8SApple OSS Distributions
583*4f1223e8SApple OSS Distributions /* Create an eventlink and associate threads to it */
584*4f1223e8SApple OSS Distributions kr = test_eventlink_create(port_pair);
585*4f1223e8SApple OSS Distributions if (kr != KERN_SUCCESS) {
586*4f1223e8SApple OSS Distributions return;
587*4f1223e8SApple OSS Distributions }
588*4f1223e8SApple OSS Distributions
589*4f1223e8SApple OSS Distributions pthread = thread_create_for_test(test_eventlink_wait_for_signal, (void *)(uintptr_t)port_pair[0]);
590*4f1223e8SApple OSS Distributions
591*4f1223e8SApple OSS Distributions sleep(5);
592*4f1223e8SApple OSS Distributions
593*4f1223e8SApple OSS Distributions /* Associate thread and signal the eventlink */
594*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(port_pair[1], self, 0, 0, 0, 0, MELA_OPTION_NONE);
595*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_associate for object 2");
596*4f1223e8SApple OSS Distributions
597*4f1223e8SApple OSS Distributions kr = mach_eventlink_signal(port_pair[1], 0);
598*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_signal for object 2");
599*4f1223e8SApple OSS Distributions
600*4f1223e8SApple OSS Distributions pthread_join(pthread, NULL);
601*4f1223e8SApple OSS Distributions
602*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[0]);
603*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[1]);
604*4f1223e8SApple OSS Distributions }
605*4f1223e8SApple OSS Distributions
606*4f1223e8SApple OSS Distributions /*
607*4f1223e8SApple OSS Distributions * Test 11: Test eventlink wait_signal.
608*4f1223e8SApple OSS Distributions *
609*4f1223e8SApple OSS Distributions * Create an eventlink object, associate threads and test wait_signal.
610*4f1223e8SApple OSS Distributions */
611*4f1223e8SApple OSS Distributions T_DECL(test_eventlink_wait_signal, "eventlink wait_signal", T_META_ASROOT(YES), T_META_TAG_VM_PREFERRED)
612*4f1223e8SApple OSS Distributions {
613*4f1223e8SApple OSS Distributions kern_return_t kr;
614*4f1223e8SApple OSS Distributions mach_port_t port_pair[2];
615*4f1223e8SApple OSS Distributions pthread_t pthread;
616*4f1223e8SApple OSS Distributions mach_port_t self = mach_thread_self();
617*4f1223e8SApple OSS Distributions uint64_t count = 0;
618*4f1223e8SApple OSS Distributions
619*4f1223e8SApple OSS Distributions /* Create an eventlink and associate threads to it */
620*4f1223e8SApple OSS Distributions kr = test_eventlink_create(port_pair);
621*4f1223e8SApple OSS Distributions if (kr != KERN_SUCCESS) {
622*4f1223e8SApple OSS Distributions return;
623*4f1223e8SApple OSS Distributions }
624*4f1223e8SApple OSS Distributions
625*4f1223e8SApple OSS Distributions pthread = thread_create_for_test(test_eventlink_wait_then_signal, (void *)(uintptr_t)port_pair[0]);
626*4f1223e8SApple OSS Distributions
627*4f1223e8SApple OSS Distributions sleep(5);
628*4f1223e8SApple OSS Distributions
629*4f1223e8SApple OSS Distributions /* Associate thread and wait_signal the eventlink */
630*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(port_pair[1], self, 0, 0, 0, 0, MELA_OPTION_NONE);
631*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_associate for object 2");
632*4f1223e8SApple OSS Distributions
633*4f1223e8SApple OSS Distributions /* Wait on the eventlink with timeout */
634*4f1223e8SApple OSS Distributions kr = mach_eventlink_signal_wait_until(port_pair[1], &count, 0, MELSW_OPTION_NONE,
635*4f1223e8SApple OSS Distributions KERN_CLOCK_MACH_ABSOLUTE_TIME, 0);
636*4f1223e8SApple OSS Distributions
637*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_signal_wait_until");
638*4f1223e8SApple OSS Distributions T_EXPECT_EQ(count, (uint64_t)1, "mach_eventlink_signal_wait_until returned correct count value");
639*4f1223e8SApple OSS Distributions
640*4f1223e8SApple OSS Distributions pthread_join(pthread, NULL);
641*4f1223e8SApple OSS Distributions
642*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[0]);
643*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[1]);
644*4f1223e8SApple OSS Distributions }
645*4f1223e8SApple OSS Distributions
646*4f1223e8SApple OSS Distributions /*
647*4f1223e8SApple OSS Distributions * Test 12: Test eventlink wait_signal with no wait.
648*4f1223e8SApple OSS Distributions *
649*4f1223e8SApple OSS Distributions * Create an eventlink object, associate threads and test wait_signal with no wait.
650*4f1223e8SApple OSS Distributions */
651*4f1223e8SApple OSS Distributions T_DECL(test_eventlink_wait_signal_no_wait, "eventlink wait_signal with no wait", T_META_ASROOT(YES), T_META_TAG_VM_PREFERRED)
652*4f1223e8SApple OSS Distributions {
653*4f1223e8SApple OSS Distributions kern_return_t kr;
654*4f1223e8SApple OSS Distributions mach_port_t port_pair[2];
655*4f1223e8SApple OSS Distributions pthread_t pthread;
656*4f1223e8SApple OSS Distributions mach_port_t self = mach_thread_self();
657*4f1223e8SApple OSS Distributions uint64_t count = 0;
658*4f1223e8SApple OSS Distributions
659*4f1223e8SApple OSS Distributions /* Create an eventlink and associate threads to it */
660*4f1223e8SApple OSS Distributions kr = test_eventlink_create(port_pair);
661*4f1223e8SApple OSS Distributions if (kr != KERN_SUCCESS) {
662*4f1223e8SApple OSS Distributions return;
663*4f1223e8SApple OSS Distributions }
664*4f1223e8SApple OSS Distributions
665*4f1223e8SApple OSS Distributions pthread = thread_create_for_test(test_eventlink_wait_then_wait_signal_with_no_wait, (void *)(uintptr_t)port_pair[0]);
666*4f1223e8SApple OSS Distributions
667*4f1223e8SApple OSS Distributions sleep(5);
668*4f1223e8SApple OSS Distributions
669*4f1223e8SApple OSS Distributions /* Associate thread and wait_signal the eventlink */
670*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(port_pair[1], self, 0, 0, 0, 0, MELA_OPTION_NONE);
671*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_associate for object 2");
672*4f1223e8SApple OSS Distributions
673*4f1223e8SApple OSS Distributions /* Wait on the eventlink with timeout */
674*4f1223e8SApple OSS Distributions kr = mach_eventlink_signal_wait_until(port_pair[1], &count, 0, MELSW_OPTION_NONE,
675*4f1223e8SApple OSS Distributions KERN_CLOCK_MACH_ABSOLUTE_TIME, 0);
676*4f1223e8SApple OSS Distributions
677*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_signal_wait_until");
678*4f1223e8SApple OSS Distributions T_EXPECT_EQ(count, (uint64_t)1, "mach_eventlink_signal_wait_until returned correct count value");
679*4f1223e8SApple OSS Distributions
680*4f1223e8SApple OSS Distributions pthread_join(pthread, NULL);
681*4f1223e8SApple OSS Distributions
682*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[0]);
683*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[1]);
684*4f1223e8SApple OSS Distributions }
685*4f1223e8SApple OSS Distributions
686*4f1223e8SApple OSS Distributions /*
687*4f1223e8SApple OSS Distributions * Test 13: Test eventlink wait_signal with prepost.
688*4f1223e8SApple OSS Distributions *
689*4f1223e8SApple OSS Distributions * Create an eventlink object, associate threads and test wait_signal with prepost.
690*4f1223e8SApple OSS Distributions */
691*4f1223e8SApple OSS Distributions T_DECL(test_eventlink_wait_signal_prepost, "eventlink wait_signal with prepost", T_META_ASROOT(YES), T_META_TAG_VM_PREFERRED)
692*4f1223e8SApple OSS Distributions {
693*4f1223e8SApple OSS Distributions kern_return_t kr;
694*4f1223e8SApple OSS Distributions mach_port_t port_pair[2];
695*4f1223e8SApple OSS Distributions pthread_t pthread;
696*4f1223e8SApple OSS Distributions mach_port_t self = mach_thread_self();
697*4f1223e8SApple OSS Distributions uint64_t count = 0;
698*4f1223e8SApple OSS Distributions
699*4f1223e8SApple OSS Distributions /* Create an eventlink and associate threads to it */
700*4f1223e8SApple OSS Distributions kr = test_eventlink_create(port_pair);
701*4f1223e8SApple OSS Distributions if (kr != KERN_SUCCESS) {
702*4f1223e8SApple OSS Distributions return;
703*4f1223e8SApple OSS Distributions }
704*4f1223e8SApple OSS Distributions
705*4f1223e8SApple OSS Distributions pthread = thread_create_for_test(test_eventlink_wait_then_wait_signal_with_prepost, (void *)(uintptr_t)port_pair[0]);
706*4f1223e8SApple OSS Distributions
707*4f1223e8SApple OSS Distributions sleep(5);
708*4f1223e8SApple OSS Distributions
709*4f1223e8SApple OSS Distributions /* Associate thread and wait_signal the eventlink */
710*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(port_pair[1], self, 0, 0, 0, 0, MELA_OPTION_NONE);
711*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_associate for object 2");
712*4f1223e8SApple OSS Distributions
713*4f1223e8SApple OSS Distributions /* Wait on the eventlink with timeout */
714*4f1223e8SApple OSS Distributions kr = mach_eventlink_signal_wait_until(port_pair[1], &count, 0, MELSW_OPTION_NONE,
715*4f1223e8SApple OSS Distributions KERN_CLOCK_MACH_ABSOLUTE_TIME, 0);
716*4f1223e8SApple OSS Distributions
717*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_signal_wait_until");
718*4f1223e8SApple OSS Distributions T_EXPECT_EQ(count, (uint64_t)1, "mach_eventlink_signal_wait_until returned correct count value");
719*4f1223e8SApple OSS Distributions
720*4f1223e8SApple OSS Distributions pthread_join(pthread, NULL);
721*4f1223e8SApple OSS Distributions
722*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[0]);
723*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[1]);
724*4f1223e8SApple OSS Distributions }
725*4f1223e8SApple OSS Distributions
726*4f1223e8SApple OSS Distributions /*
727*4f1223e8SApple OSS Distributions * Test 14: Test eventlink wait_signal with associate on wait option.
728*4f1223e8SApple OSS Distributions *
729*4f1223e8SApple OSS Distributions * Create an eventlink object, set associate on wait on one side and test wait_signal.
730*4f1223e8SApple OSS Distributions */
731*4f1223e8SApple OSS Distributions T_DECL(test_eventlink_wait_signal_associate_on_wait, "eventlink wait_signal associate on wait", T_META_ASROOT(YES), T_META_TAG_VM_PREFERRED)
732*4f1223e8SApple OSS Distributions {
733*4f1223e8SApple OSS Distributions kern_return_t kr;
734*4f1223e8SApple OSS Distributions mach_port_t port_pair[2];
735*4f1223e8SApple OSS Distributions pthread_t pthread;
736*4f1223e8SApple OSS Distributions uint64_t count = 0;
737*4f1223e8SApple OSS Distributions
738*4f1223e8SApple OSS Distributions /* Create an eventlink and associate threads to it */
739*4f1223e8SApple OSS Distributions kr = test_eventlink_create(port_pair);
740*4f1223e8SApple OSS Distributions if (kr != KERN_SUCCESS) {
741*4f1223e8SApple OSS Distributions return;
742*4f1223e8SApple OSS Distributions }
743*4f1223e8SApple OSS Distributions
744*4f1223e8SApple OSS Distributions pthread = thread_create_for_test(test_eventlink_wait_then_signal, (void *)(uintptr_t)port_pair[0]);
745*4f1223e8SApple OSS Distributions
746*4f1223e8SApple OSS Distributions sleep(5);
747*4f1223e8SApple OSS Distributions
748*4f1223e8SApple OSS Distributions /* Set associate on wait and wait_signal the eventlink */
749*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(port_pair[1], MACH_PORT_NULL, 0, 0, 0, 0, MELA_OPTION_ASSOCIATE_ON_WAIT);
750*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_associate with associate on wait for object 2");
751*4f1223e8SApple OSS Distributions
752*4f1223e8SApple OSS Distributions /* Wait on the eventlink with timeout */
753*4f1223e8SApple OSS Distributions kr = mach_eventlink_signal_wait_until(port_pair[1], &count, 0, MELSW_OPTION_NONE,
754*4f1223e8SApple OSS Distributions KERN_CLOCK_MACH_ABSOLUTE_TIME, 0);
755*4f1223e8SApple OSS Distributions
756*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_signal_wait_until");
757*4f1223e8SApple OSS Distributions T_EXPECT_EQ(count, (uint64_t)1, "mach_eventlink_signal_wait_until returned correct count value");
758*4f1223e8SApple OSS Distributions
759*4f1223e8SApple OSS Distributions /* Remove associate on wait option */
760*4f1223e8SApple OSS Distributions kr = mach_eventlink_disassociate(port_pair[1], MELD_OPTION_NONE);
761*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_disassociate");
762*4f1223e8SApple OSS Distributions
763*4f1223e8SApple OSS Distributions /* Wait on the eventlink with timeout */
764*4f1223e8SApple OSS Distributions kr = mach_eventlink_signal_wait_until(port_pair[1], &count, 0, MELSW_OPTION_NONE,
765*4f1223e8SApple OSS Distributions KERN_CLOCK_MACH_ABSOLUTE_TIME, 0);
766*4f1223e8SApple OSS Distributions
767*4f1223e8SApple OSS Distributions T_EXPECT_MACH_ERROR(kr, KERN_INVALID_ARGUMENT, "mach_eventlink_wait_until returned expected error");
768*4f1223e8SApple OSS Distributions
769*4f1223e8SApple OSS Distributions pthread_join(pthread, NULL);
770*4f1223e8SApple OSS Distributions
771*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[0]);
772*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[1]);
773*4f1223e8SApple OSS Distributions }
774*4f1223e8SApple OSS Distributions
775*4f1223e8SApple OSS Distributions /*
776*4f1223e8SApple OSS Distributions * Test 15: Test eventlink wait_signal_loop.
777*4f1223e8SApple OSS Distributions *
778*4f1223e8SApple OSS Distributions * Create an eventlink object, associate threads and test wait_signal in a loop.
779*4f1223e8SApple OSS Distributions */
780*4f1223e8SApple OSS Distributions T_DECL(test_eventlink_wait_signal_loop, "eventlink wait_signal in loop", T_META_ASROOT(YES), T_META_TAG_VM_PREFERRED)
781*4f1223e8SApple OSS Distributions {
782*4f1223e8SApple OSS Distributions kern_return_t kr;
783*4f1223e8SApple OSS Distributions mach_port_t port_pair[2];
784*4f1223e8SApple OSS Distributions pthread_t pthread;
785*4f1223e8SApple OSS Distributions mach_port_t self = mach_thread_self();
786*4f1223e8SApple OSS Distributions uint64_t count = 0;
787*4f1223e8SApple OSS Distributions int i;
788*4f1223e8SApple OSS Distributions
789*4f1223e8SApple OSS Distributions /* Create an eventlink and associate threads to it */
790*4f1223e8SApple OSS Distributions kr = test_eventlink_create(port_pair);
791*4f1223e8SApple OSS Distributions if (kr != KERN_SUCCESS) {
792*4f1223e8SApple OSS Distributions return;
793*4f1223e8SApple OSS Distributions }
794*4f1223e8SApple OSS Distributions
795*4f1223e8SApple OSS Distributions pthread = thread_create_for_test(test_eventlink_wait_then_signal_loop, (void *)(uintptr_t)port_pair[0]);
796*4f1223e8SApple OSS Distributions
797*4f1223e8SApple OSS Distributions /* Associate thread and wait_signal the eventlink */
798*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(port_pair[1], self, 0, 0, 0, 0, MELA_OPTION_NONE);
799*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_associate for object 2");
800*4f1223e8SApple OSS Distributions
801*4f1223e8SApple OSS Distributions for (i = 0; i < g_loop_iterations; i++) {
802*4f1223e8SApple OSS Distributions /* Wait on the eventlink with timeout */
803*4f1223e8SApple OSS Distributions kr = mach_eventlink_signal_wait_until(port_pair[1], &count, 0, MELSW_OPTION_NONE,
804*4f1223e8SApple OSS Distributions KERN_CLOCK_MACH_ABSOLUTE_TIME, 0);
805*4f1223e8SApple OSS Distributions
806*4f1223e8SApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "main thread: mach_eventlink_signal_wait_until");
807*4f1223e8SApple OSS Distributions T_QUIET; T_EXPECT_EQ(count, (uint64_t)(i + 1), "main thread: mach_eventlink_signal_wait_until returned correct count value");
808*4f1223e8SApple OSS Distributions }
809*4f1223e8SApple OSS Distributions
810*4f1223e8SApple OSS Distributions pthread_join(pthread, NULL);
811*4f1223e8SApple OSS Distributions
812*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[0]);
813*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[1]);
814*4f1223e8SApple OSS Distributions }
815*4f1223e8SApple OSS Distributions
816*4f1223e8SApple OSS Distributions
817*4f1223e8SApple OSS Distributions static uint64_t
nanos_to_abs(uint64_t nanos)818*4f1223e8SApple OSS Distributions nanos_to_abs(uint64_t nanos)
819*4f1223e8SApple OSS Distributions {
820*4f1223e8SApple OSS Distributions static mach_timebase_info_data_t timebase_info;
821*4f1223e8SApple OSS Distributions mach_timebase_info(&timebase_info);
822*4f1223e8SApple OSS Distributions return nanos * timebase_info.denom / timebase_info.numer;
823*4f1223e8SApple OSS Distributions }
824*4f1223e8SApple OSS Distributions
825*4f1223e8SApple OSS Distributions static const uint64_t DEFAULT_INTERVAL_NS = 15000000; // 15 ms
826*4f1223e8SApple OSS Distributions
827*4f1223e8SApple OSS Distributions static void
set_realtime(pthread_t thread,uint64_t interval_nanos)828*4f1223e8SApple OSS Distributions set_realtime(pthread_t thread, uint64_t interval_nanos)
829*4f1223e8SApple OSS Distributions {
830*4f1223e8SApple OSS Distributions kern_return_t kr;
831*4f1223e8SApple OSS Distributions thread_time_constraint_policy_data_t pol;
832*4f1223e8SApple OSS Distributions
833*4f1223e8SApple OSS Distributions mach_port_t target_thread = pthread_mach_thread_np(thread);
834*4f1223e8SApple OSS Distributions T_QUIET; T_ASSERT_GT(target_thread, 0, "pthread_mach_thread_np");
835*4f1223e8SApple OSS Distributions
836*4f1223e8SApple OSS Distributions /* 1s 100ms 10ms */
837*4f1223e8SApple OSS Distributions pol.period = (uint32_t)nanos_to_abs(interval_nanos);
838*4f1223e8SApple OSS Distributions pol.constraint = (uint32_t)nanos_to_abs(interval_nanos);
839*4f1223e8SApple OSS Distributions pol.computation = (uint32_t)nanos_to_abs(interval_nanos - 1000000); // 1 ms of leeway
840*4f1223e8SApple OSS Distributions
841*4f1223e8SApple OSS Distributions pol.preemptible = 0; /* Ignored by OS */
842*4f1223e8SApple OSS Distributions kr = thread_policy_set(target_thread, THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t) &pol,
843*4f1223e8SApple OSS Distributions THREAD_TIME_CONSTRAINT_POLICY_COUNT);
844*4f1223e8SApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "thread_policy_set(THREAD_TIME_CONSTRAINT_POLICY)");
845*4f1223e8SApple OSS Distributions }
846*4f1223e8SApple OSS Distributions
847*4f1223e8SApple OSS Distributions
848*4f1223e8SApple OSS Distributions static _Atomic bool suspend_resume_thread_stop = false;
849*4f1223e8SApple OSS Distributions
850*4f1223e8SApple OSS Distributions static void *
test_suspend_resume_thread(void * arg)851*4f1223e8SApple OSS Distributions test_suspend_resume_thread(void *arg)
852*4f1223e8SApple OSS Distributions {
853*4f1223e8SApple OSS Distributions uint64_t count = 0;
854*4f1223e8SApple OSS Distributions mach_port_t suspend_resume_other_thread_port = (mach_port_t) (uintptr_t)arg;
855*4f1223e8SApple OSS Distributions kern_return_t kr1 = KERN_SUCCESS, kr2 = KERN_SUCCESS;
856*4f1223e8SApple OSS Distributions
857*4f1223e8SApple OSS Distributions while (!os_atomic_load(&suspend_resume_thread_stop, relaxed) && kr1 == KERN_SUCCESS && kr2 == KERN_SUCCESS) {
858*4f1223e8SApple OSS Distributions kr1 = thread_suspend(suspend_resume_other_thread_port);
859*4f1223e8SApple OSS Distributions kr2 = thread_resume(suspend_resume_other_thread_port);
860*4f1223e8SApple OSS Distributions count++;
861*4f1223e8SApple OSS Distributions }
862*4f1223e8SApple OSS Distributions
863*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr1, "thread_suspend #%lld", count);
864*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr2, "thread_resume #%lld", count);
865*4f1223e8SApple OSS Distributions
866*4f1223e8SApple OSS Distributions return NULL;
867*4f1223e8SApple OSS Distributions }
868*4f1223e8SApple OSS Distributions
869*4f1223e8SApple OSS Distributions /*
870*4f1223e8SApple OSS Distributions * Test 16: Test suspension of a thread in the middle of a wait-signal operation
871*4f1223e8SApple OSS Distributions * rdar://120761588 rdar://123887338
872*4f1223e8SApple OSS Distributions */
873*4f1223e8SApple OSS Distributions T_DECL(test_eventlink_wait_signal_suspend_loop, "eventlink wait_signal + thread_suspend/resume in loop", T_META_ASROOT(YES))
874*4f1223e8SApple OSS Distributions {
875*4f1223e8SApple OSS Distributions kern_return_t kr;
876*4f1223e8SApple OSS Distributions mach_port_t port_pair[2];
877*4f1223e8SApple OSS Distributions pthread_t pthread, suspend_thread;
878*4f1223e8SApple OSS Distributions mach_port_t self = mach_thread_self();
879*4f1223e8SApple OSS Distributions uint64_t count = 0;
880*4f1223e8SApple OSS Distributions int i;
881*4f1223e8SApple OSS Distributions
882*4f1223e8SApple OSS Distributions /* Create an eventlink and associate threads to it */
883*4f1223e8SApple OSS Distributions kr = test_eventlink_create(port_pair);
884*4f1223e8SApple OSS Distributions if (kr != KERN_SUCCESS) {
885*4f1223e8SApple OSS Distributions return;
886*4f1223e8SApple OSS Distributions }
887*4f1223e8SApple OSS Distributions
888*4f1223e8SApple OSS Distributions pthread = thread_create_for_test(test_eventlink_wait_then_signal_loop, (void *)(uintptr_t)port_pair[0]);
889*4f1223e8SApple OSS Distributions mach_port_t suspend_resume_other_thread_port = pthread_mach_thread_np(pthread);
890*4f1223e8SApple OSS Distributions
891*4f1223e8SApple OSS Distributions /*
892*4f1223e8SApple OSS Distributions * Threads must be RT to get direct handoff mode.
893*4f1223e8SApple OSS Distributions */
894*4f1223e8SApple OSS Distributions set_realtime(pthread_self(), DEFAULT_INTERVAL_NS);
895*4f1223e8SApple OSS Distributions set_realtime(pthread, DEFAULT_INTERVAL_NS);
896*4f1223e8SApple OSS Distributions
897*4f1223e8SApple OSS Distributions suspend_thread = thread_create_for_test(test_suspend_resume_thread, (void *)(uintptr_t)suspend_resume_other_thread_port);
898*4f1223e8SApple OSS Distributions
899*4f1223e8SApple OSS Distributions /* Associate thread and wait_signal the eventlink */
900*4f1223e8SApple OSS Distributions kr = mach_eventlink_associate(port_pair[1], self, 0, 0, 0, 0, MELA_OPTION_NONE);
901*4f1223e8SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "mach_eventlink_associate for object 2");
902*4f1223e8SApple OSS Distributions
903*4f1223e8SApple OSS Distributions for (i = 0; i < g_loop_iterations; i++) {
904*4f1223e8SApple OSS Distributions /* Wait on the eventlink with timeout */
905*4f1223e8SApple OSS Distributions kr = mach_eventlink_signal_wait_until(port_pair[1], &count, 0, MELSW_OPTION_NONE,
906*4f1223e8SApple OSS Distributions KERN_CLOCK_MACH_ABSOLUTE_TIME, 0);
907*4f1223e8SApple OSS Distributions
908*4f1223e8SApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "main thread: mach_eventlink_signal_wait_until");
909*4f1223e8SApple OSS Distributions T_QUIET; T_EXPECT_EQ(count, (uint64_t)(i + 1), "main thread: mach_eventlink_signal_wait_until returned correct count value");
910*4f1223e8SApple OSS Distributions }
911*4f1223e8SApple OSS Distributions
912*4f1223e8SApple OSS Distributions os_atomic_store(&suspend_resume_thread_stop, true, relaxed);
913*4f1223e8SApple OSS Distributions
914*4f1223e8SApple OSS Distributions pthread_join(suspend_thread, NULL);
915*4f1223e8SApple OSS Distributions pthread_join(pthread, NULL);
916*4f1223e8SApple OSS Distributions
917*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[0]);
918*4f1223e8SApple OSS Distributions mach_port_deallocate(mach_task_self(), port_pair[1]);
919*4f1223e8SApple OSS Distributions }
920