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