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