xref: /aosp_15_r20/external/mesa3d/src/c11/impl/threads_posix.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * C11 <threads.h> emulation library
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * (C) Copyright yohhoy 2012.
5*61046927SAndroid Build Coastguard Worker  * Distributed under the Boost Software License, Version 1.0.
6*61046927SAndroid Build Coastguard Worker  *
7*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person or organization
8*61046927SAndroid Build Coastguard Worker  * obtaining a copy of the software and accompanying documentation covered by
9*61046927SAndroid Build Coastguard Worker  * this license (the "Software") to use, reproduce, display, distribute,
10*61046927SAndroid Build Coastguard Worker  * execute, and transmit the Software, and to prepare [[derivative work]]s of the
11*61046927SAndroid Build Coastguard Worker  * Software, and to permit third-parties to whom the Software is furnished to
12*61046927SAndroid Build Coastguard Worker  * do so, all subject to the following:
13*61046927SAndroid Build Coastguard Worker  *
14*61046927SAndroid Build Coastguard Worker  * The copyright notices in the Software and this entire statement, including
15*61046927SAndroid Build Coastguard Worker  * the above license grant, this restriction and the following disclaimer,
16*61046927SAndroid Build Coastguard Worker  * must be included in all copies of the Software, in whole or in part, and
17*61046927SAndroid Build Coastguard Worker  * all derivative works of the Software, unless such copies or derivative
18*61046927SAndroid Build Coastguard Worker  * works are solely in the form of machine-executable object code generated by
19*61046927SAndroid Build Coastguard Worker  * a source language processor.
20*61046927SAndroid Build Coastguard Worker  *
21*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
24*61046927SAndroid Build Coastguard Worker  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
25*61046927SAndroid Build Coastguard Worker  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
26*61046927SAndroid Build Coastguard Worker  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27*61046927SAndroid Build Coastguard Worker  * DEALINGS IN THE SOFTWARE.
28*61046927SAndroid Build Coastguard Worker  */
29*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
30*61046927SAndroid Build Coastguard Worker #include <assert.h>
31*61046927SAndroid Build Coastguard Worker #include <limits.h>
32*61046927SAndroid Build Coastguard Worker #include <errno.h>
33*61046927SAndroid Build Coastguard Worker #include <unistd.h>
34*61046927SAndroid Build Coastguard Worker #include <sched.h>
35*61046927SAndroid Build Coastguard Worker #include <stdint.h> /* for intptr_t */
36*61046927SAndroid Build Coastguard Worker 
37*61046927SAndroid Build Coastguard Worker #include "c11/threads.h"
38*61046927SAndroid Build Coastguard Worker 
39*61046927SAndroid Build Coastguard Worker /*
40*61046927SAndroid Build Coastguard Worker Configuration macro:
41*61046927SAndroid Build Coastguard Worker 
42*61046927SAndroid Build Coastguard Worker   EMULATED_THREADS_USE_NATIVE_TIMEDLOCK
43*61046927SAndroid Build Coastguard Worker     Use pthread_mutex_timedlock() for `mtx_timedlock()'
44*61046927SAndroid Build Coastguard Worker     Otherwise use mtx_trylock() + *busy loop* emulation.
45*61046927SAndroid Build Coastguard Worker */
46*61046927SAndroid Build Coastguard Worker #if !defined(__CYGWIN__) && !defined(__APPLE__) && !defined(__NetBSD__)
47*61046927SAndroid Build Coastguard Worker #define EMULATED_THREADS_USE_NATIVE_TIMEDLOCK
48*61046927SAndroid Build Coastguard Worker #endif
49*61046927SAndroid Build Coastguard Worker 
50*61046927SAndroid Build Coastguard Worker /*---------------------------- types ----------------------------*/
51*61046927SAndroid Build Coastguard Worker 
52*61046927SAndroid Build Coastguard Worker /*
53*61046927SAndroid Build Coastguard Worker Implementation limits:
54*61046927SAndroid Build Coastguard Worker   - Conditionally emulation for "mutex with timeout"
55*61046927SAndroid Build Coastguard Worker     (see EMULATED_THREADS_USE_NATIVE_TIMEDLOCK macro)
56*61046927SAndroid Build Coastguard Worker */
57*61046927SAndroid Build Coastguard Worker struct impl_thrd_param {
58*61046927SAndroid Build Coastguard Worker     thrd_start_t func;
59*61046927SAndroid Build Coastguard Worker     void *arg;
60*61046927SAndroid Build Coastguard Worker };
61*61046927SAndroid Build Coastguard Worker 
62*61046927SAndroid Build Coastguard Worker static void *
impl_thrd_routine(void * p)63*61046927SAndroid Build Coastguard Worker impl_thrd_routine(void *p)
64*61046927SAndroid Build Coastguard Worker {
65*61046927SAndroid Build Coastguard Worker     struct impl_thrd_param pack = *((struct impl_thrd_param *)p);
66*61046927SAndroid Build Coastguard Worker     free(p);
67*61046927SAndroid Build Coastguard Worker     return (void*)(intptr_t)pack.func(pack.arg);
68*61046927SAndroid Build Coastguard Worker }
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker 
71*61046927SAndroid Build Coastguard Worker /*--------------- 7.25.2 Initialization functions ---------------*/
72*61046927SAndroid Build Coastguard Worker // 7.25.2.1
73*61046927SAndroid Build Coastguard Worker void
call_once(once_flag * flag,void (* func)(void))74*61046927SAndroid Build Coastguard Worker call_once(once_flag *flag, void (*func)(void))
75*61046927SAndroid Build Coastguard Worker {
76*61046927SAndroid Build Coastguard Worker     pthread_once(flag, func);
77*61046927SAndroid Build Coastguard Worker }
78*61046927SAndroid Build Coastguard Worker 
79*61046927SAndroid Build Coastguard Worker 
80*61046927SAndroid Build Coastguard Worker /*------------- 7.25.3 Condition variable functions -------------*/
81*61046927SAndroid Build Coastguard Worker // 7.25.3.1
82*61046927SAndroid Build Coastguard Worker int
cnd_broadcast(cnd_t * cond)83*61046927SAndroid Build Coastguard Worker cnd_broadcast(cnd_t *cond)
84*61046927SAndroid Build Coastguard Worker {
85*61046927SAndroid Build Coastguard Worker     assert(cond != NULL);
86*61046927SAndroid Build Coastguard Worker     return (pthread_cond_broadcast(cond) == 0) ? thrd_success : thrd_error;
87*61046927SAndroid Build Coastguard Worker }
88*61046927SAndroid Build Coastguard Worker 
89*61046927SAndroid Build Coastguard Worker // 7.25.3.2
90*61046927SAndroid Build Coastguard Worker void
cnd_destroy(cnd_t * cond)91*61046927SAndroid Build Coastguard Worker cnd_destroy(cnd_t *cond)
92*61046927SAndroid Build Coastguard Worker {
93*61046927SAndroid Build Coastguard Worker     assert(cond);
94*61046927SAndroid Build Coastguard Worker     pthread_cond_destroy(cond);
95*61046927SAndroid Build Coastguard Worker }
96*61046927SAndroid Build Coastguard Worker 
97*61046927SAndroid Build Coastguard Worker // 7.25.3.3
98*61046927SAndroid Build Coastguard Worker int
cnd_init(cnd_t * cond)99*61046927SAndroid Build Coastguard Worker cnd_init(cnd_t *cond)
100*61046927SAndroid Build Coastguard Worker {
101*61046927SAndroid Build Coastguard Worker     assert(cond != NULL);
102*61046927SAndroid Build Coastguard Worker     return (pthread_cond_init(cond, NULL) == 0) ? thrd_success : thrd_error;
103*61046927SAndroid Build Coastguard Worker }
104*61046927SAndroid Build Coastguard Worker 
105*61046927SAndroid Build Coastguard Worker // 7.25.3.4
106*61046927SAndroid Build Coastguard Worker int
cnd_signal(cnd_t * cond)107*61046927SAndroid Build Coastguard Worker cnd_signal(cnd_t *cond)
108*61046927SAndroid Build Coastguard Worker {
109*61046927SAndroid Build Coastguard Worker     assert(cond != NULL);
110*61046927SAndroid Build Coastguard Worker     return (pthread_cond_signal(cond) == 0) ? thrd_success : thrd_error;
111*61046927SAndroid Build Coastguard Worker }
112*61046927SAndroid Build Coastguard Worker 
113*61046927SAndroid Build Coastguard Worker // 7.25.3.5
114*61046927SAndroid Build Coastguard Worker int
cnd_timedwait(cnd_t * cond,mtx_t * mtx,const struct timespec * abs_time)115*61046927SAndroid Build Coastguard Worker cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *abs_time)
116*61046927SAndroid Build Coastguard Worker {
117*61046927SAndroid Build Coastguard Worker     int rt;
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker     assert(mtx != NULL);
120*61046927SAndroid Build Coastguard Worker     assert(cond != NULL);
121*61046927SAndroid Build Coastguard Worker     assert(abs_time != NULL);
122*61046927SAndroid Build Coastguard Worker 
123*61046927SAndroid Build Coastguard Worker     rt = pthread_cond_timedwait(cond, mtx, abs_time);
124*61046927SAndroid Build Coastguard Worker     if (rt == ETIMEDOUT)
125*61046927SAndroid Build Coastguard Worker         return thrd_timedout;
126*61046927SAndroid Build Coastguard Worker     return (rt == 0) ? thrd_success : thrd_error;
127*61046927SAndroid Build Coastguard Worker }
128*61046927SAndroid Build Coastguard Worker 
129*61046927SAndroid Build Coastguard Worker // 7.25.3.6
130*61046927SAndroid Build Coastguard Worker int
cnd_wait(cnd_t * cond,mtx_t * mtx)131*61046927SAndroid Build Coastguard Worker cnd_wait(cnd_t *cond, mtx_t *mtx)
132*61046927SAndroid Build Coastguard Worker {
133*61046927SAndroid Build Coastguard Worker     assert(mtx != NULL);
134*61046927SAndroid Build Coastguard Worker     assert(cond != NULL);
135*61046927SAndroid Build Coastguard Worker     return (pthread_cond_wait(cond, mtx) == 0) ? thrd_success : thrd_error;
136*61046927SAndroid Build Coastguard Worker }
137*61046927SAndroid Build Coastguard Worker 
138*61046927SAndroid Build Coastguard Worker 
139*61046927SAndroid Build Coastguard Worker /*-------------------- 7.25.4 Mutex functions --------------------*/
140*61046927SAndroid Build Coastguard Worker // 7.25.4.1
141*61046927SAndroid Build Coastguard Worker void
mtx_destroy(mtx_t * mtx)142*61046927SAndroid Build Coastguard Worker mtx_destroy(mtx_t *mtx)
143*61046927SAndroid Build Coastguard Worker {
144*61046927SAndroid Build Coastguard Worker     assert(mtx != NULL);
145*61046927SAndroid Build Coastguard Worker     pthread_mutex_destroy(mtx);
146*61046927SAndroid Build Coastguard Worker }
147*61046927SAndroid Build Coastguard Worker 
148*61046927SAndroid Build Coastguard Worker /*
149*61046927SAndroid Build Coastguard Worker  * XXX: Workaround when building with -O0 and without pthreads link.
150*61046927SAndroid Build Coastguard Worker  *
151*61046927SAndroid Build Coastguard Worker  * In such cases constant folding and dead code elimination won't be
152*61046927SAndroid Build Coastguard Worker  * available, thus the compiler will always add the pthread_mutexattr*
153*61046927SAndroid Build Coastguard Worker  * functions into the binary. As we try to link, we'll fail as the
154*61046927SAndroid Build Coastguard Worker  * symbols are unresolved.
155*61046927SAndroid Build Coastguard Worker  *
156*61046927SAndroid Build Coastguard Worker  * Ideally we'll enable the optimisations locally, yet that does not
157*61046927SAndroid Build Coastguard Worker  * seem to work.
158*61046927SAndroid Build Coastguard Worker  *
159*61046927SAndroid Build Coastguard Worker  * So the alternative workaround is to annotate the symbols as weak.
160*61046927SAndroid Build Coastguard Worker  * Thus the linker will be happy and things don't clash when building
161*61046927SAndroid Build Coastguard Worker  * with -O1 or greater.
162*61046927SAndroid Build Coastguard Worker  */
163*61046927SAndroid Build Coastguard Worker #if defined(HAVE_FUNC_ATTRIBUTE_WEAK) && !defined(__CYGWIN__)
164*61046927SAndroid Build Coastguard Worker __attribute__((weak))
165*61046927SAndroid Build Coastguard Worker int pthread_mutexattr_init(pthread_mutexattr_t *attr);
166*61046927SAndroid Build Coastguard Worker 
167*61046927SAndroid Build Coastguard Worker __attribute__((weak))
168*61046927SAndroid Build Coastguard Worker int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
169*61046927SAndroid Build Coastguard Worker 
170*61046927SAndroid Build Coastguard Worker __attribute__((weak))
171*61046927SAndroid Build Coastguard Worker int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
172*61046927SAndroid Build Coastguard Worker #endif
173*61046927SAndroid Build Coastguard Worker 
174*61046927SAndroid Build Coastguard Worker // 7.25.4.2
175*61046927SAndroid Build Coastguard Worker int
mtx_init(mtx_t * mtx,int type)176*61046927SAndroid Build Coastguard Worker mtx_init(mtx_t *mtx, int type)
177*61046927SAndroid Build Coastguard Worker {
178*61046927SAndroid Build Coastguard Worker     pthread_mutexattr_t attr;
179*61046927SAndroid Build Coastguard Worker     assert(mtx != NULL);
180*61046927SAndroid Build Coastguard Worker     if (type != mtx_plain && type != mtx_timed
181*61046927SAndroid Build Coastguard Worker       && type != (mtx_plain|mtx_recursive)
182*61046927SAndroid Build Coastguard Worker       && type != (mtx_timed|mtx_recursive))
183*61046927SAndroid Build Coastguard Worker         return thrd_error;
184*61046927SAndroid Build Coastguard Worker 
185*61046927SAndroid Build Coastguard Worker     if ((type & mtx_recursive) == 0) {
186*61046927SAndroid Build Coastguard Worker         pthread_mutex_init(mtx, NULL);
187*61046927SAndroid Build Coastguard Worker         return thrd_success;
188*61046927SAndroid Build Coastguard Worker     }
189*61046927SAndroid Build Coastguard Worker 
190*61046927SAndroid Build Coastguard Worker     pthread_mutexattr_init(&attr);
191*61046927SAndroid Build Coastguard Worker     pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
192*61046927SAndroid Build Coastguard Worker     pthread_mutex_init(mtx, &attr);
193*61046927SAndroid Build Coastguard Worker     pthread_mutexattr_destroy(&attr);
194*61046927SAndroid Build Coastguard Worker     return thrd_success;
195*61046927SAndroid Build Coastguard Worker }
196*61046927SAndroid Build Coastguard Worker 
197*61046927SAndroid Build Coastguard Worker // 7.25.4.3
198*61046927SAndroid Build Coastguard Worker int
mtx_lock(mtx_t * mtx)199*61046927SAndroid Build Coastguard Worker mtx_lock(mtx_t *mtx)
200*61046927SAndroid Build Coastguard Worker {
201*61046927SAndroid Build Coastguard Worker     assert(mtx != NULL);
202*61046927SAndroid Build Coastguard Worker     return (pthread_mutex_lock(mtx) == 0) ? thrd_success : thrd_error;
203*61046927SAndroid Build Coastguard Worker }
204*61046927SAndroid Build Coastguard Worker 
205*61046927SAndroid Build Coastguard Worker static int
threads_timespec_compare(const struct timespec * a,const struct timespec * b)206*61046927SAndroid Build Coastguard Worker threads_timespec_compare(const struct timespec *a, const struct timespec *b)
207*61046927SAndroid Build Coastguard Worker {
208*61046927SAndroid Build Coastguard Worker     if (a->tv_sec < b->tv_sec) {
209*61046927SAndroid Build Coastguard Worker         return -1;
210*61046927SAndroid Build Coastguard Worker     } else if (a->tv_sec > b->tv_sec) {
211*61046927SAndroid Build Coastguard Worker         return 1;
212*61046927SAndroid Build Coastguard Worker     } else if (a->tv_nsec < b->tv_nsec) {
213*61046927SAndroid Build Coastguard Worker         return -1;
214*61046927SAndroid Build Coastguard Worker     } else if (a->tv_nsec > b->tv_nsec) {
215*61046927SAndroid Build Coastguard Worker         return 1;
216*61046927SAndroid Build Coastguard Worker     }
217*61046927SAndroid Build Coastguard Worker     return 0;
218*61046927SAndroid Build Coastguard Worker }
219*61046927SAndroid Build Coastguard Worker 
220*61046927SAndroid Build Coastguard Worker // 7.25.4.4
221*61046927SAndroid Build Coastguard Worker int
mtx_timedlock(mtx_t * mtx,const struct timespec * ts)222*61046927SAndroid Build Coastguard Worker mtx_timedlock(mtx_t *mtx, const struct timespec *ts)
223*61046927SAndroid Build Coastguard Worker {
224*61046927SAndroid Build Coastguard Worker     assert(mtx != NULL);
225*61046927SAndroid Build Coastguard Worker     assert(ts != NULL);
226*61046927SAndroid Build Coastguard Worker 
227*61046927SAndroid Build Coastguard Worker     {
228*61046927SAndroid Build Coastguard Worker #ifdef EMULATED_THREADS_USE_NATIVE_TIMEDLOCK
229*61046927SAndroid Build Coastguard Worker     int rt;
230*61046927SAndroid Build Coastguard Worker     rt = pthread_mutex_timedlock(mtx, ts);
231*61046927SAndroid Build Coastguard Worker     if (rt == 0)
232*61046927SAndroid Build Coastguard Worker         return thrd_success;
233*61046927SAndroid Build Coastguard Worker     return (rt == ETIMEDOUT) ? thrd_timedout : thrd_error;
234*61046927SAndroid Build Coastguard Worker #else
235*61046927SAndroid Build Coastguard Worker     while (mtx_trylock(mtx) != thrd_success) {
236*61046927SAndroid Build Coastguard Worker         struct timespec now;
237*61046927SAndroid Build Coastguard Worker         if (timespec_get(&now, TIME_UTC) != TIME_UTC) {
238*61046927SAndroid Build Coastguard Worker             return thrd_error;
239*61046927SAndroid Build Coastguard Worker         }
240*61046927SAndroid Build Coastguard Worker         if (threads_timespec_compare(ts, &now) < 0)
241*61046927SAndroid Build Coastguard Worker             return thrd_timedout;
242*61046927SAndroid Build Coastguard Worker         // busy loop!
243*61046927SAndroid Build Coastguard Worker         thrd_yield();
244*61046927SAndroid Build Coastguard Worker     }
245*61046927SAndroid Build Coastguard Worker     return thrd_success;
246*61046927SAndroid Build Coastguard Worker #endif
247*61046927SAndroid Build Coastguard Worker     }
248*61046927SAndroid Build Coastguard Worker }
249*61046927SAndroid Build Coastguard Worker 
250*61046927SAndroid Build Coastguard Worker // 7.25.4.5
251*61046927SAndroid Build Coastguard Worker int
mtx_trylock(mtx_t * mtx)252*61046927SAndroid Build Coastguard Worker mtx_trylock(mtx_t *mtx)
253*61046927SAndroid Build Coastguard Worker {
254*61046927SAndroid Build Coastguard Worker     assert(mtx != NULL);
255*61046927SAndroid Build Coastguard Worker     return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy;
256*61046927SAndroid Build Coastguard Worker }
257*61046927SAndroid Build Coastguard Worker 
258*61046927SAndroid Build Coastguard Worker // 7.25.4.6
259*61046927SAndroid Build Coastguard Worker int
mtx_unlock(mtx_t * mtx)260*61046927SAndroid Build Coastguard Worker mtx_unlock(mtx_t *mtx)
261*61046927SAndroid Build Coastguard Worker {
262*61046927SAndroid Build Coastguard Worker     assert(mtx != NULL);
263*61046927SAndroid Build Coastguard Worker     return (pthread_mutex_unlock(mtx) == 0) ? thrd_success : thrd_error;
264*61046927SAndroid Build Coastguard Worker }
265*61046927SAndroid Build Coastguard Worker 
266*61046927SAndroid Build Coastguard Worker 
267*61046927SAndroid Build Coastguard Worker /*------------------- 7.25.5 Thread functions -------------------*/
268*61046927SAndroid Build Coastguard Worker // 7.25.5.1
269*61046927SAndroid Build Coastguard Worker int
thrd_create(thrd_t * thr,thrd_start_t func,void * arg)270*61046927SAndroid Build Coastguard Worker thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
271*61046927SAndroid Build Coastguard Worker {
272*61046927SAndroid Build Coastguard Worker     struct impl_thrd_param *pack;
273*61046927SAndroid Build Coastguard Worker     assert(thr != NULL);
274*61046927SAndroid Build Coastguard Worker     pack = (struct impl_thrd_param *)malloc(sizeof(struct impl_thrd_param));
275*61046927SAndroid Build Coastguard Worker     if (!pack) return thrd_nomem;
276*61046927SAndroid Build Coastguard Worker     pack->func = func;
277*61046927SAndroid Build Coastguard Worker     pack->arg = arg;
278*61046927SAndroid Build Coastguard Worker     if (pthread_create(thr, NULL, impl_thrd_routine, pack) != 0) {
279*61046927SAndroid Build Coastguard Worker         free(pack);
280*61046927SAndroid Build Coastguard Worker         return thrd_error;
281*61046927SAndroid Build Coastguard Worker     }
282*61046927SAndroid Build Coastguard Worker     return thrd_success;
283*61046927SAndroid Build Coastguard Worker }
284*61046927SAndroid Build Coastguard Worker 
285*61046927SAndroid Build Coastguard Worker // 7.25.5.2
286*61046927SAndroid Build Coastguard Worker thrd_t
thrd_current(void)287*61046927SAndroid Build Coastguard Worker thrd_current(void)
288*61046927SAndroid Build Coastguard Worker {
289*61046927SAndroid Build Coastguard Worker     return pthread_self();
290*61046927SAndroid Build Coastguard Worker }
291*61046927SAndroid Build Coastguard Worker 
292*61046927SAndroid Build Coastguard Worker // 7.25.5.3
293*61046927SAndroid Build Coastguard Worker int
thrd_detach(thrd_t thr)294*61046927SAndroid Build Coastguard Worker thrd_detach(thrd_t thr)
295*61046927SAndroid Build Coastguard Worker {
296*61046927SAndroid Build Coastguard Worker     return (pthread_detach(thr) == 0) ? thrd_success : thrd_error;
297*61046927SAndroid Build Coastguard Worker }
298*61046927SAndroid Build Coastguard Worker 
299*61046927SAndroid Build Coastguard Worker // 7.25.5.4
300*61046927SAndroid Build Coastguard Worker int
thrd_equal(thrd_t thr0,thrd_t thr1)301*61046927SAndroid Build Coastguard Worker thrd_equal(thrd_t thr0, thrd_t thr1)
302*61046927SAndroid Build Coastguard Worker {
303*61046927SAndroid Build Coastguard Worker     return pthread_equal(thr0, thr1);
304*61046927SAndroid Build Coastguard Worker }
305*61046927SAndroid Build Coastguard Worker 
306*61046927SAndroid Build Coastguard Worker // 7.25.5.5
307*61046927SAndroid Build Coastguard Worker _Noreturn
308*61046927SAndroid Build Coastguard Worker void
thrd_exit(int res)309*61046927SAndroid Build Coastguard Worker thrd_exit(int res)
310*61046927SAndroid Build Coastguard Worker {
311*61046927SAndroid Build Coastguard Worker     pthread_exit((void*)(intptr_t)res);
312*61046927SAndroid Build Coastguard Worker }
313*61046927SAndroid Build Coastguard Worker 
314*61046927SAndroid Build Coastguard Worker // 7.25.5.6
315*61046927SAndroid Build Coastguard Worker int
thrd_join(thrd_t thr,int * res)316*61046927SAndroid Build Coastguard Worker thrd_join(thrd_t thr, int *res)
317*61046927SAndroid Build Coastguard Worker {
318*61046927SAndroid Build Coastguard Worker     void *code;
319*61046927SAndroid Build Coastguard Worker     if (pthread_join(thr, &code) != 0)
320*61046927SAndroid Build Coastguard Worker         return thrd_error;
321*61046927SAndroid Build Coastguard Worker     if (res)
322*61046927SAndroid Build Coastguard Worker         *res = (int)(intptr_t)code;
323*61046927SAndroid Build Coastguard Worker     return thrd_success;
324*61046927SAndroid Build Coastguard Worker }
325*61046927SAndroid Build Coastguard Worker 
326*61046927SAndroid Build Coastguard Worker // 7.25.5.7
327*61046927SAndroid Build Coastguard Worker int
thrd_sleep(const struct timespec * time_point,struct timespec * remaining)328*61046927SAndroid Build Coastguard Worker thrd_sleep(const struct timespec *time_point, struct timespec *remaining)
329*61046927SAndroid Build Coastguard Worker {
330*61046927SAndroid Build Coastguard Worker     assert(time_point != NULL);
331*61046927SAndroid Build Coastguard Worker     return nanosleep(time_point, remaining);
332*61046927SAndroid Build Coastguard Worker }
333*61046927SAndroid Build Coastguard Worker 
334*61046927SAndroid Build Coastguard Worker // 7.25.5.8
335*61046927SAndroid Build Coastguard Worker void
thrd_yield(void)336*61046927SAndroid Build Coastguard Worker thrd_yield(void)
337*61046927SAndroid Build Coastguard Worker {
338*61046927SAndroid Build Coastguard Worker     sched_yield();
339*61046927SAndroid Build Coastguard Worker }
340*61046927SAndroid Build Coastguard Worker 
341*61046927SAndroid Build Coastguard Worker 
342*61046927SAndroid Build Coastguard Worker /*----------- 7.25.6 Thread-specific storage functions -----------*/
343*61046927SAndroid Build Coastguard Worker // 7.25.6.1
344*61046927SAndroid Build Coastguard Worker int
tss_create(tss_t * key,tss_dtor_t dtor)345*61046927SAndroid Build Coastguard Worker tss_create(tss_t *key, tss_dtor_t dtor)
346*61046927SAndroid Build Coastguard Worker {
347*61046927SAndroid Build Coastguard Worker     assert(key != NULL);
348*61046927SAndroid Build Coastguard Worker     return (pthread_key_create(key, dtor) == 0) ? thrd_success : thrd_error;
349*61046927SAndroid Build Coastguard Worker }
350*61046927SAndroid Build Coastguard Worker 
351*61046927SAndroid Build Coastguard Worker // 7.25.6.2
352*61046927SAndroid Build Coastguard Worker void
tss_delete(tss_t key)353*61046927SAndroid Build Coastguard Worker tss_delete(tss_t key)
354*61046927SAndroid Build Coastguard Worker {
355*61046927SAndroid Build Coastguard Worker     pthread_key_delete(key);
356*61046927SAndroid Build Coastguard Worker }
357*61046927SAndroid Build Coastguard Worker 
358*61046927SAndroid Build Coastguard Worker // 7.25.6.3
359*61046927SAndroid Build Coastguard Worker void *
tss_get(tss_t key)360*61046927SAndroid Build Coastguard Worker tss_get(tss_t key)
361*61046927SAndroid Build Coastguard Worker {
362*61046927SAndroid Build Coastguard Worker     return pthread_getspecific(key);
363*61046927SAndroid Build Coastguard Worker }
364*61046927SAndroid Build Coastguard Worker 
365*61046927SAndroid Build Coastguard Worker // 7.25.6.4
366*61046927SAndroid Build Coastguard Worker int
tss_set(tss_t key,void * val)367*61046927SAndroid Build Coastguard Worker tss_set(tss_t key, void *val)
368*61046927SAndroid Build Coastguard Worker {
369*61046927SAndroid Build Coastguard Worker     return (pthread_setspecific(key, val) == 0) ? thrd_success : thrd_error;
370*61046927SAndroid Build Coastguard Worker }
371