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