comparison libcxx/include/__threading_support @ 173:0572611fdcc8 llvm10 llvm12

reorgnization done
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 11:55:54 +0900
parents 1d019706d866
children 2e18cbf3894f
comparison
equal deleted inserted replaced
172:9fbae9c8bf63 173:0572611fdcc8
24 #elif !defined(_LIBCPP_HAS_NO_THREADS) 24 #elif !defined(_LIBCPP_HAS_NO_THREADS)
25 25
26 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 26 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
27 # include <pthread.h> 27 # include <pthread.h>
28 # include <sched.h> 28 # include <sched.h>
29 # ifdef __APPLE__
30 # define _LIBCPP_NO_NATIVE_SEMAPHORES
31 # endif
32 # ifndef _LIBCPP_NO_NATIVE_SEMAPHORES
33 # include <semaphore.h>
34 # endif
29 #elif defined(_LIBCPP_HAS_THREAD_API_C11) 35 #elif defined(_LIBCPP_HAS_THREAD_API_C11)
30 # include <threads.h> 36 # include <threads.h>
31 #endif 37 #endif
32 38
33 #if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ 39 #if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
63 69
64 // Condition Variable 70 // Condition Variable
65 typedef pthread_cond_t __libcpp_condvar_t; 71 typedef pthread_cond_t __libcpp_condvar_t;
66 #define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER 72 #define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
67 73
74 #ifndef _LIBCPP_NO_NATIVE_SEMAPHORES
75 // Semaphore
76 typedef sem_t __libcpp_semaphore_t;
77 # define _LIBCPP_SEMAPHORE_MAX SEM_VALUE_MAX
78 #endif
79
68 // Execute once 80 // Execute once
69 typedef pthread_once_t __libcpp_exec_once_flag; 81 typedef pthread_once_t __libcpp_exec_once_flag;
70 #define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT 82 #define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
71 83
72 // Thread id 84 // Thread id
125 137
126 // Condition Variable 138 // Condition Variable
127 typedef void* __libcpp_condvar_t; 139 typedef void* __libcpp_condvar_t;
128 #define _LIBCPP_CONDVAR_INITIALIZER 0 140 #define _LIBCPP_CONDVAR_INITIALIZER 0
129 141
142 // Semaphore
143 typedef void* __libcpp_semaphore_t;
144
130 // Execute Once 145 // Execute Once
131 typedef void* __libcpp_exec_once_flag; 146 typedef void* __libcpp_exec_once_flag;
132 #define _LIBCPP_EXEC_ONCE_INITIALIZER 0 147 #define _LIBCPP_EXEC_ONCE_INITIALIZER 0
133 148
134 // Thread ID 149 // Thread ID
189 __libcpp_timespec_t *__ts); 204 __libcpp_timespec_t *__ts);
190 205
191 _LIBCPP_THREAD_ABI_VISIBILITY 206 _LIBCPP_THREAD_ABI_VISIBILITY
192 int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv); 207 int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
193 208
209 #ifndef _LIBCPP_NO_NATIVE_SEMAPHORES
210
211 // Semaphore
212 _LIBCPP_THREAD_ABI_VISIBILITY
213 bool __libcpp_semaphore_init(__libcpp_semaphore_t* __sem, int __init);
214
215 _LIBCPP_THREAD_ABI_VISIBILITY
216 bool __libcpp_semaphore_destroy(__libcpp_semaphore_t* __sem);
217
218 _LIBCPP_THREAD_ABI_VISIBILITY
219 bool __libcpp_semaphore_post(__libcpp_semaphore_t* __sem);
220
221 _LIBCPP_THREAD_ABI_VISIBILITY
222 bool __libcpp_semaphore_wait(__libcpp_semaphore_t* __sem);
223
224 _LIBCPP_THREAD_ABI_VISIBILITY
225 bool __libcpp_semaphore_wait_timed(__libcpp_semaphore_t* __sem, chrono::nanoseconds const& __ns);
226
227 #endif // _LIBCPP_NO_NATIVE_SEMAPHORES
228
194 // Execute once 229 // Execute once
195 _LIBCPP_THREAD_ABI_VISIBILITY 230 _LIBCPP_THREAD_ABI_VISIBILITY
196 int __libcpp_execute_once(__libcpp_exec_once_flag *flag, 231 int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
197 void (*init_routine)()); 232 void (*init_routine)());
198 233
240 _LIBCPP_THREAD_ABI_VISIBILITY 275 _LIBCPP_THREAD_ABI_VISIBILITY
241 int __libcpp_tls_set(__libcpp_tls_key __key, void *__p); 276 int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
242 277
243 #endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 278 #endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
244 279
280 struct __libcpp_timed_backoff_policy {
281 _LIBCPP_THREAD_ABI_VISIBILITY
282 bool operator()(chrono::nanoseconds __elapsed) const;
283 };
284
285 inline _LIBCPP_INLINE_VISIBILITY
286 bool __libcpp_timed_backoff_policy::operator()(chrono::nanoseconds __elapsed) const
287 {
288 if(__elapsed > chrono::milliseconds(128))
289 __libcpp_thread_sleep_for(chrono::milliseconds(8));
290 else if(__elapsed > chrono::microseconds(64))
291 __libcpp_thread_sleep_for(__elapsed / 2);
292 else if(__elapsed > chrono::microseconds(4))
293 __libcpp_thread_yield();
294 else
295 ; // poll
296 return false;
297 }
298
299 static _LIBCPP_CONSTEXPR const int __libcpp_polling_count = 64;
300
301 template<class _Fn, class _BFn>
302 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
303 bool __libcpp_thread_poll_with_backoff(
304 _Fn && __f, _BFn && __bf, chrono::nanoseconds __max_elapsed = chrono::nanoseconds::zero())
305 {
306 auto const __start = chrono::high_resolution_clock::now();
307 for(int __count = 0;;) {
308 if(__f())
309 return true; // _Fn completion means success
310 if(__count < __libcpp_polling_count) {
311 __count += 1;
312 continue;
313 }
314 chrono::nanoseconds const __elapsed = chrono::high_resolution_clock::now() - __start;
315 if(__max_elapsed != chrono::nanoseconds::zero() && __max_elapsed < __elapsed)
316 return false; // timeout failure
317 if(__bf(__elapsed))
318 return false; // _BFn completion means failure
319 }
320 }
321
245 #if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ 322 #if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
246 defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) 323 defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL))
324
247 325
248 namespace __thread_detail { 326 namespace __thread_detail {
249 327
250 inline __libcpp_timespec_t __convert_to_timespec(const chrono::nanoseconds& __ns) 328 inline __libcpp_timespec_t __convert_to_timespec(const chrono::nanoseconds& __ns)
251 { 329 {
362 int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) 440 int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
363 { 441 {
364 return pthread_cond_destroy(__cv); 442 return pthread_cond_destroy(__cv);
365 } 443 }
366 444
445 #ifndef _LIBCPP_NO_NATIVE_SEMAPHORES
446
447 // Semaphore
448 bool __libcpp_semaphore_init(__libcpp_semaphore_t* __sem, int __init)
449 {
450 return sem_init(__sem, 0, __init) == 0;
451 }
452
453 bool __libcpp_semaphore_destroy(__libcpp_semaphore_t* __sem)
454 {
455 return sem_destroy(__sem) == 0;
456 }
457
458 bool __libcpp_semaphore_post(__libcpp_semaphore_t* __sem)
459 {
460 return sem_post(__sem) == 0;
461 }
462
463 bool __libcpp_semaphore_wait(__libcpp_semaphore_t* __sem)
464 {
465 return sem_wait(__sem) == 0;
466 }
467
468 bool __libcpp_semaphore_wait_timed(__libcpp_semaphore_t* __sem, chrono::nanoseconds const& __ns)
469 {
470 auto const __abs_time = chrono::system_clock::now().time_since_epoch() + __ns;
471 __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__abs_time);
472 return sem_timedwait(__sem, &__ts) == 0;
473 }
474
475 #endif //_LIBCPP_NO_NATIVE_SEMAPHORES
476
367 // Execute once 477 // Execute once
368 int __libcpp_execute_once(__libcpp_exec_once_flag *flag, 478 int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
369 void (*init_routine)()) { 479 void (*init_routine)()) {
370 return pthread_once(flag, init_routine); 480 return pthread_once(flag, init_routine);
371 } 481 }
597 { 707 {
598 return tss_set(__key, __p) == thrd_success ? 0 : EINVAL; 708 return tss_set(__key, __p) == thrd_success ? 0 : EINVAL;
599 } 709 }
600 710
601 #endif 711 #endif
712
602 713
603 #endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL 714 #endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
604 715
605 class _LIBCPP_TYPE_VIS thread; 716 class _LIBCPP_TYPE_VIS thread;
606 class _LIBCPP_TYPE_VIS __thread_id; 717 class _LIBCPP_TYPE_VIS __thread_id;