blob: ab294c171710d29c411139d47b2cb0f54e882c07 [file] [log] [blame]
Elliott Hughes42067112019-04-18 14:27:24 -07001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#pragma once
30
Elliott Hughes414dd2d2024-10-16 14:48:30 +000031#include <sys/cdefs.h>
32
Elliott Hughes42067112019-04-18 14:27:24 -070033#include <threads.h>
34
35#include <errno.h>
36#include <sched.h>
37#include <stdlib.h>
38
Logan Chien235aad12019-08-27 20:29:29 -070039#if defined(__BIONIC_THREADS_INLINE)
Elliott Hughes42067112019-04-18 14:27:24 -070040
41__BEGIN_DECLS
42
Dan Albert2237fcf2024-05-14 17:53:58 +000043static __inline int __bionic_thrd_error(int __pthread_code) {
Elliott Hughes42067112019-04-18 14:27:24 -070044 switch (__pthread_code) {
45 case 0: return 0;
46 case ENOMEM: return thrd_nomem;
47 case ETIMEDOUT: return thrd_timedout;
48 case EBUSY: return thrd_busy;
49 default: return thrd_error;
50 }
51}
52
zijunzhaoa8d42a42023-06-07 23:02:37 +000053__BIONIC_THREADS_INLINE void call_once(once_flag* _Nonnull __flag,
54 void (* _Nonnull __function)(void)) {
Elliott Hughes42067112019-04-18 14:27:24 -070055 pthread_once(__flag, __function);
56}
57
58
59
zijunzhaoa8d42a42023-06-07 23:02:37 +000060__BIONIC_THREADS_INLINE int cnd_broadcast(cnd_t* _Nonnull __cnd) {
Elliott Hughes42067112019-04-18 14:27:24 -070061 return __bionic_thrd_error(pthread_cond_broadcast(__cnd));
62}
63
zijunzhaoa8d42a42023-06-07 23:02:37 +000064__BIONIC_THREADS_INLINE void cnd_destroy(cnd_t* _Nonnull __cnd) {
Elliott Hughes42067112019-04-18 14:27:24 -070065 pthread_cond_destroy(__cnd);
66}
67
zijunzhaoa8d42a42023-06-07 23:02:37 +000068__BIONIC_THREADS_INLINE int cnd_init(cnd_t* _Nonnull __cnd) {
Elliott Hughes42067112019-04-18 14:27:24 -070069 return __bionic_thrd_error(pthread_cond_init(__cnd, NULL));
70}
71
zijunzhaoa8d42a42023-06-07 23:02:37 +000072__BIONIC_THREADS_INLINE int cnd_signal(cnd_t* _Nonnull __cnd) {
Elliott Hughes42067112019-04-18 14:27:24 -070073 return __bionic_thrd_error(pthread_cond_signal(__cnd));
74}
75
zijunzhaoa8d42a42023-06-07 23:02:37 +000076__BIONIC_THREADS_INLINE int cnd_timedwait(cnd_t* _Nonnull __cnd,
77 mtx_t* _Nonnull __mtx,
78 const struct timespec* _Nullable __timeout) {
Elliott Hughes42067112019-04-18 14:27:24 -070079 return __bionic_thrd_error(pthread_cond_timedwait(__cnd, __mtx, __timeout));
80}
81
zijunzhaoa8d42a42023-06-07 23:02:37 +000082__BIONIC_THREADS_INLINE int cnd_wait(cnd_t* _Nonnull __cnd, mtx_t* _Nonnull __mtx) {
Elliott Hughes42067112019-04-18 14:27:24 -070083 return __bionic_thrd_error(pthread_cond_wait(__cnd, __mtx));
84}
85
86
87
zijunzhaoa8d42a42023-06-07 23:02:37 +000088__BIONIC_THREADS_INLINE void mtx_destroy(mtx_t* _Nonnull __mtx) {
Elliott Hughes42067112019-04-18 14:27:24 -070089 pthread_mutex_destroy(__mtx);
90}
91
zijunzhaoa8d42a42023-06-07 23:02:37 +000092__BIONIC_THREADS_INLINE int mtx_init(mtx_t* _Nonnull __mtx, int __type) {
Elliott Hughes42067112019-04-18 14:27:24 -070093 int __pthread_type = (__type & mtx_recursive) ? PTHREAD_MUTEX_RECURSIVE
94 : PTHREAD_MUTEX_NORMAL;
95 __type &= ~mtx_recursive;
96 if (__type != mtx_plain && __type != mtx_timed) return thrd_error;
97
98 pthread_mutexattr_t __attr;
99 pthread_mutexattr_init(&__attr);
100 pthread_mutexattr_settype(&__attr, __pthread_type);
101 return __bionic_thrd_error(pthread_mutex_init(__mtx, &__attr));
102}
103
zijunzhaoa8d42a42023-06-07 23:02:37 +0000104__BIONIC_THREADS_INLINE int mtx_lock(mtx_t* _Nonnull __mtx) {
Elliott Hughes42067112019-04-18 14:27:24 -0700105 return __bionic_thrd_error(pthread_mutex_lock(__mtx));
106}
107
zijunzhaoa8d42a42023-06-07 23:02:37 +0000108__BIONIC_THREADS_INLINE int mtx_timedlock(mtx_t* _Nonnull __mtx,
109 const struct timespec* _Nullable __timeout) {
Elliott Hughes42067112019-04-18 14:27:24 -0700110 return __bionic_thrd_error(pthread_mutex_timedlock(__mtx, __timeout));
111}
112
zijunzhaoa8d42a42023-06-07 23:02:37 +0000113__BIONIC_THREADS_INLINE int mtx_trylock(mtx_t* _Nonnull __mtx) {
Elliott Hughes42067112019-04-18 14:27:24 -0700114 return __bionic_thrd_error(pthread_mutex_trylock(__mtx));
115}
116
zijunzhaoa8d42a42023-06-07 23:02:37 +0000117__BIONIC_THREADS_INLINE int mtx_unlock(mtx_t* _Nonnull __mtx) {
Elliott Hughes42067112019-04-18 14:27:24 -0700118 return __bionic_thrd_error(pthread_mutex_unlock(__mtx));
119}
120
Elliott Hughes42067112019-04-18 14:27:24 -0700121struct __bionic_thrd_data {
Elliott Hughes2b27f572024-08-22 21:17:34 +0000122 thrd_start_t _Nonnull __func;
123 void* _Nullable __arg;
Elliott Hughes42067112019-04-18 14:27:24 -0700124};
125
Elliott Hughes3469e7d2024-05-15 16:06:07 +0000126static __inline void* _Nonnull __bionic_thrd_trampoline(void* _Nonnull __arg) {
Elliott Hughes42067112019-04-18 14:27:24 -0700127 struct __bionic_thrd_data __data =
128 *__BIONIC_CAST(static_cast, struct __bionic_thrd_data*, __arg);
129 free(__arg);
130 int __result = __data.__func(__data.__arg);
131 return __BIONIC_CAST(reinterpret_cast, void*,
132 __BIONIC_CAST(static_cast, uintptr_t, __result));
133}
134
zijunzhaoa8d42a42023-06-07 23:02:37 +0000135__BIONIC_THREADS_INLINE int thrd_create(thrd_t* _Nonnull __thrd,
136 thrd_start_t _Nonnull __func,
137 void* _Nullable __arg) {
Elliott Hughes42067112019-04-18 14:27:24 -0700138 struct __bionic_thrd_data* __pthread_arg =
139 __BIONIC_CAST(static_cast, struct __bionic_thrd_data*,
140 malloc(sizeof(struct __bionic_thrd_data)));
141 __pthread_arg->__func = __func;
142 __pthread_arg->__arg = __arg;
143 int __result = __bionic_thrd_error(pthread_create(__thrd, NULL,
144 __bionic_thrd_trampoline,
145 __pthread_arg));
146 if (__result != thrd_success) free(__pthread_arg);
147 return __result;
148}
149
150__BIONIC_THREADS_INLINE thrd_t thrd_current(void) {
151 return pthread_self();
152}
153
154__BIONIC_THREADS_INLINE int thrd_detach(thrd_t __thrd) {
155 return __bionic_thrd_error(pthread_detach(__thrd));
156}
157
158__BIONIC_THREADS_INLINE int thrd_equal(thrd_t __lhs, thrd_t __rhs) {
159 return pthread_equal(__lhs, __rhs);
160}
161
162__BIONIC_THREADS_INLINE void thrd_exit(int __result) {
163 pthread_exit(__BIONIC_CAST(reinterpret_cast, void*,
164 __BIONIC_CAST(static_cast, uintptr_t, __result)));
165}
166
zijunzhaoa8d42a42023-06-07 23:02:37 +0000167__BIONIC_THREADS_INLINE int thrd_join(thrd_t __thrd, int* _Nullable __result) {
Elliott Hughes42067112019-04-18 14:27:24 -0700168 void* __pthread_result;
169 if (pthread_join(__thrd, &__pthread_result) != 0) return thrd_error;
170 if (__result) {
171 *__result = __BIONIC_CAST(reinterpret_cast, intptr_t, __pthread_result);
172 }
173 return thrd_success;
174}
175
zijunzhaoa8d42a42023-06-07 23:02:37 +0000176__BIONIC_THREADS_INLINE int thrd_sleep(const struct timespec* _Nonnull __duration,
177 struct timespec* _Nullable __remaining) {
Elliott Hughes42067112019-04-18 14:27:24 -0700178 int __rc = nanosleep(__duration, __remaining);
179 if (__rc == 0) return 0;
180 return (errno == EINTR) ? -1 : -2;
181}
182
183__BIONIC_THREADS_INLINE void thrd_yield(void) {
184 sched_yield();
185}
186
187
188
zijunzhaoa8d42a42023-06-07 23:02:37 +0000189__BIONIC_THREADS_INLINE int tss_create(tss_t* _Nonnull __key, tss_dtor_t _Nullable __dtor) {
Elliott Hughes42067112019-04-18 14:27:24 -0700190 return __bionic_thrd_error(pthread_key_create(__key, __dtor));
191}
192
193__BIONIC_THREADS_INLINE void tss_delete(tss_t __key) {
194 pthread_key_delete(__key);
195}
196
zijunzhaoa8d42a42023-06-07 23:02:37 +0000197__BIONIC_THREADS_INLINE void* _Nullable tss_get(tss_t __key) {
Elliott Hughes42067112019-04-18 14:27:24 -0700198 return pthread_getspecific(__key);
199}
200
zijunzhaoa8d42a42023-06-07 23:02:37 +0000201__BIONIC_THREADS_INLINE int tss_set(tss_t __key, void* _Nonnull __value) {
Elliott Hughes42067112019-04-18 14:27:24 -0700202 return __bionic_thrd_error(pthread_setspecific(__key, __value));
203}
204
205__END_DECLS
Logan Chien235aad12019-08-27 20:29:29 -0700206
207#endif // __BIONIC_THREADS_INLINE