]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libc++/include/__threading_support
Merge libc++ trunk r338150, and resolve conflicts.
[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 #include <chrono>
16 #include <errno.h>
17
18 #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
19 #pragma GCC system_header
20 #endif
21
22 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
23 # include <__external_threading>
24 #elif !defined(_LIBCPP_HAS_NO_THREADS)
25
26 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
27 # include <pthread.h>
28 # include <sched.h>
29 #endif
30
31 _LIBCPP_PUSH_MACROS
32 #include <__undef_macros>
33
34 #if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
35     defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \
36     defined(_LIBCPP_HAS_THREAD_API_WIN32)
37 #define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
38 #else
39 #define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
40 #endif
41
42 #if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis)
43 #define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
44 #else
45 #define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
46 #endif
47
48 _LIBCPP_BEGIN_NAMESPACE_STD
49
50 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
51 // Mutex
52 typedef pthread_mutex_t __libcpp_mutex_t;
53 #define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
54
55 typedef pthread_mutex_t __libcpp_recursive_mutex_t;
56
57 // Condition Variable
58 typedef pthread_cond_t __libcpp_condvar_t;
59 #define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
60
61 // Execute once
62 typedef pthread_once_t __libcpp_exec_once_flag;
63 #define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
64
65 // Thread id
66 typedef pthread_t __libcpp_thread_id;
67
68 // Thread
69 #define _LIBCPP_NULL_THREAD 0U
70
71 typedef pthread_t __libcpp_thread_t;
72
73 // Thrad Local Storage
74 typedef pthread_key_t __libcpp_tls_key;
75
76 #define _LIBCPP_TLS_DESTRUCTOR_CC
77 #else
78 // Mutex
79 typedef void* __libcpp_mutex_t;
80 #define _LIBCPP_MUTEX_INITIALIZER 0
81
82 #if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__)
83 typedef void* __libcpp_recursive_mutex_t[6];
84 #elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__)
85 typedef void* __libcpp_recursive_mutex_t[5];
86 #else
87 # error Unsupported architecture
88 #endif
89
90 // Condition Variable
91 typedef void* __libcpp_condvar_t;
92 #define _LIBCPP_CONDVAR_INITIALIZER 0
93
94 // Execute Once
95 typedef void* __libcpp_exec_once_flag;
96 #define _LIBCPP_EXEC_ONCE_INITIALIZER 0
97
98 // Thread ID
99 typedef long __libcpp_thread_id;
100
101 // Thread
102 #define _LIBCPP_NULL_THREAD 0U
103
104 typedef void* __libcpp_thread_t;
105
106 // Thread Local Storage
107 typedef long __libcpp_tls_key;
108
109 #define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall
110 #endif
111
112 // Mutex
113 _LIBCPP_THREAD_ABI_VISIBILITY
114 int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
115
116 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
117 int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
118
119 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
120 bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
121
122 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
123 int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
124
125 _LIBCPP_THREAD_ABI_VISIBILITY
126 int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
127
128 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
129 int __libcpp_mutex_lock(__libcpp_mutex_t *__m);
130
131 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
132 bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
133
134 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
135 int __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
136
137 _LIBCPP_THREAD_ABI_VISIBILITY
138 int __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
139
140 // Condition variable
141 _LIBCPP_THREAD_ABI_VISIBILITY
142 int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
143
144 _LIBCPP_THREAD_ABI_VISIBILITY
145 int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
146
147 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
148 int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
149
150 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
151 int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
152                                timespec *__ts);
153
154 _LIBCPP_THREAD_ABI_VISIBILITY
155 int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
156
157 // Execute once
158 _LIBCPP_THREAD_ABI_VISIBILITY
159 int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
160                           void (*init_routine)(void));
161
162 // Thread id
163 _LIBCPP_THREAD_ABI_VISIBILITY
164 bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
165
166 _LIBCPP_THREAD_ABI_VISIBILITY
167 bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
168
169 // Thread
170 _LIBCPP_THREAD_ABI_VISIBILITY
171 bool __libcpp_thread_isnull(const __libcpp_thread_t *__t);
172
173 _LIBCPP_THREAD_ABI_VISIBILITY
174 int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
175                            void *__arg);
176
177 _LIBCPP_THREAD_ABI_VISIBILITY
178 __libcpp_thread_id __libcpp_thread_get_current_id();
179
180 _LIBCPP_THREAD_ABI_VISIBILITY
181 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
182
183 _LIBCPP_THREAD_ABI_VISIBILITY
184 int __libcpp_thread_join(__libcpp_thread_t *__t);
185
186 _LIBCPP_THREAD_ABI_VISIBILITY
187 int __libcpp_thread_detach(__libcpp_thread_t *__t);
188
189 _LIBCPP_THREAD_ABI_VISIBILITY
190 void __libcpp_thread_yield();
191
192 _LIBCPP_THREAD_ABI_VISIBILITY
193 void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns);
194
195 // Thread local storage
196 _LIBCPP_THREAD_ABI_VISIBILITY
197 int __libcpp_tls_create(__libcpp_tls_key* __key,
198                         void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*));
199
200 _LIBCPP_THREAD_ABI_VISIBILITY
201 void *__libcpp_tls_get(__libcpp_tls_key __key);
202
203 _LIBCPP_THREAD_ABI_VISIBILITY
204 int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
205
206 #if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
207      defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) && \
208     defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
209
210 int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
211 {
212   pthread_mutexattr_t attr;
213   int __ec = pthread_mutexattr_init(&attr);
214   if (__ec)
215     return __ec;
216   __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
217   if (__ec) {
218     pthread_mutexattr_destroy(&attr);
219     return __ec;
220   }
221   __ec = pthread_mutex_init(__m, &attr);
222   if (__ec) {
223     pthread_mutexattr_destroy(&attr);
224     return __ec;
225   }
226   __ec = pthread_mutexattr_destroy(&attr);
227   if (__ec) {
228     pthread_mutex_destroy(__m);
229     return __ec;
230   }
231   return 0;
232 }
233
234 int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
235 {
236   return pthread_mutex_lock(__m);
237 }
238
239 bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
240 {
241   return pthread_mutex_trylock(__m) == 0;
242 }
243
244 int __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m)
245 {
246   return pthread_mutex_unlock(__m);
247 }
248
249 int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
250 {
251   return pthread_mutex_destroy(__m);
252 }
253
254 int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
255 {
256   return pthread_mutex_lock(__m);
257 }
258
259 bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
260 {
261   return pthread_mutex_trylock(__m) == 0;
262 }
263
264 int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
265 {
266   return pthread_mutex_unlock(__m);
267 }
268
269 int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
270 {
271   return pthread_mutex_destroy(__m);
272 }
273
274 // Condition Variable
275 int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
276 {
277   return pthread_cond_signal(__cv);
278 }
279
280 int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
281 {
282   return pthread_cond_broadcast(__cv);
283 }
284
285 int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
286 {
287   return pthread_cond_wait(__cv, __m);
288 }
289
290 int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
291                                timespec *__ts)
292 {
293   return pthread_cond_timedwait(__cv, __m, __ts);
294 }
295
296 int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
297 {
298   return pthread_cond_destroy(__cv);
299 }
300
301 // Execute once
302 int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
303                           void (*init_routine)(void)) {
304   return pthread_once(flag, init_routine);
305 }
306
307 // Thread id
308 // Returns non-zero if the thread ids are equal, otherwise 0
309 bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
310 {
311   return pthread_equal(t1, t2) != 0;
312 }
313
314 // Returns non-zero if t1 < t2, otherwise 0
315 bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
316 {
317   return t1 < t2;
318 }
319
320 // Thread
321 bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
322   return *__t == 0;
323 }
324
325 int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
326                            void *__arg)
327 {
328   return pthread_create(__t, 0, __func, __arg);
329 }
330
331 __libcpp_thread_id __libcpp_thread_get_current_id()
332 {
333   return pthread_self();
334 }
335
336 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
337 {
338   return *__t;
339 }
340
341 int __libcpp_thread_join(__libcpp_thread_t *__t)
342 {
343   return pthread_join(*__t, 0);
344 }
345
346 int __libcpp_thread_detach(__libcpp_thread_t *__t)
347 {
348   return pthread_detach(*__t);
349 }
350
351 void __libcpp_thread_yield()
352 {
353   sched_yield();
354 }
355
356 void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
357 {
358    using namespace chrono;
359    seconds __s = duration_cast<seconds>(__ns);
360    timespec __ts;
361    typedef decltype(__ts.tv_sec) ts_sec;
362    _LIBCPP_CONSTEXPR ts_sec __ts_sec_max = numeric_limits<ts_sec>::max();
363
364    if (__s.count() < __ts_sec_max)
365    {
366      __ts.tv_sec = static_cast<ts_sec>(__s.count());
367      __ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count());
368    }
369    else
370    {
371      __ts.tv_sec = __ts_sec_max;
372      __ts.tv_nsec = 999999999; // (10^9 - 1)
373    }
374
375    while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR);
376 }
377
378 // Thread local storage
379 int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
380 {
381   return pthread_key_create(__key, __at_exit);
382 }
383
384 void *__libcpp_tls_get(__libcpp_tls_key __key)
385 {
386   return pthread_getspecific(__key);
387 }
388
389 int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
390 {
391     return pthread_setspecific(__key, __p);
392 }
393
394 #endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
395
396 _LIBCPP_END_NAMESPACE_STD
397
398 _LIBCPP_POP_MACROS
399
400 #endif // !_LIBCPP_HAS_NO_THREADS
401
402 #endif // _LIBCPP_THREADING_SUPPORT