__threading_support (12604B)
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 // Thread Local Storage 74 typedef pthread_key_t __libcpp_tls_key; 75 76 #define _LIBCPP_TLS_DESTRUCTOR_CC 77 #else 78 // Mutex 79 #ifndef _LIBCPP_MUTEXES_ARE_SHIT 80 typedef void* __libcpp_mutex_t; 81 #define _LIBCPP_MUTEX_INITIALIZER 0 82 #endif 83 84 #if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__) 85 # ifdef _LIBCPP_MUTEXES_ARE_SHIT 86 typedef size_t __libcpp_recursive_mutex_t[6]; 87 # define _LIBCPP_MUTEX_INITIALIZER {(size_t) -1,(size_t) -1,(size_t) -1,(size_t) -1,(size_t) -1,(size_t) -1} 88 # else 89 typedef void* __libcpp_recursive_mutex_t[6]; 90 # endif 91 #elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__) 92 # ifdef _LIBCPP_MUTEXES_ARE_SHIT 93 typedef size_t __libcpp_recursive_mutex_t[5]; 94 # define _LIBCPP_MUTEX_INITIALIZER {(size_t) -1,(size_t) -1,(size_t) -1,(size_t) -1,(size_t) -1} 95 # else 96 typedef void* __libcpp_recursive_mutex_t[5]; 97 # endif 98 #else 99 # error Unsupported architecture 100 #endif 101 102 #ifdef _LIBCPP_MUTEXES_ARE_SHIT 103 typedef __libcpp_recursive_mutex_t __libcpp_mutex_t; 104 #endif 105 106 // Condition Variable 107 #ifdef _LIBCPP_MUTEXES_ARE_SHIT 108 typedef struct { 109 __libcpp_recursive_mutex_t waiter_cs; 110 size_t event; 111 unsigned waiter_count, release_count, generation_count; 112 } __libcpp_condvar_t; 113 # define _LIBCPP_CONDVAR_INITIALIZER {{}, (size_t) -2, 0, 0, 0} 114 #else 115 typedef void* __libcpp_condvar_t; 116 #define _LIBCPP_CONDVAR_INITIALIZER 0 117 #endif 118 119 // Execute Once 120 #ifndef _LIBCPP_MUTEXES_ARE_SHIT 121 typedef void* __libcpp_exec_once_flag; 122 #define _LIBCPP_EXEC_ONCE_INITIALIZER 0 123 #endif 124 125 // Thread ID 126 #ifdef _LIBCPP_MUTEXES_ARE_SHIT 127 typedef unsigned int __libcpp_thread_id; 128 #else 129 typedef long __libcpp_thread_id; 130 #endif 131 132 // Thread 133 #ifdef _LIBCPP_MUTEXES_ARE_SHIT 134 #define _LIBCPP_NULL_THREAD { 0, 0 } 135 136 typedef struct { 137 void* handle; 138 unsigned int id; 139 } __libcpp_thread_t; 140 #else 141 #define _LIBCPP_NULL_THREAD 0U 142 143 typedef void* __libcpp_thread_t; 144 #endif 145 146 // Thread Local Storage 147 typedef long __libcpp_tls_key; 148 149 #define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall 150 #endif 151 152 // Mutex 153 _LIBCPP_THREAD_ABI_VISIBILITY 154 int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m); 155 156 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 157 int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m); 158 159 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 160 bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m); 161 162 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 163 int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m); 164 165 _LIBCPP_THREAD_ABI_VISIBILITY 166 int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m); 167 168 #ifdef _LIBCPP_MUTEXES_ARE_SHIT 169 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 170 void __libcpp_mutex_init(__libcpp_mutex_t *__m); 171 172 // make it a linker error if the header defines vs cpp defines mismatch 173 #define __libcpp_mutex_lock __libcpp_mutex_lock_shit 174 #define __libcpp_mutex_trylock __libcpp_mutex_trylock_shit 175 #define __libcpp_mutex_unlock __libcpp_mutex_unlock_shit 176 #define __libcpp_mutex_destroy __libcpp_mutex_destroy_shit 177 #endif 178 179 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 180 int __libcpp_mutex_lock(__libcpp_mutex_t *__m); 181 182 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 183 bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m); 184 185 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 186 int __libcpp_mutex_unlock(__libcpp_mutex_t *__m); 187 188 _LIBCPP_THREAD_ABI_VISIBILITY 189 int __libcpp_mutex_destroy(__libcpp_mutex_t *__m); 190 191 // Condition variable 192 #ifdef _LIBCPP_MUTEXES_ARE_SHIT 193 _LIBCPP_THREAD_ABI_VISIBILITY 194 int __libcpp_condvar_init(__libcpp_condvar_t* __cv); 195 196 // make it a linker error if the header defines vs cpp defines mismatch 197 #define __libcpp_condvar_signal __libcpp_condvar_signal_shit 198 #define __libcpp_condvar_broadcast __libcpp_condvar_broadcast_shit 199 #define __libcpp_condvar_wait __libcpp_condvar_wait_shit 200 #define __libcpp_condvar_timedwait __libcpp_condvar_timedwait_shit 201 #define __libcpp_condvar_destroy __libcpp_condvar_destroy_shit 202 #endif 203 204 _LIBCPP_THREAD_ABI_VISIBILITY 205 int __libcpp_condvar_signal(__libcpp_condvar_t* __cv); 206 207 _LIBCPP_THREAD_ABI_VISIBILITY 208 int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv); 209 210 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 211 int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m); 212 213 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 214 int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 215 timespec *__ts); 216 217 _LIBCPP_THREAD_ABI_VISIBILITY 218 int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv); 219 220 // Execute once 221 #ifndef _LIBCPP_MUTEXES_ARE_SHIT 222 _LIBCPP_THREAD_ABI_VISIBILITY 223 int __libcpp_execute_once(__libcpp_exec_once_flag *flag, 224 void (*init_routine)(void)); 225 #endif 226 227 // Thread id 228 _LIBCPP_THREAD_ABI_VISIBILITY 229 bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2); 230 231 _LIBCPP_THREAD_ABI_VISIBILITY 232 bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2); 233 234 // Thread 235 _LIBCPP_THREAD_ABI_VISIBILITY 236 bool __libcpp_thread_isnull(const __libcpp_thread_t *__t); 237 238 _LIBCPP_THREAD_ABI_VISIBILITY 239 int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 240 void *__arg); 241 242 _LIBCPP_THREAD_ABI_VISIBILITY 243 __libcpp_thread_id __libcpp_thread_get_current_id(); 244 245 _LIBCPP_THREAD_ABI_VISIBILITY 246 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t); 247 248 _LIBCPP_THREAD_ABI_VISIBILITY 249 int __libcpp_thread_join(__libcpp_thread_t *__t); 250 251 _LIBCPP_THREAD_ABI_VISIBILITY 252 int __libcpp_thread_detach(__libcpp_thread_t *__t); 253 254 _LIBCPP_THREAD_ABI_VISIBILITY 255 void __libcpp_thread_yield(); 256 257 _LIBCPP_THREAD_ABI_VISIBILITY 258 void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns); 259 260 // Thread local storage 261 _LIBCPP_THREAD_ABI_VISIBILITY 262 int __libcpp_tls_create(__libcpp_tls_key* __key, 263 void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*)); 264 265 _LIBCPP_THREAD_ABI_VISIBILITY 266 void *__libcpp_tls_get(__libcpp_tls_key __key); 267 268 _LIBCPP_THREAD_ABI_VISIBILITY 269 int __libcpp_tls_set(__libcpp_tls_key __key, void *__p); 270 271 #if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ 272 defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) && \ 273 defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 274 275 int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) 276 { 277 pthread_mutexattr_t attr; 278 int __ec = pthread_mutexattr_init(&attr); 279 if (__ec) 280 return __ec; 281 __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 282 if (__ec) { 283 pthread_mutexattr_destroy(&attr); 284 return __ec; 285 } 286 __ec = pthread_mutex_init(__m, &attr); 287 if (__ec) { 288 pthread_mutexattr_destroy(&attr); 289 return __ec; 290 } 291 __ec = pthread_mutexattr_destroy(&attr); 292 if (__ec) { 293 pthread_mutex_destroy(__m); 294 return __ec; 295 } 296 return 0; 297 } 298 299 int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m) 300 { 301 return pthread_mutex_lock(__m); 302 } 303 304 bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m) 305 { 306 return pthread_mutex_trylock(__m) == 0; 307 } 308 309 int __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m) 310 { 311 return pthread_mutex_unlock(__m); 312 } 313 314 int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m) 315 { 316 return pthread_mutex_destroy(__m); 317 } 318 319 int __libcpp_mutex_lock(__libcpp_mutex_t *__m) 320 { 321 return pthread_mutex_lock(__m); 322 } 323 324 bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m) 325 { 326 return pthread_mutex_trylock(__m) == 0; 327 } 328 329 int __libcpp_mutex_unlock(__libcpp_mutex_t *__m) 330 { 331 return pthread_mutex_unlock(__m); 332 } 333 334 int __libcpp_mutex_destroy(__libcpp_mutex_t *__m) 335 { 336 return pthread_mutex_destroy(__m); 337 } 338 339 // Condition Variable 340 int __libcpp_condvar_signal(__libcpp_condvar_t *__cv) 341 { 342 return pthread_cond_signal(__cv); 343 } 344 345 int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv) 346 { 347 return pthread_cond_broadcast(__cv); 348 } 349 350 int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m) 351 { 352 return pthread_cond_wait(__cv, __m); 353 } 354 355 int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 356 timespec *__ts) 357 { 358 return pthread_cond_timedwait(__cv, __m, __ts); 359 } 360 361 int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) 362 { 363 return pthread_cond_destroy(__cv); 364 } 365 366 // Execute once 367 int __libcpp_execute_once(__libcpp_exec_once_flag *flag, 368 void (*init_routine)(void)) { 369 return pthread_once(flag, init_routine); 370 } 371 372 // Thread id 373 // Returns non-zero if the thread ids are equal, otherwise 0 374 bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) 375 { 376 return pthread_equal(t1, t2) != 0; 377 } 378 379 // Returns non-zero if t1 < t2, otherwise 0 380 bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) 381 { 382 return t1 < t2; 383 } 384 385 // Thread 386 bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) { 387 return *__t == 0; 388 } 389 390 int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 391 void *__arg) 392 { 393 return pthread_create(__t, 0, __func, __arg); 394 } 395 396 __libcpp_thread_id __libcpp_thread_get_current_id() 397 { 398 return pthread_self(); 399 } 400 401 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) 402 { 403 return *__t; 404 } 405 406 int __libcpp_thread_join(__libcpp_thread_t *__t) 407 { 408 return pthread_join(*__t, 0); 409 } 410 411 int __libcpp_thread_detach(__libcpp_thread_t *__t) 412 { 413 return pthread_detach(*__t); 414 } 415 416 void __libcpp_thread_yield() 417 { 418 sched_yield(); 419 } 420 421 void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) 422 { 423 using namespace chrono; 424 seconds __s = duration_cast<seconds>(__ns); 425 timespec __ts; 426 typedef decltype(__ts.tv_sec) ts_sec; 427 _LIBCPP_CONSTEXPR ts_sec __ts_sec_max = numeric_limits<ts_sec>::max(); 428 429 if (__s.count() < __ts_sec_max) 430 { 431 __ts.tv_sec = static_cast<ts_sec>(__s.count()); 432 __ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count()); 433 } 434 else 435 { 436 __ts.tv_sec = __ts_sec_max; 437 __ts.tv_nsec = 999999999; // (10^9 - 1) 438 } 439 440 while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR); 441 } 442 443 // Thread local storage 444 int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *)) 445 { 446 return pthread_key_create(__key, __at_exit); 447 } 448 449 void *__libcpp_tls_get(__libcpp_tls_key __key) 450 { 451 return pthread_getspecific(__key); 452 } 453 454 int __libcpp_tls_set(__libcpp_tls_key __key, void *__p) 455 { 456 return pthread_setspecific(__key, __p); 457 } 458 459 #endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL 460 461 _LIBCPP_END_NAMESPACE_STD 462 463 _LIBCPP_POP_MACROS 464 465 #endif // !_LIBCPP_HAS_NO_THREADS 466 467 #endif // _LIBCPP_THREADING_SUPPORT