8 #include <libkern/OSAtomicQueue.h>
10 #include "darwintest_defaults.h"
12 #define WAITTIME (100 * 1000)
36 res = pthread_join(p, NULL);
42 T_DECL(join
, "pthread_join",
43 T_META_ALL_VALID_ARCHS(YES
))
51 res
= pthread_create(&p
, NULL
, thread
, param
);
52 T_ASSERT_POSIX_ZERO(res
, "pthread_create");
54 res
= pthread_join(p
, &value
);
55 T_ASSERT_POSIX_ZERO(res
, "pthread_join");
56 T_ASSERT_EQ_PTR(param
, value
, "early join value");
59 res
= pthread_create(&p
, NULL
, thread
, param
);
60 T_ASSERT_POSIX_ZERO(res
, "pthread_create");
63 res
= pthread_join(p
, &value
);
64 T_ASSERT_POSIX_ZERO(res
, "pthread_join");
65 T_ASSERT_EQ_PTR(param
, value
, "late join value");
68 res
= pthread_create_suspended_np(&p
, NULL
, thread
, param
);
69 T_ASSERT_POSIX_ZERO(res
, "pthread_create_suspended_np");
70 kr
= thread_resume(pthread_mach_thread_np(p
));
71 T_ASSERT_EQ_INT(kr
, 0, "thread_resume");
73 res
= pthread_join(p
, &value
);
74 T_ASSERT_POSIX_ZERO(res
, "pthread_join");
75 T_ASSERT_EQ_PTR(param
, value
, "suspended early join value");
78 res
= pthread_create_suspended_np(&p
, NULL
, thread
, param
);
79 T_ASSERT_POSIX_ZERO(res
, "pthread_create_suspended_np");
80 kr
= thread_resume(pthread_mach_thread_np(p
));
81 T_ASSERT_EQ_INT(kr
, 0, "thread_resume");
84 res
= pthread_join(p
, &value
);
85 T_ASSERT_POSIX_ZERO(res
, "pthread_join");
86 T_ASSERT_EQ_PTR(param
, value
, "suspended late join value");
88 // This test is supposed to test joining on the main thread. It's not
89 // clear how to express this with libdarwintest for now.
92 param = pthread_self();
93 res = pthread_create_suspended_np(&p, NULL, thread1, param);
94 T_ASSERT_POSIX_ZERO(res, "pthread_create_suspended_np");
95 res = pthread_detach(p);
96 T_ASSERT_POSIX_ZERO(res, "pthread_detach");
97 kr = thread_resume(pthread_mach_thread_np(p));
98 T_ASSERT_EQ_INT(kr, 0, "thread_resume");
104 thread_stub(__unused
void *arg
)
109 T_DECL(pthread_join_stress
, "pthread_join in a loop")
111 for (int i
= 0; i
< 1000; i
++) {
113 for (int j
= 0; j
< i%16
; j
++){
114 T_QUIET
; T_ASSERT_POSIX_SUCCESS(pthread_create(&th
[j
], NULL
, thread_stub
, NULL
), NULL
);
116 for (int j
= i%16
; j
>= 0; j
--){
117 T_QUIET
; T_ASSERT_POSIX_SUCCESS(pthread_join(th
[j
], NULL
), NULL
);
123 static pthread_mutex_t join3way_mutex
= PTHREAD_MUTEX_INITIALIZER
;
124 static pthread_cond_t join3way_cond
= PTHREAD_COND_INITIALIZER
;
125 static OSQueueHead join3way_queue
= OS_ATOMIC_QUEUE_INIT
;
127 struct join3way_item
{
129 struct join3way_item
*next
;
133 join3way_joiner(__unused
void *arg
)
135 pthread_mutex_lock(&join3way_mutex
);
137 pthread_cond_wait(&join3way_cond
, &join3way_mutex
);
138 struct join3way_item
*item
= OSAtomicDequeue(&join3way_queue
,
139 offsetof(struct join3way_item
, next
));
140 pthread_join(item
->th
, NULL
);
147 join3way_child(__unused
void *arg
)
149 struct join3way_item
*item
= malloc(sizeof(struct join3way_item
));
150 item
->th
= pthread_self();
152 OSAtomicEnqueue(&join3way_queue
, item
,
153 offsetof(struct join3way_item
, next
));
154 pthread_cond_signal(&join3way_cond
);
159 join3way_creator(__unused
void *arg
)
162 T_QUIET
; T_ASSERT_POSIX_ZERO(pthread_attr_init(&attr
), "pthread_attr_init");
163 T_ASSERT_POSIX_ZERO(pthread_attr_set_qos_class_np(&attr
,
164 QOS_CLASS_USER_INTERACTIVE
, 0), "pthread_attr_set_qos_class_np (child)");
169 T_QUIET
; T_ASSERT_POSIX_SUCCESS(pthread_create(&t
, &attr
,
170 join3way_child
, NULL
), "create thread");
172 T_ASSERT_EQ_INT(n
, 0, "created all child threads");
176 T_DECL(pthread_join_3way
, "pthread_join from non-parent with priority inversion")
178 pthread_attr_t joinerattr
;
179 T_QUIET
; T_ASSERT_POSIX_ZERO(pthread_attr_init(&joinerattr
),
180 "pthread_attr_init");
181 T_ASSERT_POSIX_ZERO(pthread_attr_set_qos_class_np(&joinerattr
,
182 QOS_CLASS_USER_INTERACTIVE
, 0), "pthread_attr_set_qos_class_np");
185 T_ASSERT_POSIX_SUCCESS(pthread_create(&joiner
, &joinerattr
, join3way_joiner
,
186 NULL
), "create joiner thread");
188 pthread_attr_t creatorattr
;
189 T_QUIET
; T_ASSERT_POSIX_ZERO(pthread_attr_init(&creatorattr
),
190 "pthread_attr_init");
191 T_ASSERT_POSIX_ZERO(pthread_attr_set_qos_class_np(&joinerattr
,
192 QOS_CLASS_BACKGROUND
, 0), "pthread_attr_set_qos_class_np (creator)");
195 T_ASSERT_POSIX_SUCCESS(pthread_create(&creator
, &creatorattr
,
196 join3way_creator
, NULL
), "create creator thread");
198 pthread_join(creator
, NULL
);