__threading_support 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. // -*- C++ -*-
  2. //===----------------------------------------------------------------------===//
  3. //
  4. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5. // See https://llvm.org/LICENSE.txt for license information.
  6. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef _LIBCPP___THREADING_SUPPORT
  10. #define _LIBCPP___THREADING_SUPPORT
  11. #include <__availability>
  12. #include <__chrono/convert_to_timespec.h>
  13. #include <__chrono/duration.h>
  14. #include <__compare/ordering.h>
  15. #include <__config>
  16. #include <__fwd/hash.h>
  17. #include <__thread/poll_with_backoff.h>
  18. #include <errno.h>
  19. #include <iosfwd>
  20. #include <limits>
  21. #ifdef __MVS__
  22. # include <__support/ibm/nanosleep.h>
  23. #endif
  24. #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
  25. # pragma GCC system_header
  26. #endif
  27. #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
  28. #error #include <__external_threading>
  29. #elif !defined(_LIBCPP_HAS_NO_THREADS)
  30. #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
  31. # include <pthread.h>
  32. # include <sched.h>
  33. #elif defined(_LIBCPP_HAS_THREAD_API_C11)
  34. # include <threads.h>
  35. #endif
  36. #if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
  37. defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \
  38. defined(_LIBCPP_HAS_THREAD_API_WIN32)
  39. #define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
  40. #else
  41. #define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
  42. #endif
  43. #if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis)
  44. #define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
  45. #else
  46. #define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
  47. #endif
  48. typedef ::timespec __libcpp_timespec_t;
  49. #endif // !defined(_LIBCPP_HAS_NO_THREADS)
  50. _LIBCPP_BEGIN_NAMESPACE_STD
  51. #if !defined(_LIBCPP_HAS_NO_THREADS)
  52. #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
  53. // Mutex
  54. typedef pthread_mutex_t __libcpp_mutex_t;
  55. #define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
  56. typedef pthread_mutex_t __libcpp_recursive_mutex_t;
  57. // Condition Variable
  58. typedef pthread_cond_t __libcpp_condvar_t;
  59. #define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
  60. // Execute once
  61. typedef pthread_once_t __libcpp_exec_once_flag;
  62. #define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
  63. // Thread id
  64. #if defined(__MVS__)
  65. typedef unsigned long long __libcpp_thread_id;
  66. #else
  67. typedef pthread_t __libcpp_thread_id;
  68. #endif
  69. // Thread
  70. #define _LIBCPP_NULL_THREAD ((__libcpp_thread_t()))
  71. typedef pthread_t __libcpp_thread_t;
  72. // Thread Local Storage
  73. typedef pthread_key_t __libcpp_tls_key;
  74. #define _LIBCPP_TLS_DESTRUCTOR_CC
  75. #elif defined(_LIBCPP_HAS_THREAD_API_C11)
  76. // Mutex
  77. typedef mtx_t __libcpp_mutex_t;
  78. // mtx_t is a struct so using {} for initialization is valid.
  79. #define _LIBCPP_MUTEX_INITIALIZER {}
  80. typedef mtx_t __libcpp_recursive_mutex_t;
  81. // Condition Variable
  82. typedef cnd_t __libcpp_condvar_t;
  83. // cnd_t is a struct so using {} for initialization is valid.
  84. #define _LIBCPP_CONDVAR_INITIALIZER {}
  85. // Execute once
  86. typedef once_flag __libcpp_exec_once_flag;
  87. #define _LIBCPP_EXEC_ONCE_INITIALIZER ONCE_FLAG_INIT
  88. // Thread id
  89. typedef thrd_t __libcpp_thread_id;
  90. // Thread
  91. #define _LIBCPP_NULL_THREAD 0U
  92. typedef thrd_t __libcpp_thread_t;
  93. // Thread Local Storage
  94. typedef tss_t __libcpp_tls_key;
  95. #define _LIBCPP_TLS_DESTRUCTOR_CC
  96. #elif !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
  97. // Mutex
  98. typedef void* __libcpp_mutex_t;
  99. #define _LIBCPP_MUTEX_INITIALIZER 0
  100. #if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__)
  101. typedef void* __libcpp_recursive_mutex_t[6];
  102. #elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__)
  103. typedef void* __libcpp_recursive_mutex_t[5];
  104. #else
  105. # error Unsupported architecture
  106. #endif
  107. // Condition Variable
  108. typedef void* __libcpp_condvar_t;
  109. #define _LIBCPP_CONDVAR_INITIALIZER 0
  110. // Execute Once
  111. typedef void* __libcpp_exec_once_flag;
  112. #define _LIBCPP_EXEC_ONCE_INITIALIZER 0
  113. // Thread ID
  114. typedef long __libcpp_thread_id;
  115. // Thread
  116. #define _LIBCPP_NULL_THREAD 0U
  117. typedef void* __libcpp_thread_t;
  118. // Thread Local Storage
  119. typedef long __libcpp_tls_key;
  120. #define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall
  121. #endif // !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
  122. #if !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
  123. // Mutex
  124. _LIBCPP_THREAD_ABI_VISIBILITY
  125. int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
  126. _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
  127. int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
  128. _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
  129. bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
  130. _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
  131. int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
  132. _LIBCPP_THREAD_ABI_VISIBILITY
  133. int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
  134. _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
  135. int __libcpp_mutex_lock(__libcpp_mutex_t *__m);
  136. _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
  137. bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
  138. _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
  139. int __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
  140. _LIBCPP_THREAD_ABI_VISIBILITY
  141. int __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
  142. // Condition variable
  143. _LIBCPP_THREAD_ABI_VISIBILITY
  144. int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
  145. _LIBCPP_THREAD_ABI_VISIBILITY
  146. int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
  147. _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
  148. int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
  149. _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
  150. int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
  151. __libcpp_timespec_t *__ts);
  152. _LIBCPP_THREAD_ABI_VISIBILITY
  153. int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
  154. // Execute once
  155. _LIBCPP_THREAD_ABI_VISIBILITY
  156. int __libcpp_execute_once(__libcpp_exec_once_flag *__flag,
  157. void (*__init_routine)());
  158. // Thread id
  159. _LIBCPP_THREAD_ABI_VISIBILITY
  160. bool __libcpp_thread_id_equal(__libcpp_thread_id __t1, __libcpp_thread_id __t2);
  161. _LIBCPP_THREAD_ABI_VISIBILITY
  162. bool __libcpp_thread_id_less(__libcpp_thread_id __t1, __libcpp_thread_id __t2);
  163. // Thread
  164. _LIBCPP_THREAD_ABI_VISIBILITY
  165. bool __libcpp_thread_isnull(const __libcpp_thread_t *__t);
  166. _LIBCPP_THREAD_ABI_VISIBILITY
  167. int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
  168. void *__arg);
  169. _LIBCPP_THREAD_ABI_VISIBILITY
  170. __libcpp_thread_id __libcpp_thread_get_current_id();
  171. _LIBCPP_THREAD_ABI_VISIBILITY
  172. __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
  173. _LIBCPP_THREAD_ABI_VISIBILITY
  174. int __libcpp_thread_join(__libcpp_thread_t *__t);
  175. _LIBCPP_THREAD_ABI_VISIBILITY
  176. int __libcpp_thread_detach(__libcpp_thread_t *__t);
  177. _LIBCPP_THREAD_ABI_VISIBILITY
  178. void __libcpp_thread_yield();
  179. _LIBCPP_THREAD_ABI_VISIBILITY
  180. void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns);
  181. // Thread local storage
  182. _LIBCPP_THREAD_ABI_VISIBILITY
  183. int __libcpp_tls_create(__libcpp_tls_key* __key,
  184. void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*));
  185. _LIBCPP_THREAD_ABI_VISIBILITY
  186. void *__libcpp_tls_get(__libcpp_tls_key __key);
  187. _LIBCPP_THREAD_ABI_VISIBILITY
  188. int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
  189. #endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
  190. #if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
  191. defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL))
  192. #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
  193. int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
  194. {
  195. pthread_mutexattr_t attr;
  196. int __ec = pthread_mutexattr_init(&attr);
  197. if (__ec)
  198. return __ec;
  199. __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
  200. if (__ec) {
  201. pthread_mutexattr_destroy(&attr);
  202. return __ec;
  203. }
  204. __ec = pthread_mutex_init(__m, &attr);
  205. if (__ec) {
  206. pthread_mutexattr_destroy(&attr);
  207. return __ec;
  208. }
  209. __ec = pthread_mutexattr_destroy(&attr);
  210. if (__ec) {
  211. pthread_mutex_destroy(__m);
  212. return __ec;
  213. }
  214. return 0;
  215. }
  216. int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
  217. {
  218. return pthread_mutex_lock(__m);
  219. }
  220. bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
  221. {
  222. return pthread_mutex_trylock(__m) == 0;
  223. }
  224. int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
  225. {
  226. return pthread_mutex_unlock(__m);
  227. }
  228. int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
  229. {
  230. return pthread_mutex_destroy(__m);
  231. }
  232. int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
  233. {
  234. return pthread_mutex_lock(__m);
  235. }
  236. bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
  237. {
  238. return pthread_mutex_trylock(__m) == 0;
  239. }
  240. int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
  241. {
  242. return pthread_mutex_unlock(__m);
  243. }
  244. int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
  245. {
  246. return pthread_mutex_destroy(__m);
  247. }
  248. // Condition Variable
  249. int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
  250. {
  251. return pthread_cond_signal(__cv);
  252. }
  253. int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
  254. {
  255. return pthread_cond_broadcast(__cv);
  256. }
  257. int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
  258. {
  259. return pthread_cond_wait(__cv, __m);
  260. }
  261. int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
  262. __libcpp_timespec_t *__ts)
  263. {
  264. return pthread_cond_timedwait(__cv, __m, __ts);
  265. }
  266. int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
  267. {
  268. return pthread_cond_destroy(__cv);
  269. }
  270. // Execute once
  271. int __libcpp_execute_once(__libcpp_exec_once_flag *__flag,
  272. void (*__init_routine)()) {
  273. return pthread_once(__flag, __init_routine);
  274. }
  275. // Thread id
  276. // Returns non-zero if the thread ids are equal, otherwise 0
  277. bool __libcpp_thread_id_equal(__libcpp_thread_id __t1, __libcpp_thread_id __t2)
  278. {
  279. return __t1 == __t2;
  280. }
  281. // Returns non-zero if t1 < t2, otherwise 0
  282. bool __libcpp_thread_id_less(__libcpp_thread_id __t1, __libcpp_thread_id __t2)
  283. {
  284. return __t1 < __t2;
  285. }
  286. // Thread
  287. bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
  288. return __libcpp_thread_get_id(__t) == 0;
  289. }
  290. int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
  291. void *__arg)
  292. {
  293. return pthread_create(__t, nullptr, __func, __arg);
  294. }
  295. __libcpp_thread_id __libcpp_thread_get_current_id()
  296. {
  297. const __libcpp_thread_t thread = pthread_self();
  298. return __libcpp_thread_get_id(&thread);
  299. }
  300. __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
  301. {
  302. #if defined(__MVS__)
  303. return __t->__;
  304. #else
  305. return *__t;
  306. #endif
  307. }
  308. int __libcpp_thread_join(__libcpp_thread_t *__t)
  309. {
  310. return pthread_join(*__t, nullptr);
  311. }
  312. int __libcpp_thread_detach(__libcpp_thread_t *__t)
  313. {
  314. return pthread_detach(*__t);
  315. }
  316. void __libcpp_thread_yield()
  317. {
  318. sched_yield();
  319. }
  320. void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
  321. {
  322. __libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns);
  323. while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR);
  324. }
  325. // Thread local storage
  326. int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
  327. {
  328. return pthread_key_create(__key, __at_exit);
  329. }
  330. void *__libcpp_tls_get(__libcpp_tls_key __key)
  331. {
  332. return pthread_getspecific(__key);
  333. }
  334. int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
  335. {
  336. return pthread_setspecific(__key, __p);
  337. }
  338. #elif defined(_LIBCPP_HAS_THREAD_API_C11)
  339. int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
  340. {
  341. return mtx_init(__m, mtx_plain | mtx_recursive) == thrd_success ? 0 : EINVAL;
  342. }
  343. int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
  344. {
  345. return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
  346. }
  347. bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
  348. {
  349. return mtx_trylock(__m) == thrd_success;
  350. }
  351. int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
  352. {
  353. return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
  354. }
  355. int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
  356. {
  357. mtx_destroy(__m);
  358. return 0;
  359. }
  360. int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
  361. {
  362. return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
  363. }
  364. bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
  365. {
  366. return mtx_trylock(__m) == thrd_success;
  367. }
  368. int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
  369. {
  370. return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
  371. }
  372. int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
  373. {
  374. mtx_destroy(__m);
  375. return 0;
  376. }
  377. // Condition Variable
  378. int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
  379. {
  380. return cnd_signal(__cv) == thrd_success ? 0 : EINVAL;
  381. }
  382. int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
  383. {
  384. return cnd_broadcast(__cv) == thrd_success ? 0 : EINVAL;
  385. }
  386. int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
  387. {
  388. return cnd_wait(__cv, __m) == thrd_success ? 0 : EINVAL;
  389. }
  390. int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
  391. timespec *__ts)
  392. {
  393. int __ec = cnd_timedwait(__cv, __m, __ts);
  394. return __ec == thrd_timedout ? ETIMEDOUT : __ec;
  395. }
  396. int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
  397. {
  398. cnd_destroy(__cv);
  399. return 0;
  400. }
  401. // Execute once
  402. int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
  403. void (*init_routine)(void)) {
  404. ::call_once(flag, init_routine);
  405. return 0;
  406. }
  407. // Thread id
  408. // Returns non-zero if the thread ids are equal, otherwise 0
  409. bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
  410. {
  411. return thrd_equal(t1, t2) != 0;
  412. }
  413. // Returns non-zero if t1 < t2, otherwise 0
  414. bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
  415. {
  416. return t1 < t2;
  417. }
  418. // Thread
  419. bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
  420. return __libcpp_thread_get_id(__t) == 0;
  421. }
  422. int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
  423. void *__arg)
  424. {
  425. int __ec = thrd_create(__t, reinterpret_cast<thrd_start_t>(__func), __arg);
  426. return __ec == thrd_nomem ? ENOMEM : __ec;
  427. }
  428. __libcpp_thread_id __libcpp_thread_get_current_id()
  429. {
  430. return thrd_current();
  431. }
  432. __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
  433. {
  434. return *__t;
  435. }
  436. int __libcpp_thread_join(__libcpp_thread_t *__t)
  437. {
  438. return thrd_join(*__t, nullptr) == thrd_success ? 0 : EINVAL;
  439. }
  440. int __libcpp_thread_detach(__libcpp_thread_t *__t)
  441. {
  442. return thrd_detach(*__t) == thrd_success ? 0 : EINVAL;
  443. }
  444. void __libcpp_thread_yield()
  445. {
  446. thrd_yield();
  447. }
  448. void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
  449. {
  450. __libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns);
  451. thrd_sleep(&__ts, nullptr);
  452. }
  453. // Thread local storage
  454. int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
  455. {
  456. return tss_create(__key, __at_exit) == thrd_success ? 0 : EINVAL;
  457. }
  458. void *__libcpp_tls_get(__libcpp_tls_key __key)
  459. {
  460. return tss_get(__key);
  461. }
  462. int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
  463. {
  464. return tss_set(__key, __p) == thrd_success ? 0 : EINVAL;
  465. }
  466. #endif
  467. #endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
  468. class _LIBCPP_TYPE_VIS thread;
  469. class _LIBCPP_TYPE_VIS __thread_id;
  470. namespace this_thread
  471. {
  472. _LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT;
  473. } // namespace this_thread
  474. template<> struct hash<__thread_id>;
  475. class _LIBCPP_TEMPLATE_VIS __thread_id
  476. {
  477. // FIXME: pthread_t is a pointer on Darwin but a long on Linux.
  478. // NULL is the no-thread value on Darwin. Someone needs to check
  479. // on other platforms. We assume 0 works everywhere for now.
  480. __libcpp_thread_id __id_;
  481. static _LIBCPP_HIDE_FROM_ABI
  482. bool __lt_impl(__thread_id __x, __thread_id __y) _NOEXCEPT
  483. { // id==0 is always less than any other thread_id
  484. if (__x.__id_ == 0) return __y.__id_ != 0;
  485. if (__y.__id_ == 0) return false;
  486. return __libcpp_thread_id_less(__x.__id_, __y.__id_);
  487. }
  488. public:
  489. _LIBCPP_INLINE_VISIBILITY
  490. __thread_id() _NOEXCEPT : __id_(0) {}
  491. _LIBCPP_INLINE_VISIBILITY
  492. void __reset() { __id_ = 0; }
  493. friend _LIBCPP_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT;
  494. #if _LIBCPP_STD_VER <= 17
  495. friend _LIBCPP_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT;
  496. #else // _LIBCPP_STD_VER <= 17
  497. friend _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept;
  498. #endif // _LIBCPP_STD_VER <= 17
  499. template<class _CharT, class _Traits>
  500. friend
  501. _LIBCPP_INLINE_VISIBILITY
  502. basic_ostream<_CharT, _Traits>&
  503. operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id);
  504. private:
  505. _LIBCPP_INLINE_VISIBILITY
  506. __thread_id(__libcpp_thread_id __id) : __id_(__id) {}
  507. friend __thread_id this_thread::get_id() _NOEXCEPT;
  508. friend class _LIBCPP_TYPE_VIS thread;
  509. friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>;
  510. };
  511. inline _LIBCPP_HIDE_FROM_ABI
  512. bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT {
  513. // Don't pass id==0 to underlying routines
  514. if (__x.__id_ == 0)
  515. return __y.__id_ == 0;
  516. if (__y.__id_ == 0)
  517. return false;
  518. return __libcpp_thread_id_equal(__x.__id_, __y.__id_);
  519. }
  520. #if _LIBCPP_STD_VER <= 17
  521. inline _LIBCPP_HIDE_FROM_ABI
  522. bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT {
  523. return !(__x == __y);
  524. }
  525. inline _LIBCPP_HIDE_FROM_ABI
  526. bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT {
  527. return __thread_id::__lt_impl(__x.__id_, __y.__id_);
  528. }
  529. inline _LIBCPP_HIDE_FROM_ABI bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__y < __x); }
  530. inline _LIBCPP_HIDE_FROM_ABI bool operator>(__thread_id __x, __thread_id __y) _NOEXCEPT { return __y < __x; }
  531. inline _LIBCPP_HIDE_FROM_ABI bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x < __y); }
  532. #else // _LIBCPP_STD_VER <= 17
  533. inline _LIBCPP_HIDE_FROM_ABI
  534. strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept {
  535. if (__x == __y)
  536. return strong_ordering::equal;
  537. if (__thread_id::__lt_impl(__x, __y))
  538. return strong_ordering::less;
  539. return strong_ordering::greater;
  540. }
  541. #endif // _LIBCPP_STD_VER <= 17
  542. namespace this_thread
  543. {
  544. inline _LIBCPP_INLINE_VISIBILITY
  545. __thread_id
  546. get_id() _NOEXCEPT
  547. {
  548. return __libcpp_thread_get_current_id();
  549. }
  550. } // namespace this_thread
  551. #endif // !_LIBCPP_HAS_NO_THREADS
  552. _LIBCPP_END_NAMESPACE_STD
  553. #endif // _LIBCPP___THREADING_SUPPORT