1*e3723e1fSApple OSS Distributions /*
2*e3723e1fSApple OSS Distributions * kevent_qos: Tests Synchronous IPC QOS override.
3*e3723e1fSApple OSS Distributions */
4*e3723e1fSApple OSS Distributions
5*e3723e1fSApple OSS Distributions #ifdef T_NAMESPACE
6*e3723e1fSApple OSS Distributions #undef T_NAMESPACE
7*e3723e1fSApple OSS Distributions #endif
8*e3723e1fSApple OSS Distributions
9*e3723e1fSApple OSS Distributions #include <darwintest.h>
10*e3723e1fSApple OSS Distributions #include <darwintest_multiprocess.h>
11*e3723e1fSApple OSS Distributions
12*e3723e1fSApple OSS Distributions #include <dispatch/dispatch.h>
13*e3723e1fSApple OSS Distributions #include <pthread.h>
14*e3723e1fSApple OSS Distributions #include <launch.h>
15*e3723e1fSApple OSS Distributions #include <mach/mach.h>
16*e3723e1fSApple OSS Distributions #include <mach/message.h>
17*e3723e1fSApple OSS Distributions #include <mach/mach_voucher.h>
18*e3723e1fSApple OSS Distributions #include <pthread/workqueue_private.h>
19*e3723e1fSApple OSS Distributions #include <voucher/ipc_pthread_priority_types.h>
20*e3723e1fSApple OSS Distributions #include <servers/bootstrap.h>
21*e3723e1fSApple OSS Distributions #include <stdlib.h>
22*e3723e1fSApple OSS Distributions #include <sys/event.h>
23*e3723e1fSApple OSS Distributions #include <unistd.h>
24*e3723e1fSApple OSS Distributions #include <crt_externs.h>
25*e3723e1fSApple OSS Distributions #include <mach/mach_port.h>
26*e3723e1fSApple OSS Distributions #include <mach/mach_sync_ipc.h>
27*e3723e1fSApple OSS Distributions
28*e3723e1fSApple OSS Distributions T_GLOBAL_META(T_META_NAMESPACE("xnu.kevent_qos"),
29*e3723e1fSApple OSS Distributions T_META_RADAR_COMPONENT_NAME("xnu"),
30*e3723e1fSApple OSS Distributions T_META_RADAR_COMPONENT_VERSION("kevent"));
31*e3723e1fSApple OSS Distributions
32*e3723e1fSApple OSS Distributions #define ARRAYLEN(arr) (sizeof(arr) / sizeof(arr[0]))
33*e3723e1fSApple OSS Distributions
34*e3723e1fSApple OSS Distributions #define INTERMITTENT_TIMEOUT_SEC (3)
35*e3723e1fSApple OSS Distributions #define RECV_TIMEOUT_SECS (4)
36*e3723e1fSApple OSS Distributions #define SEND_TIMEOUT_SECS (6)
37*e3723e1fSApple OSS Distributions #define HELPER_TIMEOUT_SECS (15)
38*e3723e1fSApple OSS Distributions
39*e3723e1fSApple OSS Distributions #define ENV_VAR_QOS (3)
40*e3723e1fSApple OSS Distributions static const char *qos_env[ENV_VAR_QOS] = {"XNU_TEST_QOS_BO", "XNU_TEST_QOS_QO", "XNU_TEST_QOS_AO"};
41*e3723e1fSApple OSS Distributions static const char *qos_name_env[ENV_VAR_QOS] = {"XNU_TEST_QOS_NAME_BO", "XNU_TEST_QOS_NAME_QO", "XNU_TEST_QOS_NAME_AO"};
42*e3723e1fSApple OSS Distributions
43*e3723e1fSApple OSS Distributions #define ENV_VAR_FUNCTION (1)
44*e3723e1fSApple OSS Distributions static const char *wl_function_name = "XNU_TEST_WL_FUNCTION";
45*e3723e1fSApple OSS Distributions
46*e3723e1fSApple OSS Distributions static qos_class_t g_expected_qos[ENV_VAR_QOS];
47*e3723e1fSApple OSS Distributions static const char *g_expected_qos_name[ENV_VAR_QOS];
48*e3723e1fSApple OSS Distributions
49*e3723e1fSApple OSS Distributions #define ENV_QOS_BEFORE_OVERRIDE (0)
50*e3723e1fSApple OSS Distributions #define ENV_QOS_QUEUE_OVERRIDE (1)
51*e3723e1fSApple OSS Distributions #define ENV_QOS_AFTER_OVERRIDE (2)
52*e3723e1fSApple OSS Distributions
53*e3723e1fSApple OSS Distributions #define USR_THROTTLE_LEVEL_TIER0 0
54*e3723e1fSApple OSS Distributions #define USR_THROTTLE_LEVEL_TIER1 1
55*e3723e1fSApple OSS Distributions
56*e3723e1fSApple OSS Distributions struct test_msg {
57*e3723e1fSApple OSS Distributions mach_msg_header_t header;
58*e3723e1fSApple OSS Distributions mach_msg_body_t body;
59*e3723e1fSApple OSS Distributions mach_msg_port_descriptor_t port_descriptor;
60*e3723e1fSApple OSS Distributions mach_msg_option_t opts;
61*e3723e1fSApple OSS Distributions mach_msg_priority_t qos;
62*e3723e1fSApple OSS Distributions };
63*e3723e1fSApple OSS Distributions
64*e3723e1fSApple OSS Distributions #pragma mark pthread callbacks
65*e3723e1fSApple OSS Distributions
66*e3723e1fSApple OSS Distributions static pthread_t
67*e3723e1fSApple OSS Distributions thread_create_at_qos(qos_class_t qos, void * (*function)(void *));
68*e3723e1fSApple OSS Distributions static void
69*e3723e1fSApple OSS Distributions send(mach_port_t send_port, mach_port_t reply_port, mach_port_t msg_port, qos_class_t qos, mach_msg_option_t options);
70*e3723e1fSApple OSS Distributions static void
71*e3723e1fSApple OSS Distributions enable_kevent(uint64_t *workloop_id, unsigned long long port);
72*e3723e1fSApple OSS Distributions static void
73*e3723e1fSApple OSS Distributions populate_kevent(struct kevent_qos_s *kev, unsigned long long port);
74*e3723e1fSApple OSS Distributions
75*e3723e1fSApple OSS Distributions static void
worker_cb(pthread_priority_t __unused priority)76*e3723e1fSApple OSS Distributions worker_cb(pthread_priority_t __unused priority)
77*e3723e1fSApple OSS Distributions {
78*e3723e1fSApple OSS Distributions T_FAIL("a worker thread was created");
79*e3723e1fSApple OSS Distributions }
80*e3723e1fSApple OSS Distributions
81*e3723e1fSApple OSS Distributions static void
event_cb(void ** __unused events,int * __unused nevents)82*e3723e1fSApple OSS Distributions event_cb(void ** __unused events, int * __unused nevents)
83*e3723e1fSApple OSS Distributions {
84*e3723e1fSApple OSS Distributions T_FAIL("a kevent routine was called instead of workloop");
85*e3723e1fSApple OSS Distributions }
86*e3723e1fSApple OSS Distributions
87*e3723e1fSApple OSS Distributions static uint32_t
get_user_promotion_basepri(void)88*e3723e1fSApple OSS Distributions get_user_promotion_basepri(void)
89*e3723e1fSApple OSS Distributions {
90*e3723e1fSApple OSS Distributions mach_msg_type_number_t count = THREAD_POLICY_STATE_COUNT;
91*e3723e1fSApple OSS Distributions struct thread_policy_state thread_policy;
92*e3723e1fSApple OSS Distributions boolean_t get_default = FALSE;
93*e3723e1fSApple OSS Distributions mach_port_t thread_port = pthread_mach_thread_np(pthread_self());
94*e3723e1fSApple OSS Distributions
95*e3723e1fSApple OSS Distributions kern_return_t kr = thread_policy_get(thread_port, THREAD_POLICY_STATE,
96*e3723e1fSApple OSS Distributions (thread_policy_t)&thread_policy, &count, &get_default);
97*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "thread_policy_get");
98*e3723e1fSApple OSS Distributions return thread_policy.thps_user_promotion_basepri;
99*e3723e1fSApple OSS Distributions }
100*e3723e1fSApple OSS Distributions
101*e3723e1fSApple OSS Distributions static uint32_t
get_thread_iotier(void)102*e3723e1fSApple OSS Distributions get_thread_iotier(void)
103*e3723e1fSApple OSS Distributions {
104*e3723e1fSApple OSS Distributions mach_msg_type_number_t count = THREAD_POLICY_STATE_COUNT;
105*e3723e1fSApple OSS Distributions struct thread_policy_state thread_policy;
106*e3723e1fSApple OSS Distributions boolean_t get_default = FALSE;
107*e3723e1fSApple OSS Distributions mach_port_t thread_port = pthread_mach_thread_np(pthread_self());
108*e3723e1fSApple OSS Distributions
109*e3723e1fSApple OSS Distributions kern_return_t kr = thread_policy_get(thread_port, THREAD_POLICY_STATE,
110*e3723e1fSApple OSS Distributions (thread_policy_t)&thread_policy, &count, &get_default);
111*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "thread_policy_get");
112*e3723e1fSApple OSS Distributions return (thread_policy.effective >> POLICY_EFF_IO_TIER_SHIFT) & POLICY_EFF_IO_TIER_MASK;
113*e3723e1fSApple OSS Distributions }
114*e3723e1fSApple OSS Distributions
115*e3723e1fSApple OSS Distributions #define EXPECT_QOS_EQ(qos, ...) do { \
116*e3723e1fSApple OSS Distributions if ((qos) == QOS_CLASS_USER_INTERACTIVE) { \
117*e3723e1fSApple OSS Distributions T_EXPECT_EFFECTIVE_QOS_EQ(QOS_CLASS_USER_INITIATED, __VA_ARGS__); \
118*e3723e1fSApple OSS Distributions T_EXPECT_EQ(47u, get_user_promotion_basepri(), __VA_ARGS__); \
119*e3723e1fSApple OSS Distributions } else { \
120*e3723e1fSApple OSS Distributions T_EXPECT_EFFECTIVE_QOS_EQ(qos, __VA_ARGS__); \
121*e3723e1fSApple OSS Distributions } \
122*e3723e1fSApple OSS Distributions } while (0)
123*e3723e1fSApple OSS Distributions
124*e3723e1fSApple OSS Distributions #define EXPECT_TEST_MSG(_ke) do { \
125*e3723e1fSApple OSS Distributions struct kevent_qos_s *ke = _ke; \
126*e3723e1fSApple OSS Distributions mach_msg_header_t *hdr = (mach_msg_header_t *)ke->ext[0]; \
127*e3723e1fSApple OSS Distributions T_ASSERT_NOTNULL(hdr, "has a message"); \
128*e3723e1fSApple OSS Distributions T_ASSERT_EQ(hdr->msgh_size, (uint32_t)sizeof(struct test_msg), "of the right size"); \
129*e3723e1fSApple OSS Distributions struct test_msg *tmsg = (struct test_msg *)hdr; \
130*e3723e1fSApple OSS Distributions if (tmsg->opts & MACH_SEND_PROPAGATE_QOS) { \
131*e3723e1fSApple OSS Distributions T_EXPECT_EQ(tmsg->qos, ((uint32_t)(ke->ext[2] >> 32)), \
132*e3723e1fSApple OSS Distributions "propagation works"); \
133*e3723e1fSApple OSS Distributions } \
134*e3723e1fSApple OSS Distributions } while (0)
135*e3723e1fSApple OSS Distributions
136*e3723e1fSApple OSS Distributions /*
137*e3723e1fSApple OSS Distributions * Basic WL handler callback, it sleeps for n seconds and then checks the
138*e3723e1fSApple OSS Distributions * effective Qos of the servicer thread.
139*e3723e1fSApple OSS Distributions */
140*e3723e1fSApple OSS Distributions static void
workloop_cb_test_intransit(uint64_t * workloop_id __unused,void ** eventslist,int * events)141*e3723e1fSApple OSS Distributions workloop_cb_test_intransit(uint64_t *workloop_id __unused, void **eventslist, int *events)
142*e3723e1fSApple OSS Distributions {
143*e3723e1fSApple OSS Distributions T_LOG("Workloop handler workloop_cb_test_intransit called. "
144*e3723e1fSApple OSS Distributions "Will wait for %d seconds to make sure client enqueues the sync msg \n",
145*e3723e1fSApple OSS Distributions 2 * RECV_TIMEOUT_SECS);
146*e3723e1fSApple OSS Distributions
147*e3723e1fSApple OSS Distributions EXPECT_TEST_MSG(*eventslist);
148*e3723e1fSApple OSS Distributions
149*e3723e1fSApple OSS Distributions /* Wait for the client to send the high priority message to override the qos */
150*e3723e1fSApple OSS Distributions sleep(2 * RECV_TIMEOUT_SECS);
151*e3723e1fSApple OSS Distributions
152*e3723e1fSApple OSS Distributions /* Skip the test if we can't check Qos */
153*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
154*e3723e1fSApple OSS Distributions
155*e3723e1fSApple OSS Distributions /* The effective Qos should be the one expected after override */
156*e3723e1fSApple OSS Distributions EXPECT_QOS_EQ(g_expected_qos[ENV_QOS_AFTER_OVERRIDE],
157*e3723e1fSApple OSS Distributions "dispatch_source event handler QoS should be %s", g_expected_qos_name[ENV_QOS_AFTER_OVERRIDE]);
158*e3723e1fSApple OSS Distributions
159*e3723e1fSApple OSS Distributions *events = 0;
160*e3723e1fSApple OSS Distributions T_END;
161*e3723e1fSApple OSS Distributions }
162*e3723e1fSApple OSS Distributions
163*e3723e1fSApple OSS Distributions /*
164*e3723e1fSApple OSS Distributions * WL handler which checks if the servicer thread has correct Qos.
165*e3723e1fSApple OSS Distributions */
166*e3723e1fSApple OSS Distributions static void
workloop_cb_test_sync_send(uint64_t * workloop_id __unused,void ** eventslist,int * events)167*e3723e1fSApple OSS Distributions workloop_cb_test_sync_send(uint64_t *workloop_id __unused, void **eventslist, int *events)
168*e3723e1fSApple OSS Distributions {
169*e3723e1fSApple OSS Distributions T_LOG("Workloop handler workloop_cb_test_sync_send called");
170*e3723e1fSApple OSS Distributions
171*e3723e1fSApple OSS Distributions EXPECT_TEST_MSG(*eventslist);
172*e3723e1fSApple OSS Distributions
173*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
174*e3723e1fSApple OSS Distributions
175*e3723e1fSApple OSS Distributions /* The effective Qos should be the one expected after override */
176*e3723e1fSApple OSS Distributions EXPECT_QOS_EQ(g_expected_qos[ENV_QOS_AFTER_OVERRIDE],
177*e3723e1fSApple OSS Distributions "dispatch_source event handler QoS should be %s", g_expected_qos_name[ENV_QOS_AFTER_OVERRIDE]);
178*e3723e1fSApple OSS Distributions
179*e3723e1fSApple OSS Distributions *events = 0;
180*e3723e1fSApple OSS Distributions T_END;
181*e3723e1fSApple OSS Distributions }
182*e3723e1fSApple OSS Distributions
183*e3723e1fSApple OSS Distributions /*
184*e3723e1fSApple OSS Distributions * WL handler which checks if the servicer thread has correct Qos.
185*e3723e1fSApple OSS Distributions */
186*e3723e1fSApple OSS Distributions static void
workloop_cb_test_kernel_sync_send(uint64_t * workloop_id __unused,void ** eventslist,int * events)187*e3723e1fSApple OSS Distributions workloop_cb_test_kernel_sync_send(uint64_t *workloop_id __unused, void **eventslist, int *events)
188*e3723e1fSApple OSS Distributions {
189*e3723e1fSApple OSS Distributions T_LOG("Workloop handler workloop_cb_test_kernel_sync_send called");
190*e3723e1fSApple OSS Distributions
191*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
192*e3723e1fSApple OSS Distributions
193*e3723e1fSApple OSS Distributions /* Wait for the kernel upcall to block on receive */
194*e3723e1fSApple OSS Distributions sleep(2 * RECV_TIMEOUT_SECS);
195*e3723e1fSApple OSS Distributions
196*e3723e1fSApple OSS Distributions /* The effective Qos should be the one expected after override */
197*e3723e1fSApple OSS Distributions EXPECT_QOS_EQ(g_expected_qos[ENV_QOS_AFTER_OVERRIDE],
198*e3723e1fSApple OSS Distributions "dispatch_source event handler QoS should be %s", g_expected_qos_name[ENV_QOS_AFTER_OVERRIDE]);
199*e3723e1fSApple OSS Distributions
200*e3723e1fSApple OSS Distributions *events = 0;
201*e3723e1fSApple OSS Distributions T_END;
202*e3723e1fSApple OSS Distributions }
203*e3723e1fSApple OSS Distributions
204*e3723e1fSApple OSS Distributions /*
205*e3723e1fSApple OSS Distributions * WL handler which checks if the servicer thread has correct Qos.
206*e3723e1fSApple OSS Distributions */
207*e3723e1fSApple OSS Distributions static void
workloop_cb_test_kernel_async_send(uint64_t * workloop_id __unused,void ** eventslist,int * events)208*e3723e1fSApple OSS Distributions workloop_cb_test_kernel_async_send(uint64_t *workloop_id __unused, void **eventslist, int *events)
209*e3723e1fSApple OSS Distributions {
210*e3723e1fSApple OSS Distributions T_LOG("Workloop handler workloop_cb_test_kernel_sync_send called");
211*e3723e1fSApple OSS Distributions
212*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
213*e3723e1fSApple OSS Distributions
214*e3723e1fSApple OSS Distributions /* The effective Qos should be the one expected after override */
215*e3723e1fSApple OSS Distributions EXPECT_QOS_EQ(g_expected_qos[ENV_QOS_AFTER_OVERRIDE],
216*e3723e1fSApple OSS Distributions "dispatch_source event handler QoS should be %s", g_expected_qos_name[ENV_QOS_AFTER_OVERRIDE]);
217*e3723e1fSApple OSS Distributions
218*e3723e1fSApple OSS Distributions T_ASSERT_EQ(get_thread_iotier(), USR_THROTTLE_LEVEL_TIER0, "Thread IOTier has correct override");
219*e3723e1fSApple OSS Distributions
220*e3723e1fSApple OSS Distributions *events = 0;
221*e3723e1fSApple OSS Distributions T_END;
222*e3723e1fSApple OSS Distributions }
223*e3723e1fSApple OSS Distributions
224*e3723e1fSApple OSS Distributions /*
225*e3723e1fSApple OSS Distributions * WL handler which checks the overridden Qos and then enables the knote and checks
226*e3723e1fSApple OSS Distributions * for the Qos again if that dropped the sync ipc override.
227*e3723e1fSApple OSS Distributions */
228*e3723e1fSApple OSS Distributions static void
workloop_cb_test_sync_send_and_enable(uint64_t * workloop_id,struct kevent_qos_s ** eventslist,int * events)229*e3723e1fSApple OSS Distributions workloop_cb_test_sync_send_and_enable(uint64_t *workloop_id, struct kevent_qos_s **eventslist, int *events)
230*e3723e1fSApple OSS Distributions {
231*e3723e1fSApple OSS Distributions unsigned override_priority;
232*e3723e1fSApple OSS Distributions unsigned reenable_priority;
233*e3723e1fSApple OSS Distributions
234*e3723e1fSApple OSS Distributions T_LOG("Workloop handler workloop_cb_test_sync_send_and_enable called");
235*e3723e1fSApple OSS Distributions
236*e3723e1fSApple OSS Distributions EXPECT_TEST_MSG(*eventslist);
237*e3723e1fSApple OSS Distributions
238*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
239*e3723e1fSApple OSS Distributions
240*e3723e1fSApple OSS Distributions /* The effective Qos should be the one expected after override */
241*e3723e1fSApple OSS Distributions EXPECT_QOS_EQ(g_expected_qos[ENV_QOS_AFTER_OVERRIDE],
242*e3723e1fSApple OSS Distributions "dispatch_source event handler QoS should be %s", g_expected_qos_name[ENV_QOS_AFTER_OVERRIDE]);
243*e3723e1fSApple OSS Distributions
244*e3723e1fSApple OSS Distributions /* Snapshot the current override priority */
245*e3723e1fSApple OSS Distributions override_priority = get_user_promotion_basepri();
246*e3723e1fSApple OSS Distributions
247*e3723e1fSApple OSS Distributions /* Enable the knote */
248*e3723e1fSApple OSS Distributions struct kevent_qos_s *kev = *eventslist;
249*e3723e1fSApple OSS Distributions enable_kevent(workloop_id, kev->ident);
250*e3723e1fSApple OSS Distributions
251*e3723e1fSApple OSS Distributions /*
252*e3723e1fSApple OSS Distributions * Check if the override has been dropped, check for priority instead of qos since
253*e3723e1fSApple OSS Distributions * there will be async qos push.
254*e3723e1fSApple OSS Distributions */
255*e3723e1fSApple OSS Distributions reenable_priority = get_user_promotion_basepri();
256*e3723e1fSApple OSS Distributions T_EXPECT_LT(reenable_priority, override_priority,
257*e3723e1fSApple OSS Distributions "thread's current override priority %d should be less than override priority prior to enabling knote %d",
258*e3723e1fSApple OSS Distributions reenable_priority, override_priority);
259*e3723e1fSApple OSS Distributions
260*e3723e1fSApple OSS Distributions *events = 0;
261*e3723e1fSApple OSS Distributions T_END;
262*e3723e1fSApple OSS Distributions }
263*e3723e1fSApple OSS Distributions
264*e3723e1fSApple OSS Distributions /*
265*e3723e1fSApple OSS Distributions * WL handler which checks the overridden Qos and then handoffs the IPC,
266*e3723e1fSApple OSS Distributions * enables the knote and checks for the Qos again that it hasn't dropped the sync ipc override.
267*e3723e1fSApple OSS Distributions */
268*e3723e1fSApple OSS Distributions static void
workloop_cb_test_sync_send_and_enable_handoff(uint64_t * workloop_id,struct kevent_qos_s ** eventslist,int * events)269*e3723e1fSApple OSS Distributions workloop_cb_test_sync_send_and_enable_handoff(uint64_t *workloop_id, struct kevent_qos_s **eventslist, int *events)
270*e3723e1fSApple OSS Distributions {
271*e3723e1fSApple OSS Distributions unsigned override_priority;
272*e3723e1fSApple OSS Distributions int error;
273*e3723e1fSApple OSS Distributions
274*e3723e1fSApple OSS Distributions T_LOG("Workloop handler workloop_cb_test_sync_send_and_enable_handoff called");
275*e3723e1fSApple OSS Distributions
276*e3723e1fSApple OSS Distributions EXPECT_TEST_MSG(*eventslist);
277*e3723e1fSApple OSS Distributions
278*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
279*e3723e1fSApple OSS Distributions
280*e3723e1fSApple OSS Distributions /* The effective Qos should be the one expected after override */
281*e3723e1fSApple OSS Distributions EXPECT_QOS_EQ(g_expected_qos[ENV_QOS_AFTER_OVERRIDE],
282*e3723e1fSApple OSS Distributions "dispatch_source event handler QoS should be %s",
283*e3723e1fSApple OSS Distributions g_expected_qos_name[ENV_QOS_AFTER_OVERRIDE]);
284*e3723e1fSApple OSS Distributions
285*e3723e1fSApple OSS Distributions /* Snapshot the current override priority */
286*e3723e1fSApple OSS Distributions override_priority = get_user_promotion_basepri();
287*e3723e1fSApple OSS Distributions
288*e3723e1fSApple OSS Distributions struct kevent_qos_s *kev = *eventslist;
289*e3723e1fSApple OSS Distributions mach_msg_header_t *hdr = (mach_msg_header_t *)kev->ext[0];
290*e3723e1fSApple OSS Distributions
291*e3723e1fSApple OSS Distributions /* handoff the IPC */
292*e3723e1fSApple OSS Distributions struct kevent_qos_s handoff_kev = {
293*e3723e1fSApple OSS Distributions .filter = EVFILT_WORKLOOP,
294*e3723e1fSApple OSS Distributions .ident = hdr->msgh_remote_port,
295*e3723e1fSApple OSS Distributions .flags = EV_ADD | EV_DISABLE,
296*e3723e1fSApple OSS Distributions .fflags = 0x80000000,
297*e3723e1fSApple OSS Distributions };
298*e3723e1fSApple OSS Distributions
299*e3723e1fSApple OSS Distributions error = kevent_id(*workloop_id, &handoff_kev, 1, &handoff_kev, 1, NULL,
300*e3723e1fSApple OSS Distributions NULL, KEVENT_FLAG_WORKLOOP | KEVENT_FLAG_ERROR_EVENTS | KEVENT_FLAG_DYNAMIC_KQ_MUST_EXIST);
301*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(error, "kevent_id");
302*e3723e1fSApple OSS Distributions T_ASSERT_EQ(0, error, "Handed off the sync IPC");
303*e3723e1fSApple OSS Distributions
304*e3723e1fSApple OSS Distributions /* Enable the knote */
305*e3723e1fSApple OSS Distributions enable_kevent(workloop_id, kev->ident);
306*e3723e1fSApple OSS Distributions
307*e3723e1fSApple OSS Distributions /*
308*e3723e1fSApple OSS Distributions * Check if the override has not been dropped.
309*e3723e1fSApple OSS Distributions */
310*e3723e1fSApple OSS Distributions EXPECT_QOS_EQ(g_expected_qos[ENV_QOS_AFTER_OVERRIDE],
311*e3723e1fSApple OSS Distributions "dispatch_source event handler QoS should still be %s",
312*e3723e1fSApple OSS Distributions g_expected_qos_name[ENV_QOS_AFTER_OVERRIDE]);
313*e3723e1fSApple OSS Distributions
314*e3723e1fSApple OSS Distributions *events = 0;
315*e3723e1fSApple OSS Distributions T_END;
316*e3723e1fSApple OSS Distributions }
317*e3723e1fSApple OSS Distributions
318*e3723e1fSApple OSS Distributions /*
319*e3723e1fSApple OSS Distributions * WL handler receives the first message and checks sync ipc override, then enables the knote
320*e3723e1fSApple OSS Distributions * and receives 2nd message and checks it sync ipc override.
321*e3723e1fSApple OSS Distributions */
322*e3723e1fSApple OSS Distributions static int send_two_sync_handler_called = 0;
323*e3723e1fSApple OSS Distributions static void
workloop_cb_test_send_two_sync(uint64_t * workloop_id __unused,struct kevent_qos_s ** eventslist,int * events)324*e3723e1fSApple OSS Distributions workloop_cb_test_send_two_sync(uint64_t *workloop_id __unused, struct kevent_qos_s **eventslist, int *events)
325*e3723e1fSApple OSS Distributions {
326*e3723e1fSApple OSS Distributions T_LOG("Workloop handler workloop_cb_test_send_two_sync called for %d time", send_two_sync_handler_called + 1);
327*e3723e1fSApple OSS Distributions
328*e3723e1fSApple OSS Distributions EXPECT_TEST_MSG(*eventslist);
329*e3723e1fSApple OSS Distributions
330*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
331*e3723e1fSApple OSS Distributions
332*e3723e1fSApple OSS Distributions T_LOG("Number of events received is %d\n", *events);
333*e3723e1fSApple OSS Distributions
334*e3723e1fSApple OSS Distributions if (send_two_sync_handler_called == 0) {
335*e3723e1fSApple OSS Distributions /* The effective Qos should be the one expected after override */
336*e3723e1fSApple OSS Distributions EXPECT_QOS_EQ(g_expected_qos[ENV_QOS_AFTER_OVERRIDE],
337*e3723e1fSApple OSS Distributions "dispatch_source event handler QoS should be %s", g_expected_qos_name[ENV_QOS_AFTER_OVERRIDE]);
338*e3723e1fSApple OSS Distributions
339*e3723e1fSApple OSS Distributions /* Enable the knote to get 2nd message */
340*e3723e1fSApple OSS Distributions struct kevent_qos_s *kev = *eventslist;
341*e3723e1fSApple OSS Distributions uint64_t port = kev->ident;
342*e3723e1fSApple OSS Distributions populate_kevent(kev, port);
343*e3723e1fSApple OSS Distributions *events = 1;
344*e3723e1fSApple OSS Distributions } else {
345*e3723e1fSApple OSS Distributions EXPECT_QOS_EQ(g_expected_qos[ENV_QOS_BEFORE_OVERRIDE],
346*e3723e1fSApple OSS Distributions "dispatch_source event handler QoS should be %s", g_expected_qos_name[ENV_QOS_BEFORE_OVERRIDE]);
347*e3723e1fSApple OSS Distributions *events = 0;
348*e3723e1fSApple OSS Distributions T_END;
349*e3723e1fSApple OSS Distributions }
350*e3723e1fSApple OSS Distributions send_two_sync_handler_called++;
351*e3723e1fSApple OSS Distributions }
352*e3723e1fSApple OSS Distributions
353*e3723e1fSApple OSS Distributions /*
354*e3723e1fSApple OSS Distributions * Checks the sync ipc override and then waits for client to destroy the
355*e3723e1fSApple OSS Distributions * special reply port and checks if that removes the sync ipc override.
356*e3723e1fSApple OSS Distributions */
357*e3723e1fSApple OSS Distributions static boolean_t two_send_and_destroy_test_passed = FALSE;
358*e3723e1fSApple OSS Distributions static int two_send_and_destroy_handler = 0;
359*e3723e1fSApple OSS Distributions static void
workloop_cb_test_two_send_and_destroy(uint64_t * workloop_id __unused,struct kevent_qos_s ** eventslist __unused,int * events)360*e3723e1fSApple OSS Distributions workloop_cb_test_two_send_and_destroy(uint64_t *workloop_id __unused, struct kevent_qos_s **eventslist __unused, int *events)
361*e3723e1fSApple OSS Distributions {
362*e3723e1fSApple OSS Distributions T_LOG("Workloop handler workloop_cb_test_two_send_and_destroy called %d times", two_send_and_destroy_handler + 1);
363*e3723e1fSApple OSS Distributions
364*e3723e1fSApple OSS Distributions EXPECT_TEST_MSG(*eventslist);
365*e3723e1fSApple OSS Distributions
366*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
367*e3723e1fSApple OSS Distributions
368*e3723e1fSApple OSS Distributions if (two_send_and_destroy_handler == 0) {
369*e3723e1fSApple OSS Distributions /* Sleep to make sure the mqueue gets full */
370*e3723e1fSApple OSS Distributions sleep(RECV_TIMEOUT_SECS);
371*e3723e1fSApple OSS Distributions
372*e3723e1fSApple OSS Distributions /* The effective Qos should be the one expected after override */
373*e3723e1fSApple OSS Distributions EXPECT_QOS_EQ(g_expected_qos[ENV_QOS_AFTER_OVERRIDE],
374*e3723e1fSApple OSS Distributions "dispatch_source event handler QoS should be %s", g_expected_qos_name[ENV_QOS_AFTER_OVERRIDE]);
375*e3723e1fSApple OSS Distributions
376*e3723e1fSApple OSS Distributions sleep(SEND_TIMEOUT_SECS);
377*e3723e1fSApple OSS Distributions
378*e3723e1fSApple OSS Distributions /* Special reply port should have been destroyed, check Qos again */
379*e3723e1fSApple OSS Distributions EXPECT_QOS_EQ(g_expected_qos[ENV_QOS_BEFORE_OVERRIDE],
380*e3723e1fSApple OSS Distributions "dispatch_source event handler QoS should be %s", g_expected_qos_name[ENV_QOS_BEFORE_OVERRIDE]);
381*e3723e1fSApple OSS Distributions
382*e3723e1fSApple OSS Distributions two_send_and_destroy_test_passed = TRUE;
383*e3723e1fSApple OSS Distributions } else {
384*e3723e1fSApple OSS Distributions if (two_send_and_destroy_test_passed) {
385*e3723e1fSApple OSS Distributions T_END;
386*e3723e1fSApple OSS Distributions }
387*e3723e1fSApple OSS Distributions }
388*e3723e1fSApple OSS Distributions
389*e3723e1fSApple OSS Distributions /* Enable the knote to get next message */
390*e3723e1fSApple OSS Distributions struct kevent_qos_s *kev = *eventslist;
391*e3723e1fSApple OSS Distributions uint64_t port = kev->ident;
392*e3723e1fSApple OSS Distributions populate_kevent(kev, port);
393*e3723e1fSApple OSS Distributions *events = 1;
394*e3723e1fSApple OSS Distributions two_send_and_destroy_handler++;
395*e3723e1fSApple OSS Distributions T_LOG("Handler returning \n");
396*e3723e1fSApple OSS Distributions }
397*e3723e1fSApple OSS Distributions
398*e3723e1fSApple OSS Distributions static mach_port_type_t
get_reply_port(struct kevent_qos_s * kev)399*e3723e1fSApple OSS Distributions get_reply_port(struct kevent_qos_s *kev)
400*e3723e1fSApple OSS Distributions {
401*e3723e1fSApple OSS Distributions mach_msg_header_t *hdr;
402*e3723e1fSApple OSS Distributions mach_port_t reply_port;
403*e3723e1fSApple OSS Distributions mach_port_type_t type;
404*e3723e1fSApple OSS Distributions kern_return_t kr;
405*e3723e1fSApple OSS Distributions
406*e3723e1fSApple OSS Distributions hdr = (void*)kev->ext[0];
407*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_NOTNULL(hdr, "msg hdr");
408*e3723e1fSApple OSS Distributions
409*e3723e1fSApple OSS Distributions reply_port = hdr->msgh_remote_port;
410*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_TRUE(MACH_PORT_VALID(reply_port), "reply port valid");
411*e3723e1fSApple OSS Distributions kr = mach_port_type(mach_task_self(), reply_port, &type);
412*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_port_type");
413*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_TRUE(type & MACH_PORT_TYPE_SEND_ONCE, "send once received");
414*e3723e1fSApple OSS Distributions
415*e3723e1fSApple OSS Distributions return reply_port;
416*e3723e1fSApple OSS Distributions }
417*e3723e1fSApple OSS Distributions
418*e3723e1fSApple OSS Distributions static void
send_reply(mach_port_t reply_port)419*e3723e1fSApple OSS Distributions send_reply(mach_port_t reply_port)
420*e3723e1fSApple OSS Distributions {
421*e3723e1fSApple OSS Distributions kern_return_t kr;
422*e3723e1fSApple OSS Distributions
423*e3723e1fSApple OSS Distributions struct {
424*e3723e1fSApple OSS Distributions mach_msg_header_t header;
425*e3723e1fSApple OSS Distributions } send_msg = {
426*e3723e1fSApple OSS Distributions .header = {
427*e3723e1fSApple OSS Distributions .msgh_remote_port = reply_port,
428*e3723e1fSApple OSS Distributions .msgh_local_port = MACH_PORT_NULL,
429*e3723e1fSApple OSS Distributions .msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0),
430*e3723e1fSApple OSS Distributions .msgh_id = 0x100,
431*e3723e1fSApple OSS Distributions .msgh_size = sizeof(send_msg),
432*e3723e1fSApple OSS Distributions },
433*e3723e1fSApple OSS Distributions };
434*e3723e1fSApple OSS Distributions
435*e3723e1fSApple OSS Distributions kr = mach_msg(&(send_msg.header),
436*e3723e1fSApple OSS Distributions MACH_SEND_MSG,
437*e3723e1fSApple OSS Distributions send_msg.header.msgh_size,
438*e3723e1fSApple OSS Distributions 0,
439*e3723e1fSApple OSS Distributions MACH_PORT_NULL,
440*e3723e1fSApple OSS Distributions 0,
441*e3723e1fSApple OSS Distributions 0);
442*e3723e1fSApple OSS Distributions
443*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "server mach_msg");
444*e3723e1fSApple OSS Distributions }
445*e3723e1fSApple OSS Distributions
446*e3723e1fSApple OSS Distributions static void
populate_kevent(struct kevent_qos_s * kev,unsigned long long port)447*e3723e1fSApple OSS Distributions populate_kevent(struct kevent_qos_s *kev, unsigned long long port)
448*e3723e1fSApple OSS Distributions {
449*e3723e1fSApple OSS Distributions memset(kev, 0, sizeof(struct kevent_qos_s));
450*e3723e1fSApple OSS Distributions kev->ident = port;
451*e3723e1fSApple OSS Distributions kev->filter = EVFILT_MACHPORT;
452*e3723e1fSApple OSS Distributions kev->flags = EV_ADD | EV_ENABLE | EV_UDATA_SPECIFIC | EV_DISPATCH | EV_VANISHED;
453*e3723e1fSApple OSS Distributions kev->fflags = (MACH_RCV_MSG | MACH_RCV_VOUCHER | MACH_RCV_LARGE | MACH_RCV_LARGE_IDENTITY |
454*e3723e1fSApple OSS Distributions MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AV) |
455*e3723e1fSApple OSS Distributions MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0));
456*e3723e1fSApple OSS Distributions kev->data = 1;
457*e3723e1fSApple OSS Distributions }
458*e3723e1fSApple OSS Distributions
459*e3723e1fSApple OSS Distributions static void
enable_kevent(uint64_t * workloop_id,unsigned long long port)460*e3723e1fSApple OSS Distributions enable_kevent(uint64_t *workloop_id, unsigned long long port)
461*e3723e1fSApple OSS Distributions {
462*e3723e1fSApple OSS Distributions struct kevent_qos_s kev;
463*e3723e1fSApple OSS Distributions int error;
464*e3723e1fSApple OSS Distributions
465*e3723e1fSApple OSS Distributions populate_kevent(&kev, port);
466*e3723e1fSApple OSS Distributions struct kevent_qos_s kev_err[] = {{ 0 }};
467*e3723e1fSApple OSS Distributions
468*e3723e1fSApple OSS Distributions error = kevent_id(*workloop_id, &kev, 1, kev_err, 1, NULL,
469*e3723e1fSApple OSS Distributions NULL, KEVENT_FLAG_WORKLOOP | KEVENT_FLAG_ERROR_EVENTS | KEVENT_FLAG_DYNAMIC_KQ_MUST_EXIST);
470*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(error, "kevent_id");
471*e3723e1fSApple OSS Distributions }
472*e3723e1fSApple OSS Distributions
473*e3723e1fSApple OSS Distributions /*
474*e3723e1fSApple OSS Distributions * WL handler which sends a msg to the client from handler.
475*e3723e1fSApple OSS Distributions */
476*e3723e1fSApple OSS Distributions static void
workloop_cb_test_sync_send_reply(uint64_t * workloop_id __unused,struct kevent_qos_s ** eventslist,int * events)477*e3723e1fSApple OSS Distributions workloop_cb_test_sync_send_reply(uint64_t *workloop_id __unused, struct kevent_qos_s **eventslist, int *events)
478*e3723e1fSApple OSS Distributions {
479*e3723e1fSApple OSS Distributions T_LOG("Workloop handler workloop_cb_test_sync_send_reply called");
480*e3723e1fSApple OSS Distributions
481*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
482*e3723e1fSApple OSS Distributions
483*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT(*events, 1, "events received");
484*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT((*eventslist)->filter, EVFILT_MACHPORT, "received EVFILT_MACHPORT");
485*e3723e1fSApple OSS Distributions
486*e3723e1fSApple OSS Distributions /* send reply */
487*e3723e1fSApple OSS Distributions send_reply(get_reply_port(*eventslist));
488*e3723e1fSApple OSS Distributions
489*e3723e1fSApple OSS Distributions *events = 0;
490*e3723e1fSApple OSS Distributions }
491*e3723e1fSApple OSS Distributions
492*e3723e1fSApple OSS Distributions /*
493*e3723e1fSApple OSS Distributions * WL handler which deallocates reply port.
494*e3723e1fSApple OSS Distributions */
495*e3723e1fSApple OSS Distributions static void
workloop_cb_test_sync_send_deallocate(uint64_t * workloop_id __unused,struct kevent_qos_s ** eventslist,int * events)496*e3723e1fSApple OSS Distributions workloop_cb_test_sync_send_deallocate(uint64_t *workloop_id __unused, struct kevent_qos_s **eventslist, int *events)
497*e3723e1fSApple OSS Distributions {
498*e3723e1fSApple OSS Distributions mach_port_t reply_port;
499*e3723e1fSApple OSS Distributions kern_return_t kr;
500*e3723e1fSApple OSS Distributions
501*e3723e1fSApple OSS Distributions T_LOG("Workloop handler workloop_cb_test_sync_send_deallocate called");
502*e3723e1fSApple OSS Distributions
503*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
504*e3723e1fSApple OSS Distributions
505*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT(*events, 1, "events received");
506*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT((*eventslist)->filter, EVFILT_MACHPORT, "received EVFILT_MACHPORT");
507*e3723e1fSApple OSS Distributions
508*e3723e1fSApple OSS Distributions reply_port = get_reply_port(*eventslist);
509*e3723e1fSApple OSS Distributions
510*e3723e1fSApple OSS Distributions /* deallocate port */
511*e3723e1fSApple OSS Distributions kr = mach_port_deallocate(mach_task_self(), reply_port);
512*e3723e1fSApple OSS Distributions
513*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_deallocate");
514*e3723e1fSApple OSS Distributions
515*e3723e1fSApple OSS Distributions *events = 0;
516*e3723e1fSApple OSS Distributions
517*e3723e1fSApple OSS Distributions T_LOG("Handler returning \n");
518*e3723e1fSApple OSS Distributions }
519*e3723e1fSApple OSS Distributions
520*e3723e1fSApple OSS Distributions
521*e3723e1fSApple OSS Distributions /*
522*e3723e1fSApple OSS Distributions * WL handler which sends a msg to the client before enabling the event from handler.
523*e3723e1fSApple OSS Distributions */
524*e3723e1fSApple OSS Distributions static void
workloop_cb_test_sync_send_reply_kevent(uint64_t * workloop_id,struct kevent_qos_s ** eventslist,int * events)525*e3723e1fSApple OSS Distributions workloop_cb_test_sync_send_reply_kevent(uint64_t *workloop_id, struct kevent_qos_s **eventslist, int *events)
526*e3723e1fSApple OSS Distributions {
527*e3723e1fSApple OSS Distributions T_LOG("Workloop handler workloop_cb_test_sync_send_reply_kevent called");
528*e3723e1fSApple OSS Distributions
529*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
530*e3723e1fSApple OSS Distributions
531*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT(*events, 1, "events received");
532*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT(((*eventslist)->filter), EVFILT_MACHPORT, "received EVFILT_MACHPORT");
533*e3723e1fSApple OSS Distributions
534*e3723e1fSApple OSS Distributions struct kevent_qos_s *kev = *eventslist;
535*e3723e1fSApple OSS Distributions
536*e3723e1fSApple OSS Distributions /* send reply */
537*e3723e1fSApple OSS Distributions send_reply(get_reply_port(kev));
538*e3723e1fSApple OSS Distributions
539*e3723e1fSApple OSS Distributions /* Enable the knote */
540*e3723e1fSApple OSS Distributions enable_kevent(workloop_id, kev->ident);
541*e3723e1fSApple OSS Distributions
542*e3723e1fSApple OSS Distributions *events = 0;
543*e3723e1fSApple OSS Distributions
544*e3723e1fSApple OSS Distributions T_LOG("Handler returning \n");
545*e3723e1fSApple OSS Distributions }
546*e3723e1fSApple OSS Distributions
547*e3723e1fSApple OSS Distributions /*
548*e3723e1fSApple OSS Distributions * WL handler which sends a msg to the client before enabling the event from pthread.
549*e3723e1fSApple OSS Distributions */
550*e3723e1fSApple OSS Distributions static void
workloop_cb_test_sync_send_reply_kevent_pthread(uint64_t * workloop_id __unused,struct kevent_qos_s ** eventslist,int * events)551*e3723e1fSApple OSS Distributions workloop_cb_test_sync_send_reply_kevent_pthread(uint64_t *workloop_id __unused, struct kevent_qos_s **eventslist, int *events)
552*e3723e1fSApple OSS Distributions {
553*e3723e1fSApple OSS Distributions T_LOG("Workloop handler workloop_cb_test_sync_send_reply_kevent_pthread called");
554*e3723e1fSApple OSS Distributions
555*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
556*e3723e1fSApple OSS Distributions
557*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT(*events, 1, "events received");
558*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT((*eventslist)->filter, EVFILT_MACHPORT, "received EVFILT_MACHPORT");
559*e3723e1fSApple OSS Distributions
560*e3723e1fSApple OSS Distributions struct kevent_qos_s *kev = *eventslist;
561*e3723e1fSApple OSS Distributions
562*e3723e1fSApple OSS Distributions /* send reply */
563*e3723e1fSApple OSS Distributions send_reply(get_reply_port(kev));
564*e3723e1fSApple OSS Distributions
565*e3723e1fSApple OSS Distributions populate_kevent(kev, kev->ident);
566*e3723e1fSApple OSS Distributions
567*e3723e1fSApple OSS Distributions *events = 1;
568*e3723e1fSApple OSS Distributions
569*e3723e1fSApple OSS Distributions T_LOG("Handler returning \n");
570*e3723e1fSApple OSS Distributions }
571*e3723e1fSApple OSS Distributions
572*e3723e1fSApple OSS Distributions /*
573*e3723e1fSApple OSS Distributions * WL handler which sends a msg to the client after reenabling the event.
574*e3723e1fSApple OSS Distributions */
575*e3723e1fSApple OSS Distributions static void
workloop_cb_test_sync_send_kevent_reply(uint64_t * workloop_id,struct kevent_qos_s ** eventslist,int * events)576*e3723e1fSApple OSS Distributions workloop_cb_test_sync_send_kevent_reply(uint64_t *workloop_id, struct kevent_qos_s **eventslist, int *events)
577*e3723e1fSApple OSS Distributions {
578*e3723e1fSApple OSS Distributions T_LOG("workloop handler workloop_cb_test_sync_send_kevent_reply called");
579*e3723e1fSApple OSS Distributions
580*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
581*e3723e1fSApple OSS Distributions
582*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT(*events, 1, "events received");
583*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT((*eventslist)->filter, EVFILT_MACHPORT, "received EVFILT_MACHPORT");
584*e3723e1fSApple OSS Distributions
585*e3723e1fSApple OSS Distributions struct kevent_qos_s *kev = *eventslist;
586*e3723e1fSApple OSS Distributions mach_port_t reply_port = get_reply_port(*eventslist);
587*e3723e1fSApple OSS Distributions
588*e3723e1fSApple OSS Distributions /* Enable the knote */
589*e3723e1fSApple OSS Distributions enable_kevent(workloop_id, kev->ident);
590*e3723e1fSApple OSS Distributions
591*e3723e1fSApple OSS Distributions /* send reply */
592*e3723e1fSApple OSS Distributions send_reply(reply_port);
593*e3723e1fSApple OSS Distributions
594*e3723e1fSApple OSS Distributions *events = 0;
595*e3723e1fSApple OSS Distributions
596*e3723e1fSApple OSS Distributions T_LOG("Handler returning \n");
597*e3723e1fSApple OSS Distributions }
598*e3723e1fSApple OSS Distributions
599*e3723e1fSApple OSS Distributions /*
600*e3723e1fSApple OSS Distributions * WL handler that does nothing.
601*e3723e1fSApple OSS Distributions */
602*e3723e1fSApple OSS Distributions static void
workloop_cb_test_sync_send_do_nothing(uint64_t * workloop_id __unused,struct kevent_qos_s ** eventslist,int * events)603*e3723e1fSApple OSS Distributions workloop_cb_test_sync_send_do_nothing(uint64_t *workloop_id __unused, struct kevent_qos_s **eventslist, int *events)
604*e3723e1fSApple OSS Distributions {
605*e3723e1fSApple OSS Distributions T_LOG("Workloop handler workloop_cb_test_sync_send_do_nothing called");
606*e3723e1fSApple OSS Distributions
607*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
608*e3723e1fSApple OSS Distributions
609*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT(*events, 1, "events received");
610*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT((*eventslist)->filter, EVFILT_MACHPORT, "received EVFILT_MACHPORT");
611*e3723e1fSApple OSS Distributions
612*e3723e1fSApple OSS Distributions /* do nothing */
613*e3723e1fSApple OSS Distributions
614*e3723e1fSApple OSS Distributions *events = 0;
615*e3723e1fSApple OSS Distributions
616*e3723e1fSApple OSS Distributions T_LOG("Handler returning \n");
617*e3723e1fSApple OSS Distributions }
618*e3723e1fSApple OSS Distributions
619*e3723e1fSApple OSS Distributions /*
620*e3723e1fSApple OSS Distributions * WL handler that returns the event to reenable.
621*e3723e1fSApple OSS Distributions */
622*e3723e1fSApple OSS Distributions static void
workloop_cb_test_sync_send_do_nothing_kevent_pthread(uint64_t * workloop_id __unused,struct kevent_qos_s ** eventslist,int * events)623*e3723e1fSApple OSS Distributions workloop_cb_test_sync_send_do_nothing_kevent_pthread(uint64_t *workloop_id __unused, struct kevent_qos_s **eventslist, int *events)
624*e3723e1fSApple OSS Distributions {
625*e3723e1fSApple OSS Distributions T_LOG("Workloop handler workloop_cb_test_sync_send_do_nothing_kevent_pthread called");
626*e3723e1fSApple OSS Distributions
627*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
628*e3723e1fSApple OSS Distributions
629*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT(*events, 1, "events received");
630*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT((*eventslist)->filter, EVFILT_MACHPORT, "received EVFILT_MACHPORT");
631*e3723e1fSApple OSS Distributions
632*e3723e1fSApple OSS Distributions struct kevent_qos_s *kev = *eventslist;
633*e3723e1fSApple OSS Distributions populate_kevent(kev, kev->ident);
634*e3723e1fSApple OSS Distributions
635*e3723e1fSApple OSS Distributions *events = 1;
636*e3723e1fSApple OSS Distributions
637*e3723e1fSApple OSS Distributions T_LOG("handler returning \n");
638*e3723e1fSApple OSS Distributions }
639*e3723e1fSApple OSS Distributions
640*e3723e1fSApple OSS Distributions /*
641*e3723e1fSApple OSS Distributions * WL handler that exits.
642*e3723e1fSApple OSS Distributions */
643*e3723e1fSApple OSS Distributions static void
workloop_cb_test_sync_send_do_nothing_exit(uint64_t * workloop_id __unused,struct kevent_qos_s ** eventslist,__unused int * events)644*e3723e1fSApple OSS Distributions workloop_cb_test_sync_send_do_nothing_exit(uint64_t *workloop_id __unused, struct kevent_qos_s **eventslist, __unused int *events)
645*e3723e1fSApple OSS Distributions {
646*e3723e1fSApple OSS Distributions T_LOG("workloop handler workloop_cb_test_sync_send_do_nothing_exit called");
647*e3723e1fSApple OSS Distributions
648*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
649*e3723e1fSApple OSS Distributions
650*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT(*events, 1, "events received");
651*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT((*eventslist)->filter, EVFILT_MACHPORT, "received EVFILT_MACHPORT");
652*e3723e1fSApple OSS Distributions
653*e3723e1fSApple OSS Distributions /* call exit */
654*e3723e1fSApple OSS Distributions exit(0);
655*e3723e1fSApple OSS Distributions }
656*e3723e1fSApple OSS Distributions
657*e3723e1fSApple OSS Distributions /*
658*e3723e1fSApple OSS Distributions * WL handler which:
659*e3723e1fSApple OSS Distributions * first sync sends a msg to the client and reenables kevent after
660*e3723e1fSApple OSS Distributions * second sync sends a msg and reenables kevent after.
661*e3723e1fSApple OSS Distributions */
662*e3723e1fSApple OSS Distributions static void
workloop_cb_test_sync_send_reply_kevent_reply_kevent(uint64_t * workloop_id __unused,struct kevent_qos_s ** eventslist,int * events)663*e3723e1fSApple OSS Distributions workloop_cb_test_sync_send_reply_kevent_reply_kevent(uint64_t *workloop_id __unused, struct kevent_qos_s **eventslist, int *events)
664*e3723e1fSApple OSS Distributions {
665*e3723e1fSApple OSS Distributions T_LOG("Workloop handler workloop_cb_test_sync_send_reply_kevent_reply_kevent called");
666*e3723e1fSApple OSS Distributions
667*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
668*e3723e1fSApple OSS Distributions
669*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT(*events, 1, "events received");
670*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT((*eventslist)->filter, EVFILT_MACHPORT, "received EVFILT_MACHPORT");
671*e3723e1fSApple OSS Distributions
672*e3723e1fSApple OSS Distributions struct kevent_qos_s *kev = *eventslist;
673*e3723e1fSApple OSS Distributions
674*e3723e1fSApple OSS Distributions /* send reply */
675*e3723e1fSApple OSS Distributions send_reply(get_reply_port(kev));
676*e3723e1fSApple OSS Distributions
677*e3723e1fSApple OSS Distributions populate_kevent(kev, kev->ident);
678*e3723e1fSApple OSS Distributions
679*e3723e1fSApple OSS Distributions *events = 1;
680*e3723e1fSApple OSS Distributions
681*e3723e1fSApple OSS Distributions T_LOG("Handler returning \n");
682*e3723e1fSApple OSS Distributions }
683*e3723e1fSApple OSS Distributions
684*e3723e1fSApple OSS Distributions /*
685*e3723e1fSApple OSS Distributions * WL handler which:
686*e3723e1fSApple OSS Distributions * first sync reenables kevent and after sends a msg
687*e3723e1fSApple OSS Distributions * second sync sends a msg and reenables kevent after.
688*e3723e1fSApple OSS Distributions */
689*e3723e1fSApple OSS Distributions static int workloop_cb_test_sync_send_kevent_reply_reply_kevent_handler_called = 0;
690*e3723e1fSApple OSS Distributions static void
workloop_cb_test_sync_send_kevent_reply_reply_kevent(uint64_t * workloop_id,struct kevent_qos_s ** eventslist,int * events)691*e3723e1fSApple OSS Distributions workloop_cb_test_sync_send_kevent_reply_reply_kevent(uint64_t *workloop_id, struct kevent_qos_s **eventslist, int *events)
692*e3723e1fSApple OSS Distributions {
693*e3723e1fSApple OSS Distributions T_LOG("workloop handler workloop_cb_test_sync_send_kevent_reply_reply_kevent called");
694*e3723e1fSApple OSS Distributions
695*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
696*e3723e1fSApple OSS Distributions
697*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT(*events, 1, "events received");
698*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT((*eventslist)->filter, EVFILT_MACHPORT, "received EVFILT_MACHPORT");
699*e3723e1fSApple OSS Distributions
700*e3723e1fSApple OSS Distributions struct kevent_qos_s *kev = *eventslist;
701*e3723e1fSApple OSS Distributions mach_port_t reply_port = get_reply_port(kev);
702*e3723e1fSApple OSS Distributions
703*e3723e1fSApple OSS Distributions if (workloop_cb_test_sync_send_kevent_reply_reply_kevent_handler_called == 0) {
704*e3723e1fSApple OSS Distributions workloop_cb_test_sync_send_kevent_reply_reply_kevent_handler_called = 1;
705*e3723e1fSApple OSS Distributions
706*e3723e1fSApple OSS Distributions /* Enable the knote */
707*e3723e1fSApple OSS Distributions enable_kevent(workloop_id, kev->ident);
708*e3723e1fSApple OSS Distributions
709*e3723e1fSApple OSS Distributions /* send reply */
710*e3723e1fSApple OSS Distributions send_reply(reply_port);
711*e3723e1fSApple OSS Distributions
712*e3723e1fSApple OSS Distributions *events = 0;
713*e3723e1fSApple OSS Distributions } else {
714*e3723e1fSApple OSS Distributions /* send reply */
715*e3723e1fSApple OSS Distributions send_reply(reply_port);
716*e3723e1fSApple OSS Distributions
717*e3723e1fSApple OSS Distributions /* Enable the knote */
718*e3723e1fSApple OSS Distributions enable_kevent(workloop_id, kev->ident);
719*e3723e1fSApple OSS Distributions
720*e3723e1fSApple OSS Distributions *events = 0;
721*e3723e1fSApple OSS Distributions }
722*e3723e1fSApple OSS Distributions
723*e3723e1fSApple OSS Distributions T_LOG("Handler returning \n");
724*e3723e1fSApple OSS Distributions }
725*e3723e1fSApple OSS Distributions
726*e3723e1fSApple OSS Distributions /*
727*e3723e1fSApple OSS Distributions * WL handler which:
728*e3723e1fSApple OSS Distributions * first sync reenables kevent and after sends a msg
729*e3723e1fSApple OSS Distributions * second sync reenables kevent and after sends a msg
730*e3723e1fSApple OSS Distributions */
731*e3723e1fSApple OSS Distributions static void
workloop_cb_test_sync_send_kevent_reply_kevent_reply(uint64_t * workloop_id,struct kevent_qos_s ** eventslist,int * events)732*e3723e1fSApple OSS Distributions workloop_cb_test_sync_send_kevent_reply_kevent_reply(uint64_t *workloop_id, struct kevent_qos_s **eventslist, int *events)
733*e3723e1fSApple OSS Distributions {
734*e3723e1fSApple OSS Distributions T_LOG("workloop handler workloop_cb_test_sync_send_kevent_reply_kevent_reply called");
735*e3723e1fSApple OSS Distributions
736*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
737*e3723e1fSApple OSS Distributions
738*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT(*events, 1, "events received");
739*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT((*eventslist)->filter, EVFILT_MACHPORT, "received EVFILT_MACHPORT");
740*e3723e1fSApple OSS Distributions
741*e3723e1fSApple OSS Distributions struct kevent_qos_s *kev = *eventslist;
742*e3723e1fSApple OSS Distributions mach_port_t reply_port = get_reply_port(kev);
743*e3723e1fSApple OSS Distributions
744*e3723e1fSApple OSS Distributions /* Enable the knote */
745*e3723e1fSApple OSS Distributions enable_kevent(workloop_id, kev->ident);
746*e3723e1fSApple OSS Distributions
747*e3723e1fSApple OSS Distributions /* send reply */
748*e3723e1fSApple OSS Distributions send_reply(reply_port);
749*e3723e1fSApple OSS Distributions
750*e3723e1fSApple OSS Distributions *events = 0;
751*e3723e1fSApple OSS Distributions T_LOG("Handler returning \n");
752*e3723e1fSApple OSS Distributions }
753*e3723e1fSApple OSS Distributions
754*e3723e1fSApple OSS Distributions /*
755*e3723e1fSApple OSS Distributions * WL handler which:
756*e3723e1fSApple OSS Distributions * first sync ends a msg and reenables kevent after
757*e3723e1fSApple OSS Distributions * second sync reenables kevent and sends a msg after
758*e3723e1fSApple OSS Distributions */
759*e3723e1fSApple OSS Distributions static int workloop_cb_test_sync_send_reply_kevent_kevent_reply_handler_called = 0;
760*e3723e1fSApple OSS Distributions static void
workloop_cb_test_sync_send_reply_kevent_kevent_reply(uint64_t * workloop_id,struct kevent_qos_s ** eventslist,int * events)761*e3723e1fSApple OSS Distributions workloop_cb_test_sync_send_reply_kevent_kevent_reply(uint64_t *workloop_id, struct kevent_qos_s **eventslist, int *events)
762*e3723e1fSApple OSS Distributions {
763*e3723e1fSApple OSS Distributions T_LOG("workloop handler workloop_cb_test_sync_send_reply_kevent_kevent_reply called");
764*e3723e1fSApple OSS Distributions
765*e3723e1fSApple OSS Distributions T_ASSERT_EQ(geteuid(), 0, "kevent_qos test requires root privileges to run.");
766*e3723e1fSApple OSS Distributions
767*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT(*events, 1, "events received");
768*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ_INT((*eventslist)->filter, EVFILT_MACHPORT, "received EVFILT_MACHPORT");
769*e3723e1fSApple OSS Distributions
770*e3723e1fSApple OSS Distributions struct kevent_qos_s *kev = *eventslist;
771*e3723e1fSApple OSS Distributions mach_port_t reply_port = get_reply_port(kev);
772*e3723e1fSApple OSS Distributions
773*e3723e1fSApple OSS Distributions if (workloop_cb_test_sync_send_reply_kevent_kevent_reply_handler_called == 0) {
774*e3723e1fSApple OSS Distributions workloop_cb_test_sync_send_reply_kevent_kevent_reply_handler_called = 1;
775*e3723e1fSApple OSS Distributions
776*e3723e1fSApple OSS Distributions /* send reply */
777*e3723e1fSApple OSS Distributions send_reply(reply_port);
778*e3723e1fSApple OSS Distributions
779*e3723e1fSApple OSS Distributions populate_kevent(kev, kev->ident);
780*e3723e1fSApple OSS Distributions
781*e3723e1fSApple OSS Distributions *events = 1;
782*e3723e1fSApple OSS Distributions } else {
783*e3723e1fSApple OSS Distributions /* Enable the knote */
784*e3723e1fSApple OSS Distributions enable_kevent(workloop_id, kev->ident);
785*e3723e1fSApple OSS Distributions /* send reply */
786*e3723e1fSApple OSS Distributions send_reply(reply_port);
787*e3723e1fSApple OSS Distributions
788*e3723e1fSApple OSS Distributions *events = 0;
789*e3723e1fSApple OSS Distributions }
790*e3723e1fSApple OSS Distributions
791*e3723e1fSApple OSS Distributions T_LOG("Handler returning \n");
792*e3723e1fSApple OSS Distributions }
793*e3723e1fSApple OSS Distributions #pragma mark Mach receive
794*e3723e1fSApple OSS Distributions
795*e3723e1fSApple OSS Distributions #define KEVENT_QOS_SERVICE_NAME "com.apple.xnu.test.kevent_qos"
796*e3723e1fSApple OSS Distributions
797*e3723e1fSApple OSS Distributions static mach_port_t
get_server_port(void)798*e3723e1fSApple OSS Distributions get_server_port(void)
799*e3723e1fSApple OSS Distributions {
800*e3723e1fSApple OSS Distributions mach_port_t port;
801*e3723e1fSApple OSS Distributions kern_return_t kr = bootstrap_check_in(bootstrap_port,
802*e3723e1fSApple OSS Distributions KEVENT_QOS_SERVICE_NAME, &port);
803*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "server bootstrap_check_in");
804*e3723e1fSApple OSS Distributions return port;
805*e3723e1fSApple OSS Distributions }
806*e3723e1fSApple OSS Distributions
807*e3723e1fSApple OSS Distributions static void
env_set_qos(char ** env,qos_class_t qos[],const char * qos_name[],const char * wl_function)808*e3723e1fSApple OSS Distributions env_set_qos(char **env, qos_class_t qos[], const char *qos_name[], const char *wl_function)
809*e3723e1fSApple OSS Distributions {
810*e3723e1fSApple OSS Distributions int i;
811*e3723e1fSApple OSS Distributions char *qos_str, *qos_name_str;
812*e3723e1fSApple OSS Distributions for (i = 0; i < ENV_VAR_QOS; i++) {
813*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(asprintf(&qos_str, "%s=%d", qos_env[i], qos[i]),
814*e3723e1fSApple OSS Distributions NULL);
815*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(
816*e3723e1fSApple OSS Distributions asprintf(&qos_name_str, "%s=%s", qos_name_env[i], qos_name[i]), NULL);
817*e3723e1fSApple OSS Distributions env[2 * i] = qos_str;
818*e3723e1fSApple OSS Distributions env[2 * i + 1] = qos_name_str;
819*e3723e1fSApple OSS Distributions }
820*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(asprintf(&env[2 * i], "%s=%s", wl_function_name, wl_function),
821*e3723e1fSApple OSS Distributions NULL);
822*e3723e1fSApple OSS Distributions env[2 * i + 1] = NULL;
823*e3723e1fSApple OSS Distributions }
824*e3723e1fSApple OSS Distributions
825*e3723e1fSApple OSS Distributions static void
environ_get_qos(qos_class_t qos[],const char * qos_name[],const char ** wl_function)826*e3723e1fSApple OSS Distributions environ_get_qos(qos_class_t qos[], const char *qos_name[], const char **wl_function)
827*e3723e1fSApple OSS Distributions {
828*e3723e1fSApple OSS Distributions char *qos_str;
829*e3723e1fSApple OSS Distributions char *qos_end;
830*e3723e1fSApple OSS Distributions int i;
831*e3723e1fSApple OSS Distributions
832*e3723e1fSApple OSS Distributions for (i = 0; i < ENV_VAR_QOS; i++) {
833*e3723e1fSApple OSS Distributions qos_str = getenv(qos_env[i]);
834*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_NOTNULL(qos_str, "getenv(%s)", qos_env[i]);
835*e3723e1fSApple OSS Distributions
836*e3723e1fSApple OSS Distributions unsigned long qos_l = strtoul(qos_str, &qos_end, 10);
837*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ(*qos_end, '\0', "getenv(%s) = '%s' should be an "
838*e3723e1fSApple OSS Distributions "integer", qos_env[i], qos_str);
839*e3723e1fSApple OSS Distributions
840*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_LT(qos_l, (unsigned long)100, "getenv(%s) = '%s' should "
841*e3723e1fSApple OSS Distributions "be less than 100", qos_env[i], qos_str);
842*e3723e1fSApple OSS Distributions
843*e3723e1fSApple OSS Distributions qos[i] = (qos_class_t)qos_l;
844*e3723e1fSApple OSS Distributions qos_name[i] = getenv(qos_name_env[i]);
845*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_NOTNULL(qos_name[i], "getenv(%s)", qos_name_env[i]);
846*e3723e1fSApple OSS Distributions }
847*e3723e1fSApple OSS Distributions *wl_function = getenv(wl_function_name);
848*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_NOTNULL(*wl_function, "getenv(%s)", wl_function_name);
849*e3723e1fSApple OSS Distributions }
850*e3723e1fSApple OSS Distributions
851*e3723e1fSApple OSS Distributions static inline thread_qos_t
thread_qos_from_qos_class(qos_class_t cls)852*e3723e1fSApple OSS Distributions thread_qos_from_qos_class(qos_class_t cls)
853*e3723e1fSApple OSS Distributions {
854*e3723e1fSApple OSS Distributions switch ((unsigned int)cls) {
855*e3723e1fSApple OSS Distributions case QOS_CLASS_USER_INTERACTIVE: return THREAD_QOS_USER_INTERACTIVE;
856*e3723e1fSApple OSS Distributions case QOS_CLASS_USER_INITIATED: return THREAD_QOS_USER_INITIATED;
857*e3723e1fSApple OSS Distributions case QOS_CLASS_DEFAULT: return THREAD_QOS_DEFAULT;
858*e3723e1fSApple OSS Distributions case QOS_CLASS_UTILITY: return THREAD_QOS_UTILITY;
859*e3723e1fSApple OSS Distributions case QOS_CLASS_BACKGROUND: return THREAD_QOS_BACKGROUND;
860*e3723e1fSApple OSS Distributions case QOS_CLASS_MAINTENANCE: return THREAD_QOS_MAINTENANCE;
861*e3723e1fSApple OSS Distributions default: return THREAD_QOS_UNSPECIFIED;
862*e3723e1fSApple OSS Distributions }
863*e3723e1fSApple OSS Distributions }
864*e3723e1fSApple OSS Distributions
865*e3723e1fSApple OSS Distributions static void
send(mach_port_t send_port,mach_port_t reply_port,mach_port_t msg_port,qos_class_t qos,mach_msg_option_t options)866*e3723e1fSApple OSS Distributions send(
867*e3723e1fSApple OSS Distributions mach_port_t send_port,
868*e3723e1fSApple OSS Distributions mach_port_t reply_port,
869*e3723e1fSApple OSS Distributions mach_port_t msg_port,
870*e3723e1fSApple OSS Distributions qos_class_t qos,
871*e3723e1fSApple OSS Distributions mach_msg_option_t options)
872*e3723e1fSApple OSS Distributions {
873*e3723e1fSApple OSS Distributions kern_return_t ret = 0;
874*e3723e1fSApple OSS Distributions mach_msg_priority_t priority = (uint32_t)_pthread_qos_class_encode(qos, 0, 0);
875*e3723e1fSApple OSS Distributions
876*e3723e1fSApple OSS Distributions struct test_msg send_msg = {
877*e3723e1fSApple OSS Distributions .header = {
878*e3723e1fSApple OSS Distributions .msgh_remote_port = send_port,
879*e3723e1fSApple OSS Distributions .msgh_local_port = reply_port,
880*e3723e1fSApple OSS Distributions .msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_COPY_SEND,
881*e3723e1fSApple OSS Distributions reply_port ? MACH_MSG_TYPE_MAKE_SEND_ONCE : 0, 0,
882*e3723e1fSApple OSS Distributions MACH_MSGH_BITS_COMPLEX),
883*e3723e1fSApple OSS Distributions .msgh_id = 0x100,
884*e3723e1fSApple OSS Distributions .msgh_size = sizeof(send_msg),
885*e3723e1fSApple OSS Distributions },
886*e3723e1fSApple OSS Distributions .body = {
887*e3723e1fSApple OSS Distributions .msgh_descriptor_count = 1,
888*e3723e1fSApple OSS Distributions },
889*e3723e1fSApple OSS Distributions .port_descriptor = {
890*e3723e1fSApple OSS Distributions .name = msg_port,
891*e3723e1fSApple OSS Distributions .disposition = MACH_MSG_TYPE_MOVE_RECEIVE,
892*e3723e1fSApple OSS Distributions .type = MACH_MSG_PORT_DESCRIPTOR,
893*e3723e1fSApple OSS Distributions },
894*e3723e1fSApple OSS Distributions .opts = options,
895*e3723e1fSApple OSS Distributions };
896*e3723e1fSApple OSS Distributions
897*e3723e1fSApple OSS Distributions if (msg_port == MACH_PORT_NULL) {
898*e3723e1fSApple OSS Distributions send_msg.body.msgh_descriptor_count = 0;
899*e3723e1fSApple OSS Distributions }
900*e3723e1fSApple OSS Distributions
901*e3723e1fSApple OSS Distributions send_msg.qos = priority;
902*e3723e1fSApple OSS Distributions priority = mach_msg_priority_encode(0, thread_qos_from_qos_class(qos), 0);
903*e3723e1fSApple OSS Distributions
904*e3723e1fSApple OSS Distributions mach_msg_option_t send_opts = options;
905*e3723e1fSApple OSS Distributions send_opts |= MACH_SEND_MSG | MACH_SEND_TIMEOUT | MACH_SEND_OVERRIDE;
906*e3723e1fSApple OSS Distributions
907*e3723e1fSApple OSS Distributions ret = mach_msg(&send_msg.header, send_opts, send_msg.header.msgh_size,
908*e3723e1fSApple OSS Distributions 0, MACH_PORT_NULL, 10000, priority);
909*e3723e1fSApple OSS Distributions
910*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(ret, "client mach_msg");
911*e3723e1fSApple OSS Distributions }
912*e3723e1fSApple OSS Distributions
913*e3723e1fSApple OSS Distributions static kern_return_t
receive(mach_port_t rcv_port,mach_port_t notify_port)914*e3723e1fSApple OSS Distributions receive(
915*e3723e1fSApple OSS Distributions mach_port_t rcv_port,
916*e3723e1fSApple OSS Distributions mach_port_t notify_port)
917*e3723e1fSApple OSS Distributions {
918*e3723e1fSApple OSS Distributions kern_return_t ret = 0;
919*e3723e1fSApple OSS Distributions
920*e3723e1fSApple OSS Distributions struct test_msg rcv_msg = {
921*e3723e1fSApple OSS Distributions .header = {
922*e3723e1fSApple OSS Distributions .msgh_remote_port = MACH_PORT_NULL,
923*e3723e1fSApple OSS Distributions .msgh_local_port = rcv_port,
924*e3723e1fSApple OSS Distributions .msgh_size = sizeof(rcv_msg),
925*e3723e1fSApple OSS Distributions },
926*e3723e1fSApple OSS Distributions };
927*e3723e1fSApple OSS Distributions
928*e3723e1fSApple OSS Distributions T_LOG("Client: Starting sync receive\n");
929*e3723e1fSApple OSS Distributions
930*e3723e1fSApple OSS Distributions ret = mach_msg(&(rcv_msg.header),
931*e3723e1fSApple OSS Distributions MACH_RCV_MSG |
932*e3723e1fSApple OSS Distributions MACH_RCV_TIMEOUT |
933*e3723e1fSApple OSS Distributions MACH_RCV_SYNC_WAIT,
934*e3723e1fSApple OSS Distributions 0,
935*e3723e1fSApple OSS Distributions rcv_msg.header.msgh_size,
936*e3723e1fSApple OSS Distributions rcv_port,
937*e3723e1fSApple OSS Distributions SEND_TIMEOUT_SECS * 1000,
938*e3723e1fSApple OSS Distributions notify_port);
939*e3723e1fSApple OSS Distributions
940*e3723e1fSApple OSS Distributions return ret;
941*e3723e1fSApple OSS Distributions }
942*e3723e1fSApple OSS Distributions
943*e3723e1fSApple OSS Distributions T_HELPER_DECL(qos_get_special_reply_port,
944*e3723e1fSApple OSS Distributions "Test get_special_reply_port and it's corner cases.")
945*e3723e1fSApple OSS Distributions {
946*e3723e1fSApple OSS Distributions mach_port_t special_reply_port;
947*e3723e1fSApple OSS Distributions mach_port_t new_special_reply_port;
948*e3723e1fSApple OSS Distributions
949*e3723e1fSApple OSS Distributions special_reply_port = thread_get_special_reply_port();
950*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_TRUE(MACH_PORT_VALID(special_reply_port), "get_thread_special_reply_port");
951*e3723e1fSApple OSS Distributions
952*e3723e1fSApple OSS Distributions new_special_reply_port = thread_get_special_reply_port();
953*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_TRUE(MACH_PORT_VALID(new_special_reply_port), "get_thread_special_reply_port");
954*e3723e1fSApple OSS Distributions
955*e3723e1fSApple OSS Distributions mach_port_destroy(mach_task_self(), special_reply_port);
956*e3723e1fSApple OSS Distributions mach_port_destroy(mach_task_self(), new_special_reply_port);
957*e3723e1fSApple OSS Distributions
958*e3723e1fSApple OSS Distributions new_special_reply_port = thread_get_special_reply_port();
959*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_TRUE(MACH_PORT_VALID(new_special_reply_port), "get_thread_special_reply_port");
960*e3723e1fSApple OSS Distributions
961*e3723e1fSApple OSS Distributions T_END;
962*e3723e1fSApple OSS Distributions }
963*e3723e1fSApple OSS Distributions
964*e3723e1fSApple OSS Distributions static void *
qos_client_send_to_intransit(void * arg __unused)965*e3723e1fSApple OSS Distributions qos_client_send_to_intransit(void *arg __unused)
966*e3723e1fSApple OSS Distributions {
967*e3723e1fSApple OSS Distributions mach_port_t qos_send_port;
968*e3723e1fSApple OSS Distributions mach_port_t msg_port;
969*e3723e1fSApple OSS Distributions mach_port_t special_reply_port;
970*e3723e1fSApple OSS Distributions
971*e3723e1fSApple OSS Distributions kern_return_t kr = bootstrap_look_up(bootstrap_port,
972*e3723e1fSApple OSS Distributions KEVENT_QOS_SERVICE_NAME, &qos_send_port);
973*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "client bootstrap_look_up");
974*e3723e1fSApple OSS Distributions
975*e3723e1fSApple OSS Distributions special_reply_port = thread_get_special_reply_port();
976*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_TRUE(MACH_PORT_VALID(special_reply_port), "get_thread_special_reply_port");
977*e3723e1fSApple OSS Distributions
978*e3723e1fSApple OSS Distributions /* Create a rcv right to send in a msg */
979*e3723e1fSApple OSS Distributions kr = mach_port_allocate(mach_task_self(),
980*e3723e1fSApple OSS Distributions MACH_PORT_RIGHT_RECEIVE,
981*e3723e1fSApple OSS Distributions &msg_port);
982*e3723e1fSApple OSS Distributions
983*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "client mach_port_allocate");
984*e3723e1fSApple OSS Distributions
985*e3723e1fSApple OSS Distributions kr = mach_port_insert_right(mach_task_self(),
986*e3723e1fSApple OSS Distributions msg_port,
987*e3723e1fSApple OSS Distributions msg_port,
988*e3723e1fSApple OSS Distributions MACH_MSG_TYPE_MAKE_SEND);
989*e3723e1fSApple OSS Distributions
990*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "client mach_port_insert_right");
991*e3723e1fSApple OSS Distributions
992*e3723e1fSApple OSS Distributions /* Send an empty msg on the port to fire the WL thread */
993*e3723e1fSApple OSS Distributions send(qos_send_port, MACH_PORT_NULL, MACH_PORT_NULL,
994*e3723e1fSApple OSS Distributions g_expected_qos[ENV_QOS_BEFORE_OVERRIDE], 0);
995*e3723e1fSApple OSS Distributions
996*e3723e1fSApple OSS Distributions /* Sleep 3 seconds for the server to start */
997*e3723e1fSApple OSS Distributions sleep(3);
998*e3723e1fSApple OSS Distributions
999*e3723e1fSApple OSS Distributions /* Send the message with msg port as in-transit port, this msg will not be dequeued */
1000*e3723e1fSApple OSS Distributions send(qos_send_port, MACH_PORT_NULL, msg_port,
1001*e3723e1fSApple OSS Distributions g_expected_qos[ENV_QOS_BEFORE_OVERRIDE], 0);
1002*e3723e1fSApple OSS Distributions
1003*e3723e1fSApple OSS Distributions /* Send 5 messages to msg port to make sure the port is full */
1004*e3723e1fSApple OSS Distributions for (int i = 0; i < 5; i++) {
1005*e3723e1fSApple OSS Distributions send(msg_port, MACH_PORT_NULL, MACH_PORT_NULL,
1006*e3723e1fSApple OSS Distributions g_expected_qos[ENV_QOS_BEFORE_OVERRIDE], 0);
1007*e3723e1fSApple OSS Distributions }
1008*e3723e1fSApple OSS Distributions
1009*e3723e1fSApple OSS Distributions T_LOG("Sent 5 msgs, now trying to send sync ipc message, which will block with a timeout\n");
1010*e3723e1fSApple OSS Distributions /* Send the message to the in-transit port, it should block and override the rcv's workloop */
1011*e3723e1fSApple OSS Distributions send(msg_port, special_reply_port, MACH_PORT_NULL,
1012*e3723e1fSApple OSS Distributions g_expected_qos[ENV_QOS_AFTER_OVERRIDE], 0);
1013*e3723e1fSApple OSS Distributions T_LOG("Client done sending messages, now waiting for server to end the test");
1014*e3723e1fSApple OSS Distributions
1015*e3723e1fSApple OSS Distributions T_ASSERT_FAIL("client timed out");
1016*e3723e1fSApple OSS Distributions return NULL;
1017*e3723e1fSApple OSS Distributions }
1018*e3723e1fSApple OSS Distributions
1019*e3723e1fSApple OSS Distributions T_HELPER_DECL(qos_client_send_to_intransit_with_thr_pri,
1020*e3723e1fSApple OSS Distributions "Send synchronous messages from a pri thread to an intransit port")
1021*e3723e1fSApple OSS Distributions {
1022*e3723e1fSApple OSS Distributions thread_create_at_qos(g_expected_qos[ENV_QOS_AFTER_OVERRIDE], qos_client_send_to_intransit);
1023*e3723e1fSApple OSS Distributions sleep(HELPER_TIMEOUT_SECS);
1024*e3723e1fSApple OSS Distributions }
1025*e3723e1fSApple OSS Distributions
1026*e3723e1fSApple OSS Distributions static pthread_t
thread_create_at_qos(qos_class_t qos,void * (* function)(void *))1027*e3723e1fSApple OSS Distributions thread_create_at_qos(qos_class_t qos, void * (*function)(void *))
1028*e3723e1fSApple OSS Distributions {
1029*e3723e1fSApple OSS Distributions qos_class_t qos_thread;
1030*e3723e1fSApple OSS Distributions pthread_t thread;
1031*e3723e1fSApple OSS Distributions pthread_attr_t attr;
1032*e3723e1fSApple OSS Distributions int ret;
1033*e3723e1fSApple OSS Distributions
1034*e3723e1fSApple OSS Distributions ret = setpriority(PRIO_DARWIN_ROLE, 0, PRIO_DARWIN_ROLE_UI_FOCAL);
1035*e3723e1fSApple OSS Distributions if (ret != 0) {
1036*e3723e1fSApple OSS Distributions T_LOG("set priority failed\n");
1037*e3723e1fSApple OSS Distributions }
1038*e3723e1fSApple OSS Distributions
1039*e3723e1fSApple OSS Distributions pthread_attr_init(&attr);
1040*e3723e1fSApple OSS Distributions pthread_attr_set_qos_class_np(&attr, qos, 0);
1041*e3723e1fSApple OSS Distributions pthread_create(&thread, &attr, function, NULL);
1042*e3723e1fSApple OSS Distributions
1043*e3723e1fSApple OSS Distributions T_LOG("pthread created\n");
1044*e3723e1fSApple OSS Distributions pthread_get_qos_class_np(thread, &qos_thread, NULL);
1045*e3723e1fSApple OSS Distributions T_EXPECT_EQ(qos_thread, (qos_class_t)qos, NULL);
1046*e3723e1fSApple OSS Distributions return thread;
1047*e3723e1fSApple OSS Distributions }
1048*e3723e1fSApple OSS Distributions
1049*e3723e1fSApple OSS Distributions static void *
qos_send_and_sync_rcv(void * arg __unused)1050*e3723e1fSApple OSS Distributions qos_send_and_sync_rcv(void *arg __unused)
1051*e3723e1fSApple OSS Distributions {
1052*e3723e1fSApple OSS Distributions mach_port_t qos_send_port;
1053*e3723e1fSApple OSS Distributions mach_port_t special_reply_port;
1054*e3723e1fSApple OSS Distributions
1055*e3723e1fSApple OSS Distributions T_LOG("Client: from created thread\n");
1056*e3723e1fSApple OSS Distributions T_EXPECT_EFFECTIVE_QOS_EQ(g_expected_qos[ENV_QOS_AFTER_OVERRIDE],
1057*e3723e1fSApple OSS Distributions "pthread QoS should be %s", g_expected_qos_name[ENV_QOS_AFTER_OVERRIDE]);
1058*e3723e1fSApple OSS Distributions
1059*e3723e1fSApple OSS Distributions kern_return_t kr = bootstrap_look_up(bootstrap_port,
1060*e3723e1fSApple OSS Distributions KEVENT_QOS_SERVICE_NAME, &qos_send_port);
1061*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "client bootstrap_look_up");
1062*e3723e1fSApple OSS Distributions
1063*e3723e1fSApple OSS Distributions special_reply_port = thread_get_special_reply_port();
1064*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_TRUE(MACH_PORT_VALID(special_reply_port), "get_thread_special_reply_port");
1065*e3723e1fSApple OSS Distributions
1066*e3723e1fSApple OSS Distributions /* enqueue two messages to make sure that mqueue is not empty */
1067*e3723e1fSApple OSS Distributions send(qos_send_port, MACH_PORT_NULL, MACH_PORT_NULL,
1068*e3723e1fSApple OSS Distributions g_expected_qos[ENV_QOS_QUEUE_OVERRIDE], 0);
1069*e3723e1fSApple OSS Distributions
1070*e3723e1fSApple OSS Distributions send(qos_send_port, MACH_PORT_NULL, MACH_PORT_NULL,
1071*e3723e1fSApple OSS Distributions g_expected_qos[ENV_QOS_QUEUE_OVERRIDE], 0);
1072*e3723e1fSApple OSS Distributions
1073*e3723e1fSApple OSS Distributions sleep(SEND_TIMEOUT_SECS);
1074*e3723e1fSApple OSS Distributions
1075*e3723e1fSApple OSS Distributions /* sync wait on msg port */
1076*e3723e1fSApple OSS Distributions receive(special_reply_port, qos_send_port);
1077*e3723e1fSApple OSS Distributions
1078*e3723e1fSApple OSS Distributions T_LOG("Client done doing sync rcv, now waiting for server to end the test");
1079*e3723e1fSApple OSS Distributions sleep(SEND_TIMEOUT_SECS);
1080*e3723e1fSApple OSS Distributions
1081*e3723e1fSApple OSS Distributions T_ASSERT_FAIL("client timed out");
1082*e3723e1fSApple OSS Distributions return NULL;
1083*e3723e1fSApple OSS Distributions }
1084*e3723e1fSApple OSS Distributions
1085*e3723e1fSApple OSS Distributions static void *
qos_sync_rcv(void * arg __unused)1086*e3723e1fSApple OSS Distributions qos_sync_rcv(void *arg __unused)
1087*e3723e1fSApple OSS Distributions {
1088*e3723e1fSApple OSS Distributions mach_port_t qos_send_port;
1089*e3723e1fSApple OSS Distributions mach_port_t special_reply_port;
1090*e3723e1fSApple OSS Distributions
1091*e3723e1fSApple OSS Distributions T_LOG("Client: from created thread\n");
1092*e3723e1fSApple OSS Distributions
1093*e3723e1fSApple OSS Distributions kern_return_t kr = bootstrap_look_up(bootstrap_port,
1094*e3723e1fSApple OSS Distributions KEVENT_QOS_SERVICE_NAME, &qos_send_port);
1095*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "client bootstrap_look_up");
1096*e3723e1fSApple OSS Distributions
1097*e3723e1fSApple OSS Distributions special_reply_port = thread_get_special_reply_port();
1098*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_TRUE(MACH_PORT_VALID(special_reply_port), "get_thread_special_reply_port");
1099*e3723e1fSApple OSS Distributions
1100*e3723e1fSApple OSS Distributions /* enqueue two messages to make sure that mqueue is not empty */
1101*e3723e1fSApple OSS Distributions send(qos_send_port, MACH_PORT_NULL, MACH_PORT_NULL,
1102*e3723e1fSApple OSS Distributions g_expected_qos[ENV_QOS_QUEUE_OVERRIDE], 0);
1103*e3723e1fSApple OSS Distributions
1104*e3723e1fSApple OSS Distributions sleep(RECV_TIMEOUT_SECS);
1105*e3723e1fSApple OSS Distributions
1106*e3723e1fSApple OSS Distributions /* sync wait on msg port */
1107*e3723e1fSApple OSS Distributions receive(special_reply_port, qos_send_port);
1108*e3723e1fSApple OSS Distributions
1109*e3723e1fSApple OSS Distributions T_LOG("Client done doing sync rcv, now waiting for server to end the test");
1110*e3723e1fSApple OSS Distributions sleep(SEND_TIMEOUT_SECS);
1111*e3723e1fSApple OSS Distributions
1112*e3723e1fSApple OSS Distributions T_ASSERT_FAIL("client timed out");
1113*e3723e1fSApple OSS Distributions return NULL;
1114*e3723e1fSApple OSS Distributions }
1115*e3723e1fSApple OSS Distributions
1116*e3723e1fSApple OSS Distributions static void
thread_wait_to_block(mach_port_t thread_port)1117*e3723e1fSApple OSS Distributions thread_wait_to_block(mach_port_t thread_port)
1118*e3723e1fSApple OSS Distributions {
1119*e3723e1fSApple OSS Distributions thread_extended_info_data_t extended_info;
1120*e3723e1fSApple OSS Distributions kern_return_t kr;
1121*e3723e1fSApple OSS Distributions
1122*e3723e1fSApple OSS Distributions while (1) {
1123*e3723e1fSApple OSS Distributions mach_msg_type_number_t count = THREAD_EXTENDED_INFO_COUNT;
1124*e3723e1fSApple OSS Distributions kr = thread_info(thread_port, THREAD_EXTENDED_INFO,
1125*e3723e1fSApple OSS Distributions (thread_info_t)&extended_info, &count);
1126*e3723e1fSApple OSS Distributions
1127*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "thread_info");
1128*e3723e1fSApple OSS Distributions
1129*e3723e1fSApple OSS Distributions if (extended_info.pth_run_state == TH_STATE_WAITING) {
1130*e3723e1fSApple OSS Distributions T_LOG("Target thread blocked\n");
1131*e3723e1fSApple OSS Distributions break;
1132*e3723e1fSApple OSS Distributions }
1133*e3723e1fSApple OSS Distributions thread_switch(thread_port, SWITCH_OPTION_DEPRESS, 0);
1134*e3723e1fSApple OSS Distributions }
1135*e3723e1fSApple OSS Distributions }
1136*e3723e1fSApple OSS Distributions
1137*e3723e1fSApple OSS Distributions T_HELPER_DECL(qos_client_send_sync_and_sync_rcv,
1138*e3723e1fSApple OSS Distributions "Send messages and syncronously wait for rcv")
1139*e3723e1fSApple OSS Distributions {
1140*e3723e1fSApple OSS Distributions thread_create_at_qos(g_expected_qos[ENV_QOS_AFTER_OVERRIDE], qos_send_and_sync_rcv);
1141*e3723e1fSApple OSS Distributions sleep(HELPER_TIMEOUT_SECS);
1142*e3723e1fSApple OSS Distributions }
1143*e3723e1fSApple OSS Distributions
1144*e3723e1fSApple OSS Distributions T_HELPER_DECL(qos_client_sync_rcv_qos_change,
1145*e3723e1fSApple OSS Distributions "Send messages and syncronously wait for rcv and change qos of waiting thread")
1146*e3723e1fSApple OSS Distributions {
1147*e3723e1fSApple OSS Distributions pthread_t rcv_thread;
1148*e3723e1fSApple OSS Distributions
1149*e3723e1fSApple OSS Distributions rcv_thread = thread_create_at_qos(g_expected_qos[ENV_QOS_BEFORE_OVERRIDE], qos_sync_rcv);
1150*e3723e1fSApple OSS Distributions
1151*e3723e1fSApple OSS Distributions T_LOG("Waiting for %d seconds before changing qos of rcv thread", SEND_TIMEOUT_SECS);
1152*e3723e1fSApple OSS Distributions sleep(SEND_TIMEOUT_SECS);
1153*e3723e1fSApple OSS Distributions
1154*e3723e1fSApple OSS Distributions /* Wait for the thread to block */
1155*e3723e1fSApple OSS Distributions thread_wait_to_block(pthread_mach_thread_np(rcv_thread));
1156*e3723e1fSApple OSS Distributions
1157*e3723e1fSApple OSS Distributions /* Update the rcv thread's qos */
1158*e3723e1fSApple OSS Distributions pthread_override_qos_class_start_np(rcv_thread, g_expected_qos[ENV_QOS_AFTER_OVERRIDE], 0);
1159*e3723e1fSApple OSS Distributions
1160*e3723e1fSApple OSS Distributions sleep(HELPER_TIMEOUT_SECS);
1161*e3723e1fSApple OSS Distributions }
1162*e3723e1fSApple OSS Distributions
1163*e3723e1fSApple OSS Distributions static void *
qos_client_send_sync_msg_and_test_link(void * arg)1164*e3723e1fSApple OSS Distributions qos_client_send_sync_msg_and_test_link(void *arg)
1165*e3723e1fSApple OSS Distributions {
1166*e3723e1fSApple OSS Distributions mach_port_t qos_send_port;
1167*e3723e1fSApple OSS Distributions mach_port_t special_reply_port;
1168*e3723e1fSApple OSS Distributions boolean_t in_effect = FALSE;
1169*e3723e1fSApple OSS Distributions kern_return_t kr;
1170*e3723e1fSApple OSS Distributions unsigned long expected_result = (unsigned long) arg;
1171*e3723e1fSApple OSS Distributions
1172*e3723e1fSApple OSS Distributions kr = bootstrap_look_up(bootstrap_port,
1173*e3723e1fSApple OSS Distributions KEVENT_QOS_SERVICE_NAME, &qos_send_port);
1174*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "client bootstrap_look_up");
1175*e3723e1fSApple OSS Distributions
1176*e3723e1fSApple OSS Distributions /* start monitoring sync ipc link */
1177*e3723e1fSApple OSS Distributions kr = mach_sync_ipc_link_monitoring_start(&special_reply_port);
1178*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_sync_ipc_link_monitoring_start");
1179*e3723e1fSApple OSS Distributions
1180*e3723e1fSApple OSS Distributions /* Send the message to msg port */
1181*e3723e1fSApple OSS Distributions send(qos_send_port, special_reply_port, MACH_PORT_NULL,
1182*e3723e1fSApple OSS Distributions g_expected_qos[ENV_QOS_AFTER_OVERRIDE], 0);
1183*e3723e1fSApple OSS Distributions
1184*e3723e1fSApple OSS Distributions /*
1185*e3723e1fSApple OSS Distributions * wait for the reply
1186*e3723e1fSApple OSS Distributions * some tests do not send a msg back so the receive
1187*e3723e1fSApple OSS Distributions * might fail
1188*e3723e1fSApple OSS Distributions */
1189*e3723e1fSApple OSS Distributions receive(special_reply_port, qos_send_port);
1190*e3723e1fSApple OSS Distributions
1191*e3723e1fSApple OSS Distributions /* stop monitoring link */
1192*e3723e1fSApple OSS Distributions kr = mach_sync_ipc_link_monitoring_stop(special_reply_port, &in_effect);
1193*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_sync_ipc_link_monitoring_stop");
1194*e3723e1fSApple OSS Distributions
1195*e3723e1fSApple OSS Distributions if (!in_effect) {
1196*e3723e1fSApple OSS Distributions T_LOG("Link was broken");
1197*e3723e1fSApple OSS Distributions } else {
1198*e3723e1fSApple OSS Distributions T_LOG("Link correct");
1199*e3723e1fSApple OSS Distributions }
1200*e3723e1fSApple OSS Distributions
1201*e3723e1fSApple OSS Distributions if (expected_result == 1) {
1202*e3723e1fSApple OSS Distributions T_ASSERT_TRUE(in_effect, "special reply port link after rcv");
1203*e3723e1fSApple OSS Distributions } else {
1204*e3723e1fSApple OSS Distributions T_ASSERT_FALSE(in_effect, "special reply port link after rcv");
1205*e3723e1fSApple OSS Distributions }
1206*e3723e1fSApple OSS Distributions T_END;
1207*e3723e1fSApple OSS Distributions }
1208*e3723e1fSApple OSS Distributions
1209*e3723e1fSApple OSS Distributions static void *
qos_client_send_2sync_msg_and_test_link(void * arg)1210*e3723e1fSApple OSS Distributions qos_client_send_2sync_msg_and_test_link(void *arg)
1211*e3723e1fSApple OSS Distributions {
1212*e3723e1fSApple OSS Distributions mach_port_t qos_send_port;
1213*e3723e1fSApple OSS Distributions mach_port_t special_reply_port;
1214*e3723e1fSApple OSS Distributions boolean_t in_effect = FALSE;
1215*e3723e1fSApple OSS Distributions kern_return_t kr;
1216*e3723e1fSApple OSS Distributions unsigned long expected_result = (unsigned long) arg;
1217*e3723e1fSApple OSS Distributions
1218*e3723e1fSApple OSS Distributions kr = bootstrap_look_up(bootstrap_port,
1219*e3723e1fSApple OSS Distributions KEVENT_QOS_SERVICE_NAME, &qos_send_port);
1220*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "client bootstrap_look_up");
1221*e3723e1fSApple OSS Distributions
1222*e3723e1fSApple OSS Distributions /* start monitoring sync ipc link */
1223*e3723e1fSApple OSS Distributions kr = mach_sync_ipc_link_monitoring_start(&special_reply_port);
1224*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_sync_ipc_link_monitoring_start");
1225*e3723e1fSApple OSS Distributions
1226*e3723e1fSApple OSS Distributions /* Send the first message to msg port */
1227*e3723e1fSApple OSS Distributions send(qos_send_port, special_reply_port, MACH_PORT_NULL,
1228*e3723e1fSApple OSS Distributions g_expected_qos[ENV_QOS_AFTER_OVERRIDE], 0);
1229*e3723e1fSApple OSS Distributions
1230*e3723e1fSApple OSS Distributions /* wait for the reply */
1231*e3723e1fSApple OSS Distributions kr = receive(special_reply_port, qos_send_port);
1232*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "receive");
1233*e3723e1fSApple OSS Distributions
1234*e3723e1fSApple OSS Distributions /* Send the second message to msg port */
1235*e3723e1fSApple OSS Distributions send(qos_send_port, special_reply_port, MACH_PORT_NULL,
1236*e3723e1fSApple OSS Distributions g_expected_qos[ENV_QOS_AFTER_OVERRIDE], 0);
1237*e3723e1fSApple OSS Distributions
1238*e3723e1fSApple OSS Distributions /* wait for the reply */
1239*e3723e1fSApple OSS Distributions kr = receive(special_reply_port, qos_send_port);
1240*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "receive");
1241*e3723e1fSApple OSS Distributions
1242*e3723e1fSApple OSS Distributions /* stop monitoring link */
1243*e3723e1fSApple OSS Distributions kr = mach_sync_ipc_link_monitoring_stop(special_reply_port, &in_effect);
1244*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_sync_ipc_link_monitoring_stop");
1245*e3723e1fSApple OSS Distributions
1246*e3723e1fSApple OSS Distributions if (!in_effect) {
1247*e3723e1fSApple OSS Distributions T_LOG("Link was broken");
1248*e3723e1fSApple OSS Distributions } else {
1249*e3723e1fSApple OSS Distributions T_LOG("Link correct");
1250*e3723e1fSApple OSS Distributions }
1251*e3723e1fSApple OSS Distributions
1252*e3723e1fSApple OSS Distributions if (expected_result == 1) {
1253*e3723e1fSApple OSS Distributions T_ASSERT_TRUE(in_effect, "special reply port link after rcv");
1254*e3723e1fSApple OSS Distributions } else {
1255*e3723e1fSApple OSS Distributions T_ASSERT_FALSE(in_effect, "special reply port link after rcv");
1256*e3723e1fSApple OSS Distributions }
1257*e3723e1fSApple OSS Distributions T_END;
1258*e3723e1fSApple OSS Distributions }
1259*e3723e1fSApple OSS Distributions T_HELPER_DECL(qos_client_send_sync_msg_with_link_check_correct_server,
1260*e3723e1fSApple OSS Distributions "Send sync message, wait for reply and check sync ipc link")
1261*e3723e1fSApple OSS Distributions {
1262*e3723e1fSApple OSS Distributions pthread_t thread;
1263*e3723e1fSApple OSS Distributions pthread_attr_t attr;
1264*e3723e1fSApple OSS Distributions unsigned long expected_result = 1;
1265*e3723e1fSApple OSS Distributions
1266*e3723e1fSApple OSS Distributions pthread_attr_init(&attr);
1267*e3723e1fSApple OSS Distributions pthread_create(&thread, &attr, qos_client_send_sync_msg_and_test_link, (void *)expected_result);
1268*e3723e1fSApple OSS Distributions
1269*e3723e1fSApple OSS Distributions sleep(HELPER_TIMEOUT_SECS);
1270*e3723e1fSApple OSS Distributions }
1271*e3723e1fSApple OSS Distributions
1272*e3723e1fSApple OSS Distributions T_HELPER_DECL(qos_client_send_sync_msg_with_link_check_incorrect_server,
1273*e3723e1fSApple OSS Distributions "Send sync message, wait for reply and check sync ipc link")
1274*e3723e1fSApple OSS Distributions {
1275*e3723e1fSApple OSS Distributions pthread_t thread;
1276*e3723e1fSApple OSS Distributions pthread_attr_t attr;
1277*e3723e1fSApple OSS Distributions unsigned long expected_result = 0;
1278*e3723e1fSApple OSS Distributions
1279*e3723e1fSApple OSS Distributions pthread_attr_init(&attr);
1280*e3723e1fSApple OSS Distributions pthread_create(&thread, &attr, qos_client_send_sync_msg_and_test_link, (void *)expected_result);
1281*e3723e1fSApple OSS Distributions
1282*e3723e1fSApple OSS Distributions sleep(HELPER_TIMEOUT_SECS);
1283*e3723e1fSApple OSS Distributions }
1284*e3723e1fSApple OSS Distributions
1285*e3723e1fSApple OSS Distributions T_HELPER_DECL(qos_client_send_2sync_msg_with_link_check_correct_server,
1286*e3723e1fSApple OSS Distributions "Send sync message, wait for reply and check sync ipc link")
1287*e3723e1fSApple OSS Distributions {
1288*e3723e1fSApple OSS Distributions pthread_t thread;
1289*e3723e1fSApple OSS Distributions pthread_attr_t attr;
1290*e3723e1fSApple OSS Distributions unsigned long expected_result = 1;
1291*e3723e1fSApple OSS Distributions
1292*e3723e1fSApple OSS Distributions pthread_attr_init(&attr);
1293*e3723e1fSApple OSS Distributions pthread_create(&thread, &attr, qos_client_send_2sync_msg_and_test_link, (void *)expected_result);
1294*e3723e1fSApple OSS Distributions
1295*e3723e1fSApple OSS Distributions sleep(HELPER_TIMEOUT_SECS);
1296*e3723e1fSApple OSS Distributions }
1297*e3723e1fSApple OSS Distributions
1298*e3723e1fSApple OSS Distributions T_HELPER_DECL(qos_client_send_2sync_msg_with_link_check_incorrect_server,
1299*e3723e1fSApple OSS Distributions "Send sync message, wait for reply and check sync ipc link")
1300*e3723e1fSApple OSS Distributions {
1301*e3723e1fSApple OSS Distributions pthread_t thread;
1302*e3723e1fSApple OSS Distributions pthread_attr_t attr;
1303*e3723e1fSApple OSS Distributions unsigned long expected_result = 0;
1304*e3723e1fSApple OSS Distributions
1305*e3723e1fSApple OSS Distributions pthread_attr_init(&attr);
1306*e3723e1fSApple OSS Distributions pthread_create(&thread, &attr, qos_client_send_2sync_msg_and_test_link, (void *)expected_result);
1307*e3723e1fSApple OSS Distributions
1308*e3723e1fSApple OSS Distributions sleep(HELPER_TIMEOUT_SECS);
1309*e3723e1fSApple OSS Distributions }
1310*e3723e1fSApple OSS Distributions
1311*e3723e1fSApple OSS Distributions static void *
qos_client_send_sync_msg(void * arg __unused)1312*e3723e1fSApple OSS Distributions qos_client_send_sync_msg(void *arg __unused)
1313*e3723e1fSApple OSS Distributions {
1314*e3723e1fSApple OSS Distributions mach_port_t qos_send_port;
1315*e3723e1fSApple OSS Distributions mach_port_t special_reply_port;
1316*e3723e1fSApple OSS Distributions
1317*e3723e1fSApple OSS Distributions kern_return_t kr = bootstrap_look_up(bootstrap_port,
1318*e3723e1fSApple OSS Distributions KEVENT_QOS_SERVICE_NAME, &qos_send_port);
1319*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "client bootstrap_look_up");
1320*e3723e1fSApple OSS Distributions
1321*e3723e1fSApple OSS Distributions special_reply_port = thread_get_special_reply_port();
1322*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_TRUE(MACH_PORT_VALID(special_reply_port), "get_thread_special_reply_port");
1323*e3723e1fSApple OSS Distributions
1324*e3723e1fSApple OSS Distributions /* Send the message to msg port */
1325*e3723e1fSApple OSS Distributions send(qos_send_port, special_reply_port, MACH_PORT_NULL,
1326*e3723e1fSApple OSS Distributions g_expected_qos[ENV_QOS_AFTER_OVERRIDE], 0);
1327*e3723e1fSApple OSS Distributions
1328*e3723e1fSApple OSS Distributions /* wait for the reply */
1329*e3723e1fSApple OSS Distributions receive(special_reply_port, qos_send_port);
1330*e3723e1fSApple OSS Distributions
1331*e3723e1fSApple OSS Distributions T_LOG("Client done sending messages, now waiting for server to end the test");
1332*e3723e1fSApple OSS Distributions sleep(2 * SEND_TIMEOUT_SECS);
1333*e3723e1fSApple OSS Distributions
1334*e3723e1fSApple OSS Distributions T_ASSERT_FAIL("client timed out");
1335*e3723e1fSApple OSS Distributions return NULL;
1336*e3723e1fSApple OSS Distributions }
1337*e3723e1fSApple OSS Distributions
1338*e3723e1fSApple OSS Distributions T_HELPER_DECL(qos_client_send_sync_msg_with_pri,
1339*e3723e1fSApple OSS Distributions "Send sync message and wait for reply")
1340*e3723e1fSApple OSS Distributions {
1341*e3723e1fSApple OSS Distributions thread_create_at_qos(g_expected_qos[ENV_QOS_AFTER_OVERRIDE], qos_client_send_sync_msg);
1342*e3723e1fSApple OSS Distributions sleep(HELPER_TIMEOUT_SECS);
1343*e3723e1fSApple OSS Distributions }
1344*e3723e1fSApple OSS Distributions
1345*e3723e1fSApple OSS Distributions static void *
qos_client_kernel_upcall_send_sync_msg(void * arg __unused)1346*e3723e1fSApple OSS Distributions qos_client_kernel_upcall_send_sync_msg(void *arg __unused)
1347*e3723e1fSApple OSS Distributions {
1348*e3723e1fSApple OSS Distributions mach_port_t qos_send_port;
1349*e3723e1fSApple OSS Distributions
1350*e3723e1fSApple OSS Distributions kern_return_t kr = bootstrap_look_up(bootstrap_port,
1351*e3723e1fSApple OSS Distributions KEVENT_QOS_SERVICE_NAME, &qos_send_port);
1352*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "client bootstrap_look_up");
1353*e3723e1fSApple OSS Distributions
1354*e3723e1fSApple OSS Distributions /* Call task_test_sync_upcall to perform a sync kernel upcall */
1355*e3723e1fSApple OSS Distributions kr = task_test_sync_upcall(mach_task_self(), qos_send_port);
1356*e3723e1fSApple OSS Distributions if (kr == KERN_NOT_SUPPORTED) {
1357*e3723e1fSApple OSS Distributions T_QUIET; T_SKIP("QOS Client Kernel Upcall test called on release kernel, skipping\n");
1358*e3723e1fSApple OSS Distributions }
1359*e3723e1fSApple OSS Distributions
1360*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "task_test_sync_upcall");
1361*e3723e1fSApple OSS Distributions
1362*e3723e1fSApple OSS Distributions T_LOG("Client done doing upcall, now waiting for server to end the test");
1363*e3723e1fSApple OSS Distributions sleep(2 * SEND_TIMEOUT_SECS);
1364*e3723e1fSApple OSS Distributions
1365*e3723e1fSApple OSS Distributions T_ASSERT_FAIL("client timed out");
1366*e3723e1fSApple OSS Distributions return NULL;
1367*e3723e1fSApple OSS Distributions }
1368*e3723e1fSApple OSS Distributions
1369*e3723e1fSApple OSS Distributions T_HELPER_DECL(qos_client_send_kernel_upcall_sync_msg_with_pri,
1370*e3723e1fSApple OSS Distributions "Send Kernel upcall sync message and wait for reply")
1371*e3723e1fSApple OSS Distributions {
1372*e3723e1fSApple OSS Distributions thread_create_at_qos(g_expected_qos[ENV_QOS_AFTER_OVERRIDE], qos_client_kernel_upcall_send_sync_msg);
1373*e3723e1fSApple OSS Distributions sleep(HELPER_TIMEOUT_SECS);
1374*e3723e1fSApple OSS Distributions }
1375*e3723e1fSApple OSS Distributions
1376*e3723e1fSApple OSS Distributions static void *
qos_client_kernel_upcall_send_async_msg(void * arg __unused)1377*e3723e1fSApple OSS Distributions qos_client_kernel_upcall_send_async_msg(void *arg __unused)
1378*e3723e1fSApple OSS Distributions {
1379*e3723e1fSApple OSS Distributions mach_port_t qos_send_port;
1380*e3723e1fSApple OSS Distributions
1381*e3723e1fSApple OSS Distributions kern_return_t kr = bootstrap_look_up(bootstrap_port,
1382*e3723e1fSApple OSS Distributions KEVENT_QOS_SERVICE_NAME, &qos_send_port);
1383*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "client bootstrap_look_up");
1384*e3723e1fSApple OSS Distributions
1385*e3723e1fSApple OSS Distributions /* Call task_test_async_upcall_propagation to perform an async kernel upcall */
1386*e3723e1fSApple OSS Distributions kr = task_test_async_upcall_propagation(mach_task_self(), qos_send_port, THREAD_QOS_UTILITY, USR_THROTTLE_LEVEL_TIER0);
1387*e3723e1fSApple OSS Distributions if (kr == KERN_NOT_SUPPORTED) {
1388*e3723e1fSApple OSS Distributions T_QUIET; T_SKIP("QOS Client Kernel Upcall test called on release kernel, skipping\n");
1389*e3723e1fSApple OSS Distributions }
1390*e3723e1fSApple OSS Distributions
1391*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "task_test_async_upcall_propagation");
1392*e3723e1fSApple OSS Distributions
1393*e3723e1fSApple OSS Distributions T_LOG("Client done doing upcall, now waiting for server to end the test");
1394*e3723e1fSApple OSS Distributions sleep(2 * SEND_TIMEOUT_SECS);
1395*e3723e1fSApple OSS Distributions
1396*e3723e1fSApple OSS Distributions T_ASSERT_FAIL("client timed out");
1397*e3723e1fSApple OSS Distributions return NULL;
1398*e3723e1fSApple OSS Distributions }
1399*e3723e1fSApple OSS Distributions
1400*e3723e1fSApple OSS Distributions T_HELPER_DECL(qos_iotier_client_send_kernel_upcall_async_msg,
1401*e3723e1fSApple OSS Distributions "Send Kernel upcall async message")
1402*e3723e1fSApple OSS Distributions {
1403*e3723e1fSApple OSS Distributions thread_create_at_qos(g_expected_qos[ENV_QOS_AFTER_OVERRIDE], qos_client_kernel_upcall_send_async_msg);
1404*e3723e1fSApple OSS Distributions sleep(HELPER_TIMEOUT_SECS);
1405*e3723e1fSApple OSS Distributions }
1406*e3723e1fSApple OSS Distributions
1407*e3723e1fSApple OSS Distributions static void *
qos_client_send_two_sync_msg_high_qos(void * arg __unused)1408*e3723e1fSApple OSS Distributions qos_client_send_two_sync_msg_high_qos(void *arg __unused)
1409*e3723e1fSApple OSS Distributions {
1410*e3723e1fSApple OSS Distributions mach_port_t qos_send_port;
1411*e3723e1fSApple OSS Distributions mach_port_t special_reply_port;
1412*e3723e1fSApple OSS Distributions
1413*e3723e1fSApple OSS Distributions kern_return_t kr = bootstrap_look_up(bootstrap_port,
1414*e3723e1fSApple OSS Distributions KEVENT_QOS_SERVICE_NAME, &qos_send_port);
1415*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "client bootstrap_look_up");
1416*e3723e1fSApple OSS Distributions
1417*e3723e1fSApple OSS Distributions special_reply_port = thread_get_special_reply_port();
1418*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_TRUE(MACH_PORT_VALID(special_reply_port), "get_thread_special_reply_port");
1419*e3723e1fSApple OSS Distributions
1420*e3723e1fSApple OSS Distributions /* Send the message to msg port */
1421*e3723e1fSApple OSS Distributions send(qos_send_port, special_reply_port, MACH_PORT_NULL,
1422*e3723e1fSApple OSS Distributions g_expected_qos[ENV_QOS_AFTER_OVERRIDE], 0);
1423*e3723e1fSApple OSS Distributions
1424*e3723e1fSApple OSS Distributions /* wait for the reply */
1425*e3723e1fSApple OSS Distributions receive(special_reply_port, qos_send_port);
1426*e3723e1fSApple OSS Distributions
1427*e3723e1fSApple OSS Distributions T_LOG("Client done sending messages, now waiting for server to end the test");
1428*e3723e1fSApple OSS Distributions sleep(SEND_TIMEOUT_SECS);
1429*e3723e1fSApple OSS Distributions
1430*e3723e1fSApple OSS Distributions T_ASSERT_FAIL("client timed out");
1431*e3723e1fSApple OSS Distributions return NULL;
1432*e3723e1fSApple OSS Distributions }
1433*e3723e1fSApple OSS Distributions
1434*e3723e1fSApple OSS Distributions static void *
qos_client_send_two_sync_msg_low_qos(void * arg __unused)1435*e3723e1fSApple OSS Distributions qos_client_send_two_sync_msg_low_qos(void *arg __unused)
1436*e3723e1fSApple OSS Distributions {
1437*e3723e1fSApple OSS Distributions mach_port_t qos_send_port;
1438*e3723e1fSApple OSS Distributions mach_port_t special_reply_port;
1439*e3723e1fSApple OSS Distributions
1440*e3723e1fSApple OSS Distributions kern_return_t kr = bootstrap_look_up(bootstrap_port,
1441*e3723e1fSApple OSS Distributions KEVENT_QOS_SERVICE_NAME, &qos_send_port);
1442*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "client bootstrap_look_up");
1443*e3723e1fSApple OSS Distributions
1444*e3723e1fSApple OSS Distributions special_reply_port = thread_get_special_reply_port();
1445*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_TRUE(MACH_PORT_VALID(special_reply_port), "get_thread_special_reply_port");
1446*e3723e1fSApple OSS Distributions
1447*e3723e1fSApple OSS Distributions /* Send the message to msg port */
1448*e3723e1fSApple OSS Distributions send(qos_send_port, special_reply_port, MACH_PORT_NULL,
1449*e3723e1fSApple OSS Distributions g_expected_qos[ENV_QOS_BEFORE_OVERRIDE], 0);
1450*e3723e1fSApple OSS Distributions
1451*e3723e1fSApple OSS Distributions /* wait for the reply */
1452*e3723e1fSApple OSS Distributions receive(special_reply_port, qos_send_port);
1453*e3723e1fSApple OSS Distributions
1454*e3723e1fSApple OSS Distributions T_LOG("Client done sending messages, now waiting for server to end the test");
1455*e3723e1fSApple OSS Distributions sleep(SEND_TIMEOUT_SECS);
1456*e3723e1fSApple OSS Distributions
1457*e3723e1fSApple OSS Distributions T_ASSERT_FAIL("client timed out");
1458*e3723e1fSApple OSS Distributions return NULL;
1459*e3723e1fSApple OSS Distributions }
1460*e3723e1fSApple OSS Distributions
1461*e3723e1fSApple OSS Distributions T_HELPER_DECL(qos_client_send_two_sync_msg_with_thr_pri,
1462*e3723e1fSApple OSS Distributions "Send messages sync msgs from 2 threads at given thread pri")
1463*e3723e1fSApple OSS Distributions {
1464*e3723e1fSApple OSS Distributions thread_create_at_qos(g_expected_qos[ENV_QOS_AFTER_OVERRIDE], qos_client_send_two_sync_msg_high_qos);
1465*e3723e1fSApple OSS Distributions sleep(INTERMITTENT_TIMEOUT_SEC);
1466*e3723e1fSApple OSS Distributions thread_create_at_qos(g_expected_qos[ENV_QOS_BEFORE_OVERRIDE], qos_client_send_two_sync_msg_low_qos);
1467*e3723e1fSApple OSS Distributions sleep(HELPER_TIMEOUT_SECS);
1468*e3723e1fSApple OSS Distributions }
1469*e3723e1fSApple OSS Distributions
1470*e3723e1fSApple OSS Distributions static mach_port_t other_thread_reply_port = MACH_PORT_NULL;
1471*e3723e1fSApple OSS Distributions static void *
qos_client_destroy_other_threads_port(void * arg __unused)1472*e3723e1fSApple OSS Distributions qos_client_destroy_other_threads_port(void *arg __unused)
1473*e3723e1fSApple OSS Distributions {
1474*e3723e1fSApple OSS Distributions T_LOG("Waiting 6 seconds before destroying other thread's reply port");
1475*e3723e1fSApple OSS Distributions sleep(SEND_TIMEOUT_SECS);
1476*e3723e1fSApple OSS Distributions
1477*e3723e1fSApple OSS Distributions T_LOG("Destroying other thread's special reply port ");
1478*e3723e1fSApple OSS Distributions mach_port_destroy(mach_task_self(), other_thread_reply_port);
1479*e3723e1fSApple OSS Distributions
1480*e3723e1fSApple OSS Distributions T_LOG("Other thread done destroying ");
1481*e3723e1fSApple OSS Distributions sleep(3 * SEND_TIMEOUT_SECS);
1482*e3723e1fSApple OSS Distributions
1483*e3723e1fSApple OSS Distributions T_ASSERT_FAIL("client timed out");
1484*e3723e1fSApple OSS Distributions return NULL;
1485*e3723e1fSApple OSS Distributions }
1486*e3723e1fSApple OSS Distributions
1487*e3723e1fSApple OSS Distributions static void *
qos_client_create_sepcial_reply_and_spawn_thread(void * arg __unused)1488*e3723e1fSApple OSS Distributions qos_client_create_sepcial_reply_and_spawn_thread(void *arg __unused)
1489*e3723e1fSApple OSS Distributions {
1490*e3723e1fSApple OSS Distributions mach_port_t qos_send_port;
1491*e3723e1fSApple OSS Distributions mach_port_t special_reply_port;
1492*e3723e1fSApple OSS Distributions
1493*e3723e1fSApple OSS Distributions kern_return_t kr = bootstrap_look_up(bootstrap_port,
1494*e3723e1fSApple OSS Distributions KEVENT_QOS_SERVICE_NAME, &qos_send_port);
1495*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "client bootstrap_look_up");
1496*e3723e1fSApple OSS Distributions
1497*e3723e1fSApple OSS Distributions special_reply_port = thread_get_special_reply_port();
1498*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_TRUE(MACH_PORT_VALID(special_reply_port), "get_thread_special_reply_port");
1499*e3723e1fSApple OSS Distributions
1500*e3723e1fSApple OSS Distributions other_thread_reply_port = special_reply_port;
1501*e3723e1fSApple OSS Distributions
1502*e3723e1fSApple OSS Distributions /* Send an async message */
1503*e3723e1fSApple OSS Distributions send(qos_send_port, MACH_PORT_NULL, MACH_PORT_NULL,
1504*e3723e1fSApple OSS Distributions g_expected_qos[ENV_QOS_BEFORE_OVERRIDE], 0);
1505*e3723e1fSApple OSS Distributions
1506*e3723e1fSApple OSS Distributions /* Send the sync ipc message */
1507*e3723e1fSApple OSS Distributions send(qos_send_port, special_reply_port, MACH_PORT_NULL,
1508*e3723e1fSApple OSS Distributions g_expected_qos[ENV_QOS_BEFORE_OVERRIDE], 0);
1509*e3723e1fSApple OSS Distributions
1510*e3723e1fSApple OSS Distributions /* Create a new thread to send the sync message on our special reply port */
1511*e3723e1fSApple OSS Distributions thread_create_at_qos(g_expected_qos[ENV_QOS_AFTER_OVERRIDE], qos_client_destroy_other_threads_port);
1512*e3723e1fSApple OSS Distributions
1513*e3723e1fSApple OSS Distributions /* Client starting to receive message */
1514*e3723e1fSApple OSS Distributions receive(special_reply_port, qos_send_port);
1515*e3723e1fSApple OSS Distributions
1516*e3723e1fSApple OSS Distributions sleep(3 * SEND_TIMEOUT_SECS);
1517*e3723e1fSApple OSS Distributions
1518*e3723e1fSApple OSS Distributions T_ASSERT_FAIL("client timed out");
1519*e3723e1fSApple OSS Distributions return NULL;
1520*e3723e1fSApple OSS Distributions }
1521*e3723e1fSApple OSS Distributions
1522*e3723e1fSApple OSS Distributions T_HELPER_DECL(qos_client_send_two_msg_and_destroy,
1523*e3723e1fSApple OSS Distributions "Send a message with another threads special reply port while that thread destroys the port")
1524*e3723e1fSApple OSS Distributions {
1525*e3723e1fSApple OSS Distributions thread_create_at_qos(g_expected_qos[ENV_QOS_AFTER_OVERRIDE], qos_client_create_sepcial_reply_and_spawn_thread);
1526*e3723e1fSApple OSS Distributions sleep(HELPER_TIMEOUT_SECS);
1527*e3723e1fSApple OSS Distributions }
1528*e3723e1fSApple OSS Distributions
1529*e3723e1fSApple OSS Distributions static mach_port_t send_complex_connection_port = MACH_PORT_NULL;
1530*e3723e1fSApple OSS Distributions
1531*e3723e1fSApple OSS Distributions static void *
qos_client_send_complex_msg_to_service_port(void * arg __unused)1532*e3723e1fSApple OSS Distributions qos_client_send_complex_msg_to_service_port(void *arg __unused)
1533*e3723e1fSApple OSS Distributions {
1534*e3723e1fSApple OSS Distributions mach_port_t svc_port, tsr_port, conn_port;
1535*e3723e1fSApple OSS Distributions kern_return_t kr;
1536*e3723e1fSApple OSS Distributions
1537*e3723e1fSApple OSS Distributions kr = bootstrap_look_up(bootstrap_port, KEVENT_QOS_SERVICE_NAME, &svc_port);
1538*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "client bootstrap_look_up");
1539*e3723e1fSApple OSS Distributions
1540*e3723e1fSApple OSS Distributions tsr_port = thread_get_special_reply_port();
1541*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_TRUE(MACH_PORT_VALID(tsr_port), "get_thread_special_reply_port");
1542*e3723e1fSApple OSS Distributions
1543*e3723e1fSApple OSS Distributions conn_port = send_complex_connection_port;
1544*e3723e1fSApple OSS Distributions
1545*e3723e1fSApple OSS Distributions T_LOG("Sending to the service port with a sync IPC");
1546*e3723e1fSApple OSS Distributions send(svc_port, tsr_port, conn_port,
1547*e3723e1fSApple OSS Distributions g_expected_qos[ENV_QOS_BEFORE_OVERRIDE],
1548*e3723e1fSApple OSS Distributions MACH_SEND_PROPAGATE_QOS);
1549*e3723e1fSApple OSS Distributions
1550*e3723e1fSApple OSS Distributions receive(tsr_port, svc_port);
1551*e3723e1fSApple OSS Distributions
1552*e3723e1fSApple OSS Distributions sleep(3 * SEND_TIMEOUT_SECS);
1553*e3723e1fSApple OSS Distributions
1554*e3723e1fSApple OSS Distributions T_ASSERT_FAIL("client timed out");
1555*e3723e1fSApple OSS Distributions return NULL;
1556*e3723e1fSApple OSS Distributions }
1557*e3723e1fSApple OSS Distributions
1558*e3723e1fSApple OSS Distributions static void *
qos_client_send_to_connection_then_service_port(void * arg __unused)1559*e3723e1fSApple OSS Distributions qos_client_send_to_connection_then_service_port(void *arg __unused)
1560*e3723e1fSApple OSS Distributions {
1561*e3723e1fSApple OSS Distributions mach_port_t tsr_port, conn_port;
1562*e3723e1fSApple OSS Distributions mach_port_options_t opts = {
1563*e3723e1fSApple OSS Distributions .flags = MPO_INSERT_SEND_RIGHT,
1564*e3723e1fSApple OSS Distributions };
1565*e3723e1fSApple OSS Distributions kern_return_t kr;
1566*e3723e1fSApple OSS Distributions
1567*e3723e1fSApple OSS Distributions kr = mach_port_construct(mach_task_self(), &opts, 0ull, &conn_port);
1568*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_port_construct");
1569*e3723e1fSApple OSS Distributions send_complex_connection_port = conn_port;
1570*e3723e1fSApple OSS Distributions
1571*e3723e1fSApple OSS Distributions tsr_port = thread_get_special_reply_port();
1572*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_TRUE(MACH_PORT_VALID(tsr_port), "get_thread_special_reply_port");
1573*e3723e1fSApple OSS Distributions
1574*e3723e1fSApple OSS Distributions T_LOG("Sending to the connection port with a sync IPC");
1575*e3723e1fSApple OSS Distributions send(conn_port, tsr_port, MACH_PORT_NULL,
1576*e3723e1fSApple OSS Distributions g_expected_qos[ENV_QOS_BEFORE_OVERRIDE],
1577*e3723e1fSApple OSS Distributions MACH_SEND_PROPAGATE_QOS);
1578*e3723e1fSApple OSS Distributions
1579*e3723e1fSApple OSS Distributions thread_create_at_qos(g_expected_qos[ENV_QOS_AFTER_OVERRIDE],
1580*e3723e1fSApple OSS Distributions qos_client_send_complex_msg_to_service_port);
1581*e3723e1fSApple OSS Distributions
1582*e3723e1fSApple OSS Distributions receive(tsr_port, conn_port);
1583*e3723e1fSApple OSS Distributions
1584*e3723e1fSApple OSS Distributions sleep(3 * SEND_TIMEOUT_SECS);
1585*e3723e1fSApple OSS Distributions
1586*e3723e1fSApple OSS Distributions T_ASSERT_FAIL("client timed out");
1587*e3723e1fSApple OSS Distributions return NULL;
1588*e3723e1fSApple OSS Distributions }
1589*e3723e1fSApple OSS Distributions
1590*e3723e1fSApple OSS Distributions T_HELPER_DECL(qos_client_send_complex_msg_with_pri,
1591*e3723e1fSApple OSS Distributions "Send a message with several ports causing links")
1592*e3723e1fSApple OSS Distributions {
1593*e3723e1fSApple OSS Distributions thread_create_at_qos(g_expected_qos[ENV_QOS_BEFORE_OVERRIDE],
1594*e3723e1fSApple OSS Distributions qos_client_send_to_connection_then_service_port);
1595*e3723e1fSApple OSS Distributions sleep(HELPER_TIMEOUT_SECS);
1596*e3723e1fSApple OSS Distributions }
1597*e3723e1fSApple OSS Distributions
1598*e3723e1fSApple OSS Distributions static void
run_client_server(const char * server_name,const char * client_name,qos_class_t qos[],const char * qos_name[],const char * wl_function)1599*e3723e1fSApple OSS Distributions run_client_server(const char *server_name, const char *client_name, qos_class_t qos[],
1600*e3723e1fSApple OSS Distributions const char *qos_name[], const char *wl_function)
1601*e3723e1fSApple OSS Distributions {
1602*e3723e1fSApple OSS Distributions char *env[2 * ENV_VAR_QOS + ENV_VAR_FUNCTION + 1];
1603*e3723e1fSApple OSS Distributions env_set_qos(env, qos, qos_name, wl_function);
1604*e3723e1fSApple OSS Distributions
1605*e3723e1fSApple OSS Distributions for (int i = 0; i < ENV_VAR_QOS; i++) {
1606*e3723e1fSApple OSS Distributions g_expected_qos[i] = qos[i];
1607*e3723e1fSApple OSS Distributions g_expected_qos_name[i] = qos_name[i];
1608*e3723e1fSApple OSS Distributions }
1609*e3723e1fSApple OSS Distributions
1610*e3723e1fSApple OSS Distributions dt_helper_t helpers[] = {
1611*e3723e1fSApple OSS Distributions dt_launchd_helper_domain("com.apple.xnu.test.kevent_qos.plist",
1612*e3723e1fSApple OSS Distributions server_name, env, LAUNCH_SYSTEM_DOMAIN),
1613*e3723e1fSApple OSS Distributions dt_fork_helper(client_name)
1614*e3723e1fSApple OSS Distributions };
1615*e3723e1fSApple OSS Distributions dt_run_helpers(helpers, 2, HELPER_TIMEOUT_SECS);
1616*e3723e1fSApple OSS Distributions }
1617*e3723e1fSApple OSS Distributions
1618*e3723e1fSApple OSS Distributions #pragma mark Mach receive - kevent_qos
1619*e3723e1fSApple OSS Distributions
1620*e3723e1fSApple OSS Distributions static void
expect_kevent_id_recv(mach_port_t port,qos_class_t qos[],const char * qos_name[],const char * wl_function)1621*e3723e1fSApple OSS Distributions expect_kevent_id_recv(mach_port_t port, qos_class_t qos[], const char *qos_name[], const char *wl_function)
1622*e3723e1fSApple OSS Distributions {
1623*e3723e1fSApple OSS Distributions int r;
1624*e3723e1fSApple OSS Distributions
1625*e3723e1fSApple OSS Distributions /* Qos expected by workloop thread */
1626*e3723e1fSApple OSS Distributions for (int i = 0; i < ENV_VAR_QOS; i++) {
1627*e3723e1fSApple OSS Distributions g_expected_qos[i] = qos[i];
1628*e3723e1fSApple OSS Distributions g_expected_qos_name[i] = qos_name[i];
1629*e3723e1fSApple OSS Distributions }
1630*e3723e1fSApple OSS Distributions
1631*e3723e1fSApple OSS Distributions if (strcmp(wl_function, "workloop_cb_test_intransit") == 0) {
1632*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1633*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1634*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_intransit, 0, 0), NULL);
1635*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_sync_send") == 0) {
1636*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1637*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1638*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_sync_send, 0, 0), NULL);
1639*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_sync_send_and_enable") == 0) {
1640*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1641*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1642*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_sync_send_and_enable, 0, 0), NULL);
1643*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_sync_send_and_enable_handoff") == 0) {
1644*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1645*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1646*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_sync_send_and_enable_handoff, 0, 0), NULL);
1647*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_send_two_sync") == 0) {
1648*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1649*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1650*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_send_two_sync, 0, 0), NULL);
1651*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_two_send_and_destroy") == 0) {
1652*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1653*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1654*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_two_send_and_destroy, 0, 0), NULL);
1655*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_sync_send_reply") == 0) {
1656*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1657*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1658*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_sync_send_reply, 0, 0), NULL);
1659*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_sync_send_deallocate") == 0) {
1660*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1661*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1662*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_sync_send_deallocate, 0, 0), NULL);
1663*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_sync_send_reply_kevent") == 0) {
1664*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1665*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1666*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_sync_send_reply_kevent, 0, 0), NULL);
1667*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_sync_send_reply_kevent_pthread") == 0) {
1668*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1669*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1670*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_sync_send_reply_kevent_pthread, 0, 0), NULL);
1671*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_sync_send_kevent_reply") == 0) {
1672*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1673*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1674*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_sync_send_kevent_reply, 0, 0), NULL);
1675*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_sync_send_do_nothing") == 0) {
1676*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1677*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1678*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_sync_send_do_nothing, 0, 0), NULL);
1679*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_sync_send_do_nothing_kevent_pthread") == 0) {
1680*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1681*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1682*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_sync_send_do_nothing_kevent_pthread, 0, 0), NULL);
1683*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_sync_send_do_nothing_exit") == 0) {
1684*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1685*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1686*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_sync_send_do_nothing_exit, 0, 0), NULL);
1687*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_sync_send_reply_kevent_reply_kevent") == 0) {
1688*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1689*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1690*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_sync_send_reply_kevent_reply_kevent, 0, 0), NULL);
1691*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_sync_send_kevent_reply_reply_kevent") == 0) {
1692*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1693*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1694*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_sync_send_kevent_reply_reply_kevent, 0, 0), NULL);
1695*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_sync_send_kevent_reply_kevent_reply") == 0) {
1696*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1697*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1698*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_sync_send_kevent_reply_kevent_reply, 0, 0), NULL);
1699*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_sync_send_reply_kevent_kevent_reply") == 0) {
1700*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1701*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1702*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_sync_send_reply_kevent_kevent_reply, 0, 0), NULL);
1703*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_kernel_sync_send") == 0) {
1704*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1705*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1706*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_kernel_sync_send, 0, 0), NULL);
1707*e3723e1fSApple OSS Distributions } else if (strcmp(wl_function, "workloop_cb_test_kernel_async_send") == 0) {
1708*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(_pthread_workqueue_init_with_workloop(
1709*e3723e1fSApple OSS Distributions worker_cb, event_cb,
1710*e3723e1fSApple OSS Distributions (pthread_workqueue_function_workloop_t)workloop_cb_test_kernel_async_send, 0, 0), NULL);
1711*e3723e1fSApple OSS Distributions } else {
1712*e3723e1fSApple OSS Distributions T_ASSERT_FAIL("no workloop function specified \n");
1713*e3723e1fSApple OSS Distributions }
1714*e3723e1fSApple OSS Distributions
1715*e3723e1fSApple OSS Distributions struct kevent_qos_s kev = {
1716*e3723e1fSApple OSS Distributions .ident = port,
1717*e3723e1fSApple OSS Distributions .filter = EVFILT_MACHPORT,
1718*e3723e1fSApple OSS Distributions .flags = EV_ADD | EV_UDATA_SPECIFIC | EV_DISPATCH | EV_VANISHED,
1719*e3723e1fSApple OSS Distributions .fflags = (MACH_RCV_MSG | MACH_RCV_VOUCHER | MACH_RCV_LARGE | MACH_RCV_LARGE_IDENTITY |
1720*e3723e1fSApple OSS Distributions MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AV) |
1721*e3723e1fSApple OSS Distributions MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)),
1722*e3723e1fSApple OSS Distributions .data = 1,
1723*e3723e1fSApple OSS Distributions .qos = (int32_t)_pthread_qos_class_encode(qos[ENV_QOS_QUEUE_OVERRIDE], 0, 0)
1724*e3723e1fSApple OSS Distributions };
1725*e3723e1fSApple OSS Distributions
1726*e3723e1fSApple OSS Distributions struct kevent_qos_s kev_err = { 0 };
1727*e3723e1fSApple OSS Distributions
1728*e3723e1fSApple OSS Distributions /* Setup workloop for mach msg rcv */
1729*e3723e1fSApple OSS Distributions r = kevent_id(25, &kev, 1, &kev_err, 1, NULL,
1730*e3723e1fSApple OSS Distributions NULL, KEVENT_FLAG_WORKLOOP | KEVENT_FLAG_ERROR_EVENTS);
1731*e3723e1fSApple OSS Distributions
1732*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(r, "kevent_id");
1733*e3723e1fSApple OSS Distributions T_QUIET; T_ASSERT_EQ(r, 0, "no errors returned from kevent_id");
1734*e3723e1fSApple OSS Distributions sleep(HELPER_TIMEOUT_SECS);
1735*e3723e1fSApple OSS Distributions }
1736*e3723e1fSApple OSS Distributions
1737*e3723e1fSApple OSS Distributions T_HELPER_DECL(server_kevent_id,
1738*e3723e1fSApple OSS Distributions "Reply with the QoS that a dispatch source event handler ran with")
1739*e3723e1fSApple OSS Distributions {
1740*e3723e1fSApple OSS Distributions qos_class_t qos[ENV_VAR_QOS];
1741*e3723e1fSApple OSS Distributions const char *qos_name[ENV_VAR_QOS];
1742*e3723e1fSApple OSS Distributions const char *wl_function;
1743*e3723e1fSApple OSS Distributions environ_get_qos(qos, qos_name, &wl_function);
1744*e3723e1fSApple OSS Distributions
1745*e3723e1fSApple OSS Distributions expect_kevent_id_recv(get_server_port(), qos, qos_name, wl_function);
1746*e3723e1fSApple OSS Distributions sleep(HELPER_TIMEOUT_SECS);
1747*e3723e1fSApple OSS Distributions T_ASSERT_FAIL("should receive a message within %d seconds",
1748*e3723e1fSApple OSS Distributions RECV_TIMEOUT_SECS);
1749*e3723e1fSApple OSS Distributions }
1750*e3723e1fSApple OSS Distributions
1751*e3723e1fSApple OSS Distributions static void *
special_reply_port_thread(void * ctxt)1752*e3723e1fSApple OSS Distributions special_reply_port_thread(void *ctxt)
1753*e3723e1fSApple OSS Distributions {
1754*e3723e1fSApple OSS Distributions kern_return_t ret;
1755*e3723e1fSApple OSS Distributions mach_port_t rcv_port = *(mach_port_t *)ctxt;
1756*e3723e1fSApple OSS Distributions struct test_msg rcv_msg = {
1757*e3723e1fSApple OSS Distributions .header = {
1758*e3723e1fSApple OSS Distributions .msgh_remote_port = MACH_PORT_NULL,
1759*e3723e1fSApple OSS Distributions .msgh_local_port = rcv_port,
1760*e3723e1fSApple OSS Distributions .msgh_size = sizeof(rcv_msg),
1761*e3723e1fSApple OSS Distributions },
1762*e3723e1fSApple OSS Distributions };
1763*e3723e1fSApple OSS Distributions
1764*e3723e1fSApple OSS Distributions ret = mach_msg(&rcv_msg.header, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0,
1765*e3723e1fSApple OSS Distributions rcv_msg.header.msgh_size, rcv_port, 1000, MACH_PORT_NULL);
1766*e3723e1fSApple OSS Distributions
1767*e3723e1fSApple OSS Distributions T_EXPECT_EQ(ret, MACH_RCV_TIMED_OUT, "receive should not panic");
1768*e3723e1fSApple OSS Distributions
1769*e3723e1fSApple OSS Distributions *(mach_port_t *)ctxt = MACH_PORT_NULL;
1770*e3723e1fSApple OSS Distributions
1771*e3723e1fSApple OSS Distributions sleep(1); // give some time to pthread_exit
1772*e3723e1fSApple OSS Distributions
1773*e3723e1fSApple OSS Distributions ret = mach_msg(&rcv_msg.header, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0,
1774*e3723e1fSApple OSS Distributions rcv_msg.header.msgh_size, rcv_port, 1000, MACH_PORT_NULL);
1775*e3723e1fSApple OSS Distributions
1776*e3723e1fSApple OSS Distributions T_EXPECT_EQ(ret, MACH_RCV_TIMED_OUT, "receive should not panic");
1777*e3723e1fSApple OSS Distributions
1778*e3723e1fSApple OSS Distributions T_END;
1779*e3723e1fSApple OSS Distributions }
1780*e3723e1fSApple OSS Distributions
1781*e3723e1fSApple OSS Distributions T_DECL(special_reply_port, "basic special reply port robustness checks",
1782*e3723e1fSApple OSS Distributions T_META_RUN_CONCURRENTLY(true), T_META_TAG_VM_PREFERRED)
1783*e3723e1fSApple OSS Distributions {
1784*e3723e1fSApple OSS Distributions pthread_t thread;
1785*e3723e1fSApple OSS Distributions mach_port_t srp = thread_get_special_reply_port();
1786*e3723e1fSApple OSS Distributions
1787*e3723e1fSApple OSS Distributions pthread_create(&thread, NULL, special_reply_port_thread, &srp);
1788*e3723e1fSApple OSS Distributions
1789*e3723e1fSApple OSS Distributions while (srp) {
1790*e3723e1fSApple OSS Distributions usleep(1000);
1791*e3723e1fSApple OSS Distributions }
1792*e3723e1fSApple OSS Distributions
1793*e3723e1fSApple OSS Distributions pthread_exit(NULL);
1794*e3723e1fSApple OSS Distributions }
1795*e3723e1fSApple OSS Distributions
1796*e3723e1fSApple OSS Distributions #define TEST_QOS(server_name, client_name, name, wl_function_name, qos_bo, qos_bo_name, qos_qo, qos_qo_name, qos_ao, qos_ao_name) \
1797*e3723e1fSApple OSS Distributions T_DECL(server_kevent_id_##name, \
1798*e3723e1fSApple OSS Distributions "Event delivery at " qos_ao_name " QoS using a kevent_id", \
1799*e3723e1fSApple OSS Distributions T_META_ASROOT(YES), T_META_TAG_VM_PREFERRED) \
1800*e3723e1fSApple OSS Distributions { \
1801*e3723e1fSApple OSS Distributions qos_class_t qos_array[ENV_VAR_QOS] = {qos_bo, qos_qo, qos_ao}; \
1802*e3723e1fSApple OSS Distributions const char *qos_name_array[ENV_VAR_QOS] = {qos_bo_name, qos_qo_name, qos_ao_name}; \
1803*e3723e1fSApple OSS Distributions run_client_server(server_name, client_name, qos_array, qos_name_array, wl_function_name); \
1804*e3723e1fSApple OSS Distributions }
1805*e3723e1fSApple OSS Distributions /*
1806*e3723e1fSApple OSS Distributions * Test 1: Test special reply port SPI
1807*e3723e1fSApple OSS Distributions *
1808*e3723e1fSApple OSS Distributions * Create thread special reply port and check any subsequent calls to
1809*e3723e1fSApple OSS Distributions * the same should return MACH_PORT_NULL, unless the reply port is destroyed.
1810*e3723e1fSApple OSS Distributions */
1811*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_get_special_reply_port", special_reply_port, "workloop_cb_test_intransit",
1812*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1813*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1814*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default")
1815*e3723e1fSApple OSS Distributions
1816*e3723e1fSApple OSS Distributions /*
1817*e3723e1fSApple OSS Distributions * Test 2: Test sync ipc send to an in-transit port
1818*e3723e1fSApple OSS Distributions *
1819*e3723e1fSApple OSS Distributions * Send a sync ipc message (at IN qos) to an in-transit port enqueued in a port
1820*e3723e1fSApple OSS Distributions * attached to a workloop. Test that the servicer of the workloop gets
1821*e3723e1fSApple OSS Distributions * sync ipc override.
1822*e3723e1fSApple OSS Distributions */
1823*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_to_intransit_with_thr_pri", transit_IN, "workloop_cb_test_intransit",
1824*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1825*e3723e1fSApple OSS Distributions QOS_CLASS_MAINTENANCE, "maintenance",
1826*e3723e1fSApple OSS Distributions QOS_CLASS_USER_INITIATED, "user initiated")
1827*e3723e1fSApple OSS Distributions
1828*e3723e1fSApple OSS Distributions /*
1829*e3723e1fSApple OSS Distributions * Test 3: Test sync ipc send to an in-transit port
1830*e3723e1fSApple OSS Distributions *
1831*e3723e1fSApple OSS Distributions * Send a sync ipc message (at UI qos) to an in-transit port enqueued in a port
1832*e3723e1fSApple OSS Distributions * attached to a workloop. Test that the servicer of the workloop gets
1833*e3723e1fSApple OSS Distributions * sync ipc override.
1834*e3723e1fSApple OSS Distributions */
1835*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_to_intransit_with_thr_pri", transit_UI, "workloop_cb_test_intransit",
1836*e3723e1fSApple OSS Distributions QOS_CLASS_USER_INITIATED, "user initiated",
1837*e3723e1fSApple OSS Distributions QOS_CLASS_MAINTENANCE, "maintenance",
1838*e3723e1fSApple OSS Distributions QOS_CLASS_USER_INTERACTIVE, "user initiated with 47 basepri promotion")
1839*e3723e1fSApple OSS Distributions
1840*e3723e1fSApple OSS Distributions /*
1841*e3723e1fSApple OSS Distributions * Test 4: Test starting a sync rcv overrides the servicer
1842*e3723e1fSApple OSS Distributions *
1843*e3723e1fSApple OSS Distributions * Send an async message to a port and then start waiting on
1844*e3723e1fSApple OSS Distributions * the port in mach msg rcv (at IN qos) with sync wait and test if the
1845*e3723e1fSApple OSS Distributions * servicer of the workloop gets sync ipc override.
1846*e3723e1fSApple OSS Distributions */
1847*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_sync_and_sync_rcv", rcv_IN, "workloop_cb_test_intransit",
1848*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1849*e3723e1fSApple OSS Distributions QOS_CLASS_MAINTENANCE, "maintenance",
1850*e3723e1fSApple OSS Distributions QOS_CLASS_USER_INITIATED, "user initiated")
1851*e3723e1fSApple OSS Distributions
1852*e3723e1fSApple OSS Distributions /*
1853*e3723e1fSApple OSS Distributions * Test 5: Test starting a sync rcv overrides the servicer
1854*e3723e1fSApple OSS Distributions *
1855*e3723e1fSApple OSS Distributions * Send an async message to a port and then start waiting on
1856*e3723e1fSApple OSS Distributions * the port in mach msg rcv (at UI qos) with sync wait and test if the
1857*e3723e1fSApple OSS Distributions * servicer of the workloop gets sync ipc override.
1858*e3723e1fSApple OSS Distributions */
1859*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_sync_and_sync_rcv", rcv_UI, "workloop_cb_test_intransit",
1860*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1861*e3723e1fSApple OSS Distributions QOS_CLASS_MAINTENANCE, "maintenance",
1862*e3723e1fSApple OSS Distributions QOS_CLASS_USER_INTERACTIVE, "user interactive with 47 basepri promotion")
1863*e3723e1fSApple OSS Distributions
1864*e3723e1fSApple OSS Distributions /*
1865*e3723e1fSApple OSS Distributions * Test 6: test sending sync ipc message (at IN qos) to port will override the servicer
1866*e3723e1fSApple OSS Distributions *
1867*e3723e1fSApple OSS Distributions * Send a message with sync ipc override to a port and check if the servicer
1868*e3723e1fSApple OSS Distributions * of the workloop on other side gets sync ipc override.
1869*e3723e1fSApple OSS Distributions */
1870*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_sync_msg_with_pri", send_sync_IN, "workloop_cb_test_sync_send",
1871*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1872*e3723e1fSApple OSS Distributions QOS_CLASS_MAINTENANCE, "maintenance",
1873*e3723e1fSApple OSS Distributions QOS_CLASS_USER_INITIATED, "user initiated")
1874*e3723e1fSApple OSS Distributions
1875*e3723e1fSApple OSS Distributions /*
1876*e3723e1fSApple OSS Distributions * Test 7: test sending sync ipc message (at UI qos) to port will override the servicer
1877*e3723e1fSApple OSS Distributions *
1878*e3723e1fSApple OSS Distributions * Send a message with sync ipc override to a port and check if the servicer
1879*e3723e1fSApple OSS Distributions * of the workloop on other side gets sync ipc override.
1880*e3723e1fSApple OSS Distributions */
1881*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_sync_msg_with_pri", send_sync_UI, "workloop_cb_test_sync_send",
1882*e3723e1fSApple OSS Distributions QOS_CLASS_MAINTENANCE, "maintenance",
1883*e3723e1fSApple OSS Distributions QOS_CLASS_MAINTENANCE, "maintenance",
1884*e3723e1fSApple OSS Distributions QOS_CLASS_USER_INTERACTIVE, "user initiated with 47 basepri promotion")
1885*e3723e1fSApple OSS Distributions
1886*e3723e1fSApple OSS Distributions /*
1887*e3723e1fSApple OSS Distributions * Test 8: test enabling a knote in workloop handler will drop the sync ipc override of delivered message
1888*e3723e1fSApple OSS Distributions *
1889*e3723e1fSApple OSS Distributions * Send a sync ipc message to port and check the servicer of the workloop
1890*e3723e1fSApple OSS Distributions * on other side gets sync ipc override and once the handler enables the knote,
1891*e3723e1fSApple OSS Distributions * that sync ipc override is dropped.
1892*e3723e1fSApple OSS Distributions */
1893*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_sync_msg_with_pri", send_sync_UI_and_enable, "workloop_cb_test_sync_send_and_enable",
1894*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1895*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1896*e3723e1fSApple OSS Distributions QOS_CLASS_USER_INTERACTIVE, "user initiated with 47 basepri promotion")
1897*e3723e1fSApple OSS Distributions
1898*e3723e1fSApple OSS Distributions /*
1899*e3723e1fSApple OSS Distributions * Test 9: test returning to begin processing drops sync ipc override of delivered message
1900*e3723e1fSApple OSS Distributions *
1901*e3723e1fSApple OSS Distributions * Send a sync ipc message and check if enabling the knote clears the override of
1902*e3723e1fSApple OSS Distributions * the delivered message, but should still have the override of an enqueued message.
1903*e3723e1fSApple OSS Distributions */
1904*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_two_sync_msg_with_thr_pri", send_two_sync_UI, "workloop_cb_test_send_two_sync",
1905*e3723e1fSApple OSS Distributions QOS_CLASS_BACKGROUND, "background",
1906*e3723e1fSApple OSS Distributions QOS_CLASS_MAINTENANCE, "maintenance",
1907*e3723e1fSApple OSS Distributions QOS_CLASS_USER_INTERACTIVE, "user initiated with 47 basepri promotion")
1908*e3723e1fSApple OSS Distributions
1909*e3723e1fSApple OSS Distributions /*
1910*e3723e1fSApple OSS Distributions * Test 10: test destroying the special reply port drops the override
1911*e3723e1fSApple OSS Distributions *
1912*e3723e1fSApple OSS Distributions * Send an async messages and a sync ipc message, the workloop handler
1913*e3723e1fSApple OSS Distributions * should get a sync ipc override, now test if destroying the special
1914*e3723e1fSApple OSS Distributions * reply port drops the sync ipc override on the servicer.
1915*e3723e1fSApple OSS Distributions */
1916*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_two_msg_and_destroy", send_two_UI_and_destroy, "workloop_cb_test_two_send_and_destroy",
1917*e3723e1fSApple OSS Distributions QOS_CLASS_BACKGROUND, "background",
1918*e3723e1fSApple OSS Distributions QOS_CLASS_MAINTENANCE, "maintenance",
1919*e3723e1fSApple OSS Distributions QOS_CLASS_USER_INTERACTIVE, "user initiated with 47 basepri promotion")
1920*e3723e1fSApple OSS Distributions
1921*e3723e1fSApple OSS Distributions /*
1922*e3723e1fSApple OSS Distributions * Test 11: test sending two ports with chaining
1923*e3723e1fSApple OSS Distributions *
1924*e3723e1fSApple OSS Distributions * Send a sync IPC to a connection port, which itself is embedded in a message
1925*e3723e1fSApple OSS Distributions * sent as a sync IPC to a service port.
1926*e3723e1fSApple OSS Distributions */
1927*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_complex_msg_with_pri", send_complex_sync_UI_and_enable, "workloop_cb_test_sync_send_and_enable",
1928*e3723e1fSApple OSS Distributions QOS_CLASS_USER_INITIATED, "user initiated",
1929*e3723e1fSApple OSS Distributions QOS_CLASS_USER_INITIATED, "user initiated",
1930*e3723e1fSApple OSS Distributions QOS_CLASS_USER_INTERACTIVE, "user initiated with 47 basepri promotion")
1931*e3723e1fSApple OSS Distributions
1932*e3723e1fSApple OSS Distributions /*
1933*e3723e1fSApple OSS Distributions * Test 12: test sending two ports with chaining
1934*e3723e1fSApple OSS Distributions *
1935*e3723e1fSApple OSS Distributions * Send a sync IPC to a connection port, which itself is embedded in a message
1936*e3723e1fSApple OSS Distributions * sent as a sync IPC to a service port.
1937*e3723e1fSApple OSS Distributions */
1938*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_complex_msg_with_pri", send_complex_sync_UI_and_enable_and_handoff, "workloop_cb_test_sync_send_and_enable_handoff",
1939*e3723e1fSApple OSS Distributions QOS_CLASS_USER_INITIATED, "user initiated",
1940*e3723e1fSApple OSS Distributions QOS_CLASS_USER_INITIATED, "user initiated",
1941*e3723e1fSApple OSS Distributions QOS_CLASS_USER_INTERACTIVE, "user initiated with 47 basepri promotion")
1942*e3723e1fSApple OSS Distributions
1943*e3723e1fSApple OSS Distributions /*
1944*e3723e1fSApple OSS Distributions * Test 13: test changing qos of a thread to trigger turnstile push
1945*e3723e1fSApple OSS Distributions *
1946*e3723e1fSApple OSS Distributions * Send a sync IPC to a service port and change the qos of the blocked thread
1947*e3723e1fSApple OSS Distributions * to verify that changing qos triggers a turnstile push.
1948*e3723e1fSApple OSS Distributions */
1949*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_sync_rcv_qos_change", qos_change_to_IN, "workloop_cb_test_intransit",
1950*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1951*e3723e1fSApple OSS Distributions QOS_CLASS_MAINTENANCE, "maintenance",
1952*e3723e1fSApple OSS Distributions QOS_CLASS_USER_INITIATED, "user initiated")
1953*e3723e1fSApple OSS Distributions
1954*e3723e1fSApple OSS Distributions /*
1955*e3723e1fSApple OSS Distributions * Test 14 - 21
1956*e3723e1fSApple OSS Distributions *
1957*e3723e1fSApple OSS Distributions * Test single sync ipc link with server that breaks/preserves the link in different ways.
1958*e3723e1fSApple OSS Distributions */
1959*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_sync_msg_with_link_check_correct_server", send_sync_link_correct_server_s, "workloop_cb_test_sync_send_reply",
1960*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1961*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1962*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default")
1963*e3723e1fSApple OSS Distributions
1964*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_sync_msg_with_link_check_correct_server", send_sync_link_correct_server_d, "workloop_cb_test_sync_send_deallocate",
1965*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1966*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1967*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default")
1968*e3723e1fSApple OSS Distributions
1969*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_sync_msg_with_link_check_correct_server", send_sync_link_correct_server_sk, "workloop_cb_test_sync_send_reply_kevent",
1970*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1971*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1972*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default")
1973*e3723e1fSApple OSS Distributions
1974*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_sync_msg_with_link_check_correct_server", send_sync_link_correct_server_skp, "workloop_cb_test_sync_send_reply_kevent_pthread",
1975*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1976*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1977*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default")
1978*e3723e1fSApple OSS Distributions
1979*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_sync_msg_with_link_check_incorrect_server", send_sync_link_incorrect_server_ks, "workloop_cb_test_sync_send_kevent_reply",
1980*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1981*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1982*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default")
1983*e3723e1fSApple OSS Distributions
1984*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_sync_msg_with_link_check_correct_server", send_sync_link_correct_server_n, "workloop_cb_test_sync_send_do_nothing",
1985*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1986*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1987*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default")
1988*e3723e1fSApple OSS Distributions
1989*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_sync_msg_with_link_check_incorrect_server", send_sync_link_incorrect_server_kp, "workloop_cb_test_sync_send_do_nothing_kevent_pthread",
1990*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1991*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1992*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default")
1993*e3723e1fSApple OSS Distributions
1994*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_sync_msg_with_link_check_correct_server", send_sync_link_correct_server_e, "workloop_cb_test_sync_send_do_nothing_exit",
1995*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1996*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
1997*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default")
1998*e3723e1fSApple OSS Distributions
1999*e3723e1fSApple OSS Distributions /*
2000*e3723e1fSApple OSS Distributions * Test 22 - 25
2001*e3723e1fSApple OSS Distributions *
2002*e3723e1fSApple OSS Distributions * Test sequential sync ipc link with server that breaks/preserves the link.
2003*e3723e1fSApple OSS Distributions */
2004*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_2sync_msg_with_link_check_correct_server", send_2sync_link_correct_server_sksk, "workloop_cb_test_sync_send_reply_kevent_reply_kevent",
2005*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
2006*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
2007*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default")
2008*e3723e1fSApple OSS Distributions
2009*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_2sync_msg_with_link_check_incorrect_server", send_2sync_link_incorrect_server_kssk, "workloop_cb_test_sync_send_kevent_reply_reply_kevent",
2010*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
2011*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
2012*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default")
2013*e3723e1fSApple OSS Distributions
2014*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_2sync_msg_with_link_check_incorrect_server", send_2sync_link_incorrect_server_ksks, "workloop_cb_test_sync_send_kevent_reply_kevent_reply",
2015*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
2016*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
2017*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default")
2018*e3723e1fSApple OSS Distributions
2019*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_2sync_msg_with_link_check_incorrect_server", send_2sync_link_incorrect_server_skks, "workloop_cb_test_sync_send_reply_kevent_kevent_reply",
2020*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
2021*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default",
2022*e3723e1fSApple OSS Distributions QOS_CLASS_DEFAULT, "default")
2023*e3723e1fSApple OSS Distributions
2024*e3723e1fSApple OSS Distributions /*
2025*e3723e1fSApple OSS Distributions * Test 26: test sending sync ipc from kernel (at IN qos) to port will override the servicer
2026*e3723e1fSApple OSS Distributions *
2027*e3723e1fSApple OSS Distributions * Do a kernel upcall at IN qos to a port and check if the servicer
2028*e3723e1fSApple OSS Distributions * of the workloop on other side gets sync ipc override.
2029*e3723e1fSApple OSS Distributions */
2030*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_client_send_kernel_upcall_sync_msg_with_pri", kernel_send_sync_IN, "workloop_cb_test_kernel_sync_send",
2031*e3723e1fSApple OSS Distributions QOS_CLASS_MAINTENANCE, "maintenance",
2032*e3723e1fSApple OSS Distributions QOS_CLASS_MAINTENANCE, "maintenance",
2033*e3723e1fSApple OSS Distributions QOS_CLASS_USER_INITIATED, "user initiated")
2034*e3723e1fSApple OSS Distributions
2035*e3723e1fSApple OSS Distributions /*
2036*e3723e1fSApple OSS Distributions * Test 27: test sending async ipc from kernel (at IN qos and Tier 0 iotier) to port will override the servicer
2037*e3723e1fSApple OSS Distributions *
2038*e3723e1fSApple OSS Distributions * Do a kernel upcall at IN qos and Tier 0 iotier to a port and check if
2039*e3723e1fSApple OSS Distributions * the servicer of the workloop on the other side gets the ipc override.
2040*e3723e1fSApple OSS Distributions */
2041*e3723e1fSApple OSS Distributions TEST_QOS("server_kevent_id", "qos_iotier_client_send_kernel_upcall_async_msg", kernel_send_async_IN, "workloop_cb_test_kernel_async_send",
2042*e3723e1fSApple OSS Distributions QOS_CLASS_MAINTENANCE, "maintenance",
2043*e3723e1fSApple OSS Distributions QOS_CLASS_MAINTENANCE, "maintenance",
2044*e3723e1fSApple OSS Distributions QOS_CLASS_UTILITY, "utility")
2045