libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

__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