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