]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libc++/include/__threading_support
Merge libc++ r291274, and update the library Makefile.
[FreeBSD/FreeBSD.git] / contrib / libc++ / include / __threading_support
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10
11 #ifndef _LIBCPP_THREADING_SUPPORT
12 #define _LIBCPP_THREADING_SUPPORT
13
14 #include <__config>
15
16 #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
17 #pragma GCC system_header
18 #endif
19
20 #ifndef _LIBCPP_HAS_NO_THREADS
21
22 #ifndef __libcpp_has_include
23   #ifndef __has_include
24     #define __libcpp_has_include(x) 0
25   #else
26     #define __libcpp_has_include(x) __has_include(x)
27   #endif
28 #endif
29
30 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) && \
31     !__libcpp_has_include(<__external_threading>)
32 // If the <__external_threading> header is absent, build libc++ against a
33 // pthread-oriented thread api but leave out its implementation. This setup
34 // allows building+testing of an externally-threaded library variant (on any
35 // platform that supports pthreads). Here, an 'externally-threaded' library
36 // variant is one where the implementation of the libc++ thread api is provided
37 // as a separate library.
38 #define _LIBCPP_HAS_THREAD_API_EXTERNAL_PTHREAD
39 #endif
40
41 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) && \
42     __libcpp_has_include(<__external_threading>)
43 #include <__external_threading>
44 #else
45
46 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || \
47     defined(_LIBCPP_HAS_THREAD_API_EXTERNAL_PTHREAD)
48 #include <pthread.h>
49 #include <sched.h>
50 #endif
51
52 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
53 #define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
54 #else
55 #define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
56 #endif
57
58 _LIBCPP_BEGIN_NAMESPACE_STD
59
60 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || \
61     defined(_LIBCPP_HAS_THREAD_API_EXTERNAL_PTHREAD)
62 // Mutex
63 typedef pthread_mutex_t __libcpp_mutex_t;
64 #define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
65
66 typedef pthread_mutex_t __libcpp_recursive_mutex_t;
67
68 // Condition Variable
69 typedef pthread_cond_t __libcpp_condvar_t;
70 #define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
71
72 // Execute once
73 typedef pthread_once_t __libcpp_exec_once_flag;
74 #define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
75
76 // Thread id
77 typedef pthread_t __libcpp_thread_id;
78
79 // Thread
80 typedef pthread_t __libcpp_thread_t;
81
82 // Thrad Local Storage
83 typedef pthread_key_t __libcpp_tls_key;
84 #endif
85
86 // Mutex
87 _LIBCPP_THREAD_ABI_VISIBILITY
88 int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
89
90 _LIBCPP_THREAD_ABI_VISIBILITY
91 int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
92
93 _LIBCPP_THREAD_ABI_VISIBILITY
94 int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
95
96 _LIBCPP_THREAD_ABI_VISIBILITY
97 int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
98
99 _LIBCPP_THREAD_ABI_VISIBILITY
100 int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
101
102 _LIBCPP_THREAD_ABI_VISIBILITY
103 int __libcpp_mutex_lock(__libcpp_mutex_t *__m);
104
105 _LIBCPP_THREAD_ABI_VISIBILITY
106 int __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
107
108 _LIBCPP_THREAD_ABI_VISIBILITY
109 int __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
110
111 _LIBCPP_THREAD_ABI_VISIBILITY
112 int __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
113
114 // Condition variable
115 _LIBCPP_THREAD_ABI_VISIBILITY
116 int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
117
118 _LIBCPP_THREAD_ABI_VISIBILITY
119 int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
120
121 _LIBCPP_THREAD_ABI_VISIBILITY
122 int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
123
124 _LIBCPP_THREAD_ABI_VISIBILITY
125 int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
126                                timespec *__ts);
127
128 _LIBCPP_THREAD_ABI_VISIBILITY
129 int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
130
131 // Execute once
132 _LIBCPP_THREAD_ABI_VISIBILITY
133 int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
134                           void (*init_routine)(void));
135
136 // Thread id
137 #if defined(__APPLE__) && !defined(__arm__)
138 _LIBCPP_THREAD_ABI_VISIBILITY
139 mach_port_t __libcpp_thread_get_port();
140 #endif
141
142 _LIBCPP_THREAD_ABI_VISIBILITY
143 bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
144
145 _LIBCPP_THREAD_ABI_VISIBILITY
146 bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
147
148 // Thread
149 _LIBCPP_THREAD_ABI_VISIBILITY
150 int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
151                            void *__arg);
152
153 _LIBCPP_THREAD_ABI_VISIBILITY
154 __libcpp_thread_id __libcpp_thread_get_current_id();
155
156 _LIBCPP_THREAD_ABI_VISIBILITY
157 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
158
159 _LIBCPP_THREAD_ABI_VISIBILITY
160 int __libcpp_thread_join(__libcpp_thread_t *__t);
161
162 _LIBCPP_THREAD_ABI_VISIBILITY
163 int __libcpp_thread_detach(__libcpp_thread_t *__t);
164
165 _LIBCPP_THREAD_ABI_VISIBILITY
166 void __libcpp_thread_yield();
167
168 // Thread local storage
169 _LIBCPP_THREAD_ABI_VISIBILITY
170 int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *));
171
172 _LIBCPP_THREAD_ABI_VISIBILITY
173 void *__libcpp_tls_get(__libcpp_tls_key __key);
174
175 _LIBCPP_THREAD_ABI_VISIBILITY
176 int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
177
178 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || \
179     defined(_LIBCPP_BUILDING_THREAD_API_EXTERNAL_PTHREAD)
180
181 int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
182 {
183   pthread_mutexattr_t attr;
184   int __ec = pthread_mutexattr_init(&attr);
185   if (__ec)
186     return __ec;
187   __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
188   if (__ec) {
189     pthread_mutexattr_destroy(&attr);
190     return __ec;
191   }
192   __ec = pthread_mutex_init(__m, &attr);
193   if (__ec) {
194     pthread_mutexattr_destroy(&attr);
195     return __ec;
196   }
197   __ec = pthread_mutexattr_destroy(&attr);
198   if (__ec) {
199     pthread_mutex_destroy(__m);
200     return __ec;
201   }
202   return 0;
203 }
204
205 int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
206 {
207   return pthread_mutex_lock(__m);
208 }
209
210 int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
211 {
212   return pthread_mutex_trylock(__m);
213 }
214
215 int __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m)
216 {
217   return pthread_mutex_unlock(__m);
218 }
219
220 int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
221 {
222   return pthread_mutex_destroy(__m);
223 }
224
225 int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
226 {
227   return pthread_mutex_lock(__m);
228 }
229
230 int __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
231 {
232   return pthread_mutex_trylock(__m);
233 }
234
235 int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
236 {
237   return pthread_mutex_unlock(__m);
238 }
239
240 int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
241 {
242   return pthread_mutex_destroy(__m);
243 }
244
245 // Condition Variable
246 int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
247 {
248   return pthread_cond_signal(__cv);
249 }
250
251 int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
252 {
253   return pthread_cond_broadcast(__cv);
254 }
255
256 int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
257 {
258   return pthread_cond_wait(__cv, __m);
259 }
260
261 int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
262                                timespec *__ts)
263 {
264   return pthread_cond_timedwait(__cv, __m, __ts);
265 }
266
267 int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
268 {
269   return pthread_cond_destroy(__cv);
270 }
271
272 // Execute once
273 int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
274                           void (*init_routine)(void)) {
275   return pthread_once(flag, init_routine);
276 }
277
278 // Thread id
279 #if defined(__APPLE__) && !defined(__arm__)
280 mach_port_t __libcpp_thread_get_port() {
281     return pthread_mach_thread_np(pthread_self());
282 }
283 #endif
284
285 // Returns non-zero if the thread ids are equal, otherwise 0
286 bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
287 {
288   return pthread_equal(t1, t2) != 0;
289 }
290
291 // Returns non-zero if t1 < t2, otherwise 0
292 bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
293 {
294   return t1 < t2;
295 }
296
297 // Thread
298 int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
299                            void *__arg)
300 {
301   return pthread_create(__t, 0, __func, __arg);
302 }
303
304 __libcpp_thread_id __libcpp_thread_get_current_id()
305 {
306   return pthread_self();
307 }
308
309 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
310 {
311   return *__t;
312 }
313
314 int __libcpp_thread_join(__libcpp_thread_t *__t)
315 {
316   return pthread_join(*__t, 0);
317 }
318
319 int __libcpp_thread_detach(__libcpp_thread_t *__t)
320 {
321   return pthread_detach(*__t);
322 }
323
324 void __libcpp_thread_yield()
325 {
326   sched_yield();
327 }
328
329 // Thread local storage
330 int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
331 {
332   return pthread_key_create(__key, __at_exit);
333 }
334
335 void *__libcpp_tls_get(__libcpp_tls_key __key)
336 {
337   return pthread_getspecific(__key);
338 }
339
340 int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
341 {
342     return pthread_setspecific(__key, __p);
343 }
344
345 #endif // _LIBCPP_HAS_THREAD_API_PTHREAD
346
347 _LIBCPP_END_NAMESPACE_STD
348
349 #endif // !_LIBCPP_HAS_THREAD_API_EXTERNAL || !__libcpp_has_include(<__external_threading>)
350
351 #endif // _LIBCPP_HAS_NO_THREADS
352
353 #endif // _LIBCPP_THREADING_SUPPORT