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