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