atomic 97 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673
  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_ATOMIC
  10. #define _LIBCPP_ATOMIC
  11. /*
  12. atomic synopsis
  13. namespace std
  14. {
  15. // feature test macro [version.syn]
  16. #define __cpp_lib_atomic_is_always_lock_free
  17. #define __cpp_lib_atomic_flag_test
  18. #define __cpp_lib_atomic_lock_free_type_aliases
  19. #define __cpp_lib_atomic_wait
  20. // order and consistency
  21. enum memory_order: unspecified // enum class in C++20
  22. {
  23. relaxed,
  24. consume, // load-consume
  25. acquire, // load-acquire
  26. release, // store-release
  27. acq_rel, // store-release load-acquire
  28. seq_cst // store-release load-acquire
  29. };
  30. inline constexpr auto memory_order_relaxed = memory_order::relaxed;
  31. inline constexpr auto memory_order_consume = memory_order::consume;
  32. inline constexpr auto memory_order_acquire = memory_order::acquire;
  33. inline constexpr auto memory_order_release = memory_order::release;
  34. inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
  35. inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
  36. template <class T> T kill_dependency(T y) noexcept;
  37. // lock-free property
  38. #define ATOMIC_BOOL_LOCK_FREE unspecified
  39. #define ATOMIC_CHAR_LOCK_FREE unspecified
  40. #define ATOMIC_CHAR8_T_LOCK_FREE unspecified // C++20
  41. #define ATOMIC_CHAR16_T_LOCK_FREE unspecified
  42. #define ATOMIC_CHAR32_T_LOCK_FREE unspecified
  43. #define ATOMIC_WCHAR_T_LOCK_FREE unspecified
  44. #define ATOMIC_SHORT_LOCK_FREE unspecified
  45. #define ATOMIC_INT_LOCK_FREE unspecified
  46. #define ATOMIC_LONG_LOCK_FREE unspecified
  47. #define ATOMIC_LLONG_LOCK_FREE unspecified
  48. #define ATOMIC_POINTER_LOCK_FREE unspecified
  49. template <class T>
  50. struct atomic
  51. {
  52. using value_type = T;
  53. static constexpr bool is_always_lock_free;
  54. bool is_lock_free() const volatile noexcept;
  55. bool is_lock_free() const noexcept;
  56. atomic() noexcept = default; // until C++20
  57. constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>); // since C++20
  58. constexpr atomic(T desr) noexcept;
  59. atomic(const atomic&) = delete;
  60. atomic& operator=(const atomic&) = delete;
  61. atomic& operator=(const atomic&) volatile = delete;
  62. T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
  63. T load(memory_order m = memory_order_seq_cst) const noexcept;
  64. operator T() const volatile noexcept;
  65. operator T() const noexcept;
  66. void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
  67. void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
  68. T operator=(T) volatile noexcept;
  69. T operator=(T) noexcept;
  70. T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
  71. T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
  72. bool compare_exchange_weak(T& expc, T desr,
  73. memory_order s, memory_order f) volatile noexcept;
  74. bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
  75. bool compare_exchange_strong(T& expc, T desr,
  76. memory_order s, memory_order f) volatile noexcept;
  77. bool compare_exchange_strong(T& expc, T desr,
  78. memory_order s, memory_order f) noexcept;
  79. bool compare_exchange_weak(T& expc, T desr,
  80. memory_order m = memory_order_seq_cst) volatile noexcept;
  81. bool compare_exchange_weak(T& expc, T desr,
  82. memory_order m = memory_order_seq_cst) noexcept;
  83. bool compare_exchange_strong(T& expc, T desr,
  84. memory_order m = memory_order_seq_cst) volatile noexcept;
  85. bool compare_exchange_strong(T& expc, T desr,
  86. memory_order m = memory_order_seq_cst) noexcept;
  87. void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept;
  88. void wait(T, memory_order = memory_order::seq_cst) const noexcept;
  89. void notify_one() volatile noexcept;
  90. void notify_one() noexcept;
  91. void notify_all() volatile noexcept;
  92. void notify_all() noexcept;
  93. };
  94. template <>
  95. struct atomic<integral>
  96. {
  97. using value_type = integral;
  98. using difference_type = value_type;
  99. static constexpr bool is_always_lock_free;
  100. bool is_lock_free() const volatile noexcept;
  101. bool is_lock_free() const noexcept;
  102. atomic() noexcept = default;
  103. constexpr atomic(integral desr) noexcept;
  104. atomic(const atomic&) = delete;
  105. atomic& operator=(const atomic&) = delete;
  106. atomic& operator=(const atomic&) volatile = delete;
  107. integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
  108. integral load(memory_order m = memory_order_seq_cst) const noexcept;
  109. operator integral() const volatile noexcept;
  110. operator integral() const noexcept;
  111. void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
  112. void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
  113. integral operator=(integral desr) volatile noexcept;
  114. integral operator=(integral desr) noexcept;
  115. integral exchange(integral desr,
  116. memory_order m = memory_order_seq_cst) volatile noexcept;
  117. integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
  118. bool compare_exchange_weak(integral& expc, integral desr,
  119. memory_order s, memory_order f) volatile noexcept;
  120. bool compare_exchange_weak(integral& expc, integral desr,
  121. memory_order s, memory_order f) noexcept;
  122. bool compare_exchange_strong(integral& expc, integral desr,
  123. memory_order s, memory_order f) volatile noexcept;
  124. bool compare_exchange_strong(integral& expc, integral desr,
  125. memory_order s, memory_order f) noexcept;
  126. bool compare_exchange_weak(integral& expc, integral desr,
  127. memory_order m = memory_order_seq_cst) volatile noexcept;
  128. bool compare_exchange_weak(integral& expc, integral desr,
  129. memory_order m = memory_order_seq_cst) noexcept;
  130. bool compare_exchange_strong(integral& expc, integral desr,
  131. memory_order m = memory_order_seq_cst) volatile noexcept;
  132. bool compare_exchange_strong(integral& expc, integral desr,
  133. memory_order m = memory_order_seq_cst) noexcept;
  134. integral fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
  135. integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
  136. integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
  137. integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
  138. integral fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
  139. integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
  140. integral fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
  141. integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
  142. integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
  143. integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
  144. integral operator++(int) volatile noexcept;
  145. integral operator++(int) noexcept;
  146. integral operator--(int) volatile noexcept;
  147. integral operator--(int) noexcept;
  148. integral operator++() volatile noexcept;
  149. integral operator++() noexcept;
  150. integral operator--() volatile noexcept;
  151. integral operator--() noexcept;
  152. integral operator+=(integral op) volatile noexcept;
  153. integral operator+=(integral op) noexcept;
  154. integral operator-=(integral op) volatile noexcept;
  155. integral operator-=(integral op) noexcept;
  156. integral operator&=(integral op) volatile noexcept;
  157. integral operator&=(integral op) noexcept;
  158. integral operator|=(integral op) volatile noexcept;
  159. integral operator|=(integral op) noexcept;
  160. integral operator^=(integral op) volatile noexcept;
  161. integral operator^=(integral op) noexcept;
  162. void wait(integral, memory_order = memory_order::seq_cst) const volatile noexcept;
  163. void wait(integral, memory_order = memory_order::seq_cst) const noexcept;
  164. void notify_one() volatile noexcept;
  165. void notify_one() noexcept;
  166. void notify_all() volatile noexcept;
  167. void notify_all() noexcept;
  168. };
  169. template <class T>
  170. struct atomic<T*>
  171. {
  172. using value_type = T*;
  173. using difference_type = ptrdiff_t;
  174. static constexpr bool is_always_lock_free;
  175. bool is_lock_free() const volatile noexcept;
  176. bool is_lock_free() const noexcept;
  177. atomic() noexcept = default; // until C++20
  178. constexpr atomic() noexcept; // since C++20
  179. constexpr atomic(T* desr) noexcept;
  180. atomic(const atomic&) = delete;
  181. atomic& operator=(const atomic&) = delete;
  182. atomic& operator=(const atomic&) volatile = delete;
  183. T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
  184. T* load(memory_order m = memory_order_seq_cst) const noexcept;
  185. operator T*() const volatile noexcept;
  186. operator T*() const noexcept;
  187. void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
  188. void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
  189. T* operator=(T*) volatile noexcept;
  190. T* operator=(T*) noexcept;
  191. T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
  192. T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
  193. bool compare_exchange_weak(T*& expc, T* desr,
  194. memory_order s, memory_order f) volatile noexcept;
  195. bool compare_exchange_weak(T*& expc, T* desr,
  196. memory_order s, memory_order f) noexcept;
  197. bool compare_exchange_strong(T*& expc, T* desr,
  198. memory_order s, memory_order f) volatile noexcept;
  199. bool compare_exchange_strong(T*& expc, T* desr,
  200. memory_order s, memory_order f) noexcept;
  201. bool compare_exchange_weak(T*& expc, T* desr,
  202. memory_order m = memory_order_seq_cst) volatile noexcept;
  203. bool compare_exchange_weak(T*& expc, T* desr,
  204. memory_order m = memory_order_seq_cst) noexcept;
  205. bool compare_exchange_strong(T*& expc, T* desr,
  206. memory_order m = memory_order_seq_cst) volatile noexcept;
  207. bool compare_exchange_strong(T*& expc, T* desr,
  208. memory_order m = memory_order_seq_cst) noexcept;
  209. T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
  210. T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
  211. T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
  212. T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
  213. T* operator++(int) volatile noexcept;
  214. T* operator++(int) noexcept;
  215. T* operator--(int) volatile noexcept;
  216. T* operator--(int) noexcept;
  217. T* operator++() volatile noexcept;
  218. T* operator++() noexcept;
  219. T* operator--() volatile noexcept;
  220. T* operator--() noexcept;
  221. T* operator+=(ptrdiff_t op) volatile noexcept;
  222. T* operator+=(ptrdiff_t op) noexcept;
  223. T* operator-=(ptrdiff_t op) volatile noexcept;
  224. T* operator-=(ptrdiff_t op) noexcept;
  225. void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept;
  226. void wait(T*, memory_order = memory_order::seq_cst) const noexcept;
  227. void notify_one() volatile noexcept;
  228. void notify_one() noexcept;
  229. void notify_all() volatile noexcept;
  230. void notify_all() noexcept;
  231. };
  232. // [atomics.nonmembers], non-member functions
  233. template<class T>
  234. bool atomic_is_lock_free(const volatile atomic<T>*) noexcept;
  235. template<class T>
  236. bool atomic_is_lock_free(const atomic<T>*) noexcept;
  237. template<class T>
  238. void atomic_store(volatile atomic<T>*, atomic<T>::value_type) noexcept;
  239. template<class T>
  240. void atomic_store(atomic<T>*, atomic<T>::value_type) noexcept;
  241. template<class T>
  242. void atomic_store_explicit(volatile atomic<T>*, atomic<T>::value_type,
  243. memory_order) noexcept;
  244. template<class T>
  245. void atomic_store_explicit(atomic<T>*, atomic<T>::value_type,
  246. memory_order) noexcept;
  247. template<class T>
  248. T atomic_load(const volatile atomic<T>*) noexcept;
  249. template<class T>
  250. T atomic_load(const atomic<T>*) noexcept;
  251. template<class T>
  252. T atomic_load_explicit(const volatile atomic<T>*, memory_order) noexcept;
  253. template<class T>
  254. T atomic_load_explicit(const atomic<T>*, memory_order) noexcept;
  255. template<class T>
  256. T atomic_exchange(volatile atomic<T>*, atomic<T>::value_type) noexcept;
  257. template<class T>
  258. T atomic_exchange(atomic<T>*, atomic<T>::value_type) noexcept;
  259. template<class T>
  260. T atomic_exchange_explicit(volatile atomic<T>*, atomic<T>::value_type,
  261. memory_order) noexcept;
  262. template<class T>
  263. T atomic_exchange_explicit(atomic<T>*, atomic<T>::value_type,
  264. memory_order) noexcept;
  265. template<class T>
  266. bool atomic_compare_exchange_weak(volatile atomic<T>*, atomic<T>::value_type*,
  267. atomic<T>::value_type) noexcept;
  268. template<class T>
  269. bool atomic_compare_exchange_weak(atomic<T>*, atomic<T>::value_type*,
  270. atomic<T>::value_type) noexcept;
  271. template<class T>
  272. bool atomic_compare_exchange_strong(volatile atomic<T>*, atomic<T>::value_type*,
  273. atomic<T>::value_type) noexcept;
  274. template<class T>
  275. bool atomic_compare_exchange_strong(atomic<T>*, atomic<T>::value_type*,
  276. atomic<T>::value_type) noexcept;
  277. template<class T>
  278. bool atomic_compare_exchange_weak_explicit(volatile atomic<T>*, atomic<T>::value_type*,
  279. atomic<T>::value_type,
  280. memory_order, memory_order) noexcept;
  281. template<class T>
  282. bool atomic_compare_exchange_weak_explicit(atomic<T>*, atomic<T>::value_type*,
  283. atomic<T>::value_type,
  284. memory_order, memory_order) noexcept;
  285. template<class T>
  286. bool atomic_compare_exchange_strong_explicit(volatile atomic<T>*, atomic<T>::value_type*,
  287. atomic<T>::value_type,
  288. memory_order, memory_order) noexcept;
  289. template<class T>
  290. bool atomic_compare_exchange_strong_explicit(atomic<T>*, atomic<T>::value_type*,
  291. atomic<T>::value_type,
  292. memory_order, memory_order) noexcept;
  293. template<class T>
  294. T atomic_fetch_add(volatile atomic<T>*, atomic<T>::difference_type) noexcept;
  295. template<class T>
  296. T atomic_fetch_add(atomic<T>*, atomic<T>::difference_type) noexcept;
  297. template<class T>
  298. T atomic_fetch_add_explicit(volatile atomic<T>*, atomic<T>::difference_type,
  299. memory_order) noexcept;
  300. template<class T>
  301. T atomic_fetch_add_explicit(atomic<T>*, atomic<T>::difference_type,
  302. memory_order) noexcept;
  303. template<class T>
  304. T atomic_fetch_sub(volatile atomic<T>*, atomic<T>::difference_type) noexcept;
  305. template<class T>
  306. T atomic_fetch_sub(atomic<T>*, atomic<T>::difference_type) noexcept;
  307. template<class T>
  308. T atomic_fetch_sub_explicit(volatile atomic<T>*, atomic<T>::difference_type,
  309. memory_order) noexcept;
  310. template<class T>
  311. T atomic_fetch_sub_explicit(atomic<T>*, atomic<T>::difference_type,
  312. memory_order) noexcept;
  313. template<class T>
  314. T atomic_fetch_and(volatile atomic<T>*, atomic<T>::value_type) noexcept;
  315. template<class T>
  316. T atomic_fetch_and(atomic<T>*, atomic<T>::value_type) noexcept;
  317. template<class T>
  318. T atomic_fetch_and_explicit(volatile atomic<T>*, atomic<T>::value_type,
  319. memory_order) noexcept;
  320. template<class T>
  321. T atomic_fetch_and_explicit(atomic<T>*, atomic<T>::value_type,
  322. memory_order) noexcept;
  323. template<class T>
  324. T atomic_fetch_or(volatile atomic<T>*, atomic<T>::value_type) noexcept;
  325. template<class T>
  326. T atomic_fetch_or(atomic<T>*, atomic<T>::value_type) noexcept;
  327. template<class T>
  328. T atomic_fetch_or_explicit(volatile atomic<T>*, atomic<T>::value_type,
  329. memory_order) noexcept;
  330. template<class T>
  331. T atomic_fetch_or_explicit(atomic<T>*, atomic<T>::value_type,
  332. memory_order) noexcept;
  333. template<class T>
  334. T atomic_fetch_xor(volatile atomic<T>*, atomic<T>::value_type) noexcept;
  335. template<class T>
  336. T atomic_fetch_xor(atomic<T>*, atomic<T>::value_type) noexcept;
  337. template<class T>
  338. T atomic_fetch_xor_explicit(volatile atomic<T>*, atomic<T>::value_type,
  339. memory_order) noexcept;
  340. template<class T>
  341. T atomic_fetch_xor_explicit(atomic<T>*, atomic<T>::value_type,
  342. memory_order) noexcept;
  343. template<class T>
  344. void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type) noexcept;
  345. template<class T>
  346. void atomic_wait(const atomic<T>*, atomic<T>::value_type) noexcept;
  347. template<class T>
  348. void atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type,
  349. memory_order) noexcept;
  350. template<class T>
  351. void atomic_wait_explicit(const atomic<T>*, atomic<T>::value_type,
  352. memory_order) noexcept;
  353. template<class T>
  354. void atomic_notify_one(volatile atomic<T>*) noexcept;
  355. template<class T>
  356. void atomic_notify_one(atomic<T>*) noexcept;
  357. template<class T>
  358. void atomic_notify_all(volatile atomic<T>*) noexcept;
  359. template<class T>
  360. void atomic_notify_all(atomic<T>*) noexcept;
  361. // Atomics for standard typedef types
  362. typedef atomic<bool> atomic_bool;
  363. typedef atomic<char> atomic_char;
  364. typedef atomic<signed char> atomic_schar;
  365. typedef atomic<unsigned char> atomic_uchar;
  366. typedef atomic<short> atomic_short;
  367. typedef atomic<unsigned short> atomic_ushort;
  368. typedef atomic<int> atomic_int;
  369. typedef atomic<unsigned int> atomic_uint;
  370. typedef atomic<long> atomic_long;
  371. typedef atomic<unsigned long> atomic_ulong;
  372. typedef atomic<long long> atomic_llong;
  373. typedef atomic<unsigned long long> atomic_ullong;
  374. typedef atomic<char8_t> atomic_char8_t; // C++20
  375. typedef atomic<char16_t> atomic_char16_t;
  376. typedef atomic<char32_t> atomic_char32_t;
  377. typedef atomic<wchar_t> atomic_wchar_t;
  378. typedef atomic<int_least8_t> atomic_int_least8_t;
  379. typedef atomic<uint_least8_t> atomic_uint_least8_t;
  380. typedef atomic<int_least16_t> atomic_int_least16_t;
  381. typedef atomic<uint_least16_t> atomic_uint_least16_t;
  382. typedef atomic<int_least32_t> atomic_int_least32_t;
  383. typedef atomic<uint_least32_t> atomic_uint_least32_t;
  384. typedef atomic<int_least64_t> atomic_int_least64_t;
  385. typedef atomic<uint_least64_t> atomic_uint_least64_t;
  386. typedef atomic<int_fast8_t> atomic_int_fast8_t;
  387. typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
  388. typedef atomic<int_fast16_t> atomic_int_fast16_t;
  389. typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
  390. typedef atomic<int_fast32_t> atomic_int_fast32_t;
  391. typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
  392. typedef atomic<int_fast64_t> atomic_int_fast64_t;
  393. typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
  394. typedef atomic<int8_t> atomic_int8_t;
  395. typedef atomic<uint8_t> atomic_uint8_t;
  396. typedef atomic<int16_t> atomic_int16_t;
  397. typedef atomic<uint16_t> atomic_uint16_t;
  398. typedef atomic<int32_t> atomic_int32_t;
  399. typedef atomic<uint32_t> atomic_uint32_t;
  400. typedef atomic<int64_t> atomic_int64_t;
  401. typedef atomic<uint64_t> atomic_uint64_t;
  402. typedef atomic<intptr_t> atomic_intptr_t;
  403. typedef atomic<uintptr_t> atomic_uintptr_t;
  404. typedef atomic<size_t> atomic_size_t;
  405. typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
  406. typedef atomic<intmax_t> atomic_intmax_t;
  407. typedef atomic<uintmax_t> atomic_uintmax_t;
  408. // flag type and operations
  409. typedef struct atomic_flag
  410. {
  411. atomic_flag() noexcept = default; // until C++20
  412. constexpr atomic_flag() noexcept; // since C++20
  413. atomic_flag(const atomic_flag&) = delete;
  414. atomic_flag& operator=(const atomic_flag&) = delete;
  415. atomic_flag& operator=(const atomic_flag&) volatile = delete;
  416. bool test(memory_order m = memory_order_seq_cst) volatile noexcept;
  417. bool test(memory_order m = memory_order_seq_cst) noexcept;
  418. bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
  419. bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
  420. void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
  421. void clear(memory_order m = memory_order_seq_cst) noexcept;
  422. void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept;
  423. void wait(bool, memory_order = memory_order::seq_cst) const noexcept;
  424. void notify_one() volatile noexcept;
  425. void notify_one() noexcept;
  426. void notify_all() volatile noexcept;
  427. void notify_all() noexcept;
  428. } atomic_flag;
  429. bool atomic_flag_test(volatile atomic_flag* obj) noexcept;
  430. bool atomic_flag_test(atomic_flag* obj) noexcept;
  431. bool atomic_flag_test_explicit(volatile atomic_flag* obj,
  432. memory_order m) noexcept;
  433. bool atomic_flag_test_explicit(atomic_flag* obj, memory_order m) noexcept;
  434. bool atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
  435. bool atomic_flag_test_and_set(atomic_flag* obj) noexcept;
  436. bool atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
  437. memory_order m) noexcept;
  438. bool atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
  439. void atomic_flag_clear(volatile atomic_flag* obj) noexcept;
  440. void atomic_flag_clear(atomic_flag* obj) noexcept;
  441. void atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
  442. void atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
  443. void atomic_wait(const volatile atomic_flag* obj, T old) noexcept;
  444. void atomic_wait(const atomic_flag* obj, T old) noexcept;
  445. void atomic_wait_explicit(const volatile atomic_flag* obj, T old, memory_order m) noexcept;
  446. void atomic_wait_explicit(const atomic_flag* obj, T old, memory_order m) noexcept;
  447. void atomic_one(volatile atomic_flag* obj) noexcept;
  448. void atomic_one(atomic_flag* obj) noexcept;
  449. void atomic_all(volatile atomic_flag* obj) noexcept;
  450. void atomic_all(atomic_flag* obj) noexcept;
  451. // fences
  452. void atomic_thread_fence(memory_order m) noexcept;
  453. void atomic_signal_fence(memory_order m) noexcept;
  454. // deprecated
  455. template <class T>
  456. void atomic_init(volatile atomic<T>* obj, atomic<T>::value_type desr) noexcept;
  457. template <class T>
  458. void atomic_init(atomic<T>* obj, atomic<T>::value_type desr) noexcept;
  459. #define ATOMIC_VAR_INIT(value) see below
  460. #define ATOMIC_FLAG_INIT see below
  461. } // std
  462. */
  463. #include <__assert> // all public C++ headers provide the assertion handler
  464. #include <__availability>
  465. #include <__chrono/duration.h>
  466. #include <__config>
  467. #include <__thread/poll_with_backoff.h>
  468. #include <__thread/timed_backoff_policy.h>
  469. #include <__type_traits/conditional.h>
  470. #include <__type_traits/decay.h>
  471. #include <__type_traits/is_assignable.h>
  472. #include <__type_traits/is_function.h>
  473. #include <__type_traits/is_nothrow_default_constructible.h>
  474. #include <__type_traits/is_same.h>
  475. #include <__type_traits/is_trivially_copyable.h>
  476. #include <__type_traits/remove_const.h>
  477. #include <__type_traits/remove_pointer.h>
  478. #include <__type_traits/underlying_type.h>
  479. #include <cstddef>
  480. #include <cstdint>
  481. #include <cstring>
  482. #include <version>
  483. #ifndef _LIBCPP_HAS_NO_THREADS
  484. # include <__threading_support>
  485. #endif
  486. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  487. # pragma GCC system_header
  488. #endif
  489. #ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
  490. # error <atomic> is not implemented
  491. #endif
  492. #ifdef kill_dependency
  493. # error <atomic> is incompatible with <stdatomic.h> before C++23. Please compile with -std=c++23.
  494. #endif
  495. #define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
  496. _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
  497. __m == memory_order_acquire || \
  498. __m == memory_order_acq_rel, \
  499. "memory order argument to atomic operation is invalid")
  500. #define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
  501. _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
  502. __m == memory_order_acq_rel, \
  503. "memory order argument to atomic operation is invalid")
  504. #define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
  505. _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
  506. __f == memory_order_acq_rel, \
  507. "memory order argument to atomic operation is invalid")
  508. _LIBCPP_BEGIN_NAMESPACE_STD
  509. // Figure out what the underlying type for `memory_order` would be if it were
  510. // declared as an unscoped enum (accounting for -fshort-enums). Use this result
  511. // to pin the underlying type in C++20.
  512. enum __legacy_memory_order {
  513. __mo_relaxed,
  514. __mo_consume,
  515. __mo_acquire,
  516. __mo_release,
  517. __mo_acq_rel,
  518. __mo_seq_cst
  519. };
  520. typedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t;
  521. #if _LIBCPP_STD_VER > 17
  522. enum class memory_order : __memory_order_underlying_t {
  523. relaxed = __mo_relaxed,
  524. consume = __mo_consume,
  525. acquire = __mo_acquire,
  526. release = __mo_release,
  527. acq_rel = __mo_acq_rel,
  528. seq_cst = __mo_seq_cst
  529. };
  530. inline constexpr auto memory_order_relaxed = memory_order::relaxed;
  531. inline constexpr auto memory_order_consume = memory_order::consume;
  532. inline constexpr auto memory_order_acquire = memory_order::acquire;
  533. inline constexpr auto memory_order_release = memory_order::release;
  534. inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
  535. inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
  536. #else
  537. typedef enum memory_order {
  538. memory_order_relaxed = __mo_relaxed,
  539. memory_order_consume = __mo_consume,
  540. memory_order_acquire = __mo_acquire,
  541. memory_order_release = __mo_release,
  542. memory_order_acq_rel = __mo_acq_rel,
  543. memory_order_seq_cst = __mo_seq_cst,
  544. } memory_order;
  545. #endif // _LIBCPP_STD_VER > 17
  546. template <typename _Tp> _LIBCPP_INLINE_VISIBILITY
  547. bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
  548. return _VSTD::memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0;
  549. }
  550. static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
  551. "unexpected underlying type for std::memory_order");
  552. #if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
  553. defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
  554. // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
  555. // the default operator= in an object is not volatile, a byte-by-byte copy
  556. // is required.
  557. template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
  558. typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
  559. __cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
  560. __a_value = __val;
  561. }
  562. template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
  563. typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
  564. __cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
  565. volatile char* __to = reinterpret_cast<volatile char*>(&__a_value);
  566. volatile char* __end = __to + sizeof(_Tp);
  567. volatile const char* __from = reinterpret_cast<volatile const char*>(&__val);
  568. while (__to != __end)
  569. *__to++ = *__from++;
  570. }
  571. #endif
  572. #if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
  573. template <typename _Tp>
  574. struct __cxx_atomic_base_impl {
  575. _LIBCPP_INLINE_VISIBILITY
  576. #ifndef _LIBCPP_CXX03_LANG
  577. __cxx_atomic_base_impl() _NOEXCEPT = default;
  578. #else
  579. __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
  580. #endif // _LIBCPP_CXX03_LANG
  581. _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
  582. : __a_value(value) {}
  583. _Tp __a_value;
  584. };
  585. _LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
  586. // Avoid switch statement to make this a constexpr.
  587. return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
  588. (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
  589. (__order == memory_order_release ? __ATOMIC_RELEASE:
  590. (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
  591. (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
  592. __ATOMIC_CONSUME))));
  593. }
  594. _LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
  595. // Avoid switch statement to make this a constexpr.
  596. return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
  597. (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
  598. (__order == memory_order_release ? __ATOMIC_RELAXED:
  599. (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
  600. (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
  601. __ATOMIC_CONSUME))));
  602. }
  603. template <typename _Tp>
  604. _LIBCPP_INLINE_VISIBILITY
  605. void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
  606. __cxx_atomic_assign_volatile(__a->__a_value, __val);
  607. }
  608. template <typename _Tp>
  609. _LIBCPP_INLINE_VISIBILITY
  610. void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
  611. __a->__a_value = __val;
  612. }
  613. _LIBCPP_INLINE_VISIBILITY inline
  614. void __cxx_atomic_thread_fence(memory_order __order) {
  615. __atomic_thread_fence(__to_gcc_order(__order));
  616. }
  617. _LIBCPP_INLINE_VISIBILITY inline
  618. void __cxx_atomic_signal_fence(memory_order __order) {
  619. __atomic_signal_fence(__to_gcc_order(__order));
  620. }
  621. template <typename _Tp>
  622. _LIBCPP_INLINE_VISIBILITY
  623. void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
  624. memory_order __order) {
  625. __atomic_store(&__a->__a_value, &__val,
  626. __to_gcc_order(__order));
  627. }
  628. template <typename _Tp>
  629. _LIBCPP_INLINE_VISIBILITY
  630. void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
  631. memory_order __order) {
  632. __atomic_store(&__a->__a_value, &__val,
  633. __to_gcc_order(__order));
  634. }
  635. template <typename _Tp>
  636. _LIBCPP_INLINE_VISIBILITY
  637. _Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
  638. memory_order __order) {
  639. _Tp __ret;
  640. __atomic_load(&__a->__a_value, &__ret,
  641. __to_gcc_order(__order));
  642. return __ret;
  643. }
  644. template <typename _Tp>
  645. _LIBCPP_INLINE_VISIBILITY
  646. _Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
  647. _Tp __ret;
  648. __atomic_load(&__a->__a_value, &__ret,
  649. __to_gcc_order(__order));
  650. return __ret;
  651. }
  652. template <typename _Tp>
  653. _LIBCPP_INLINE_VISIBILITY
  654. _Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
  655. _Tp __value, memory_order __order) {
  656. _Tp __ret;
  657. __atomic_exchange(&__a->__a_value, &__value, &__ret,
  658. __to_gcc_order(__order));
  659. return __ret;
  660. }
  661. template <typename _Tp>
  662. _LIBCPP_INLINE_VISIBILITY
  663. _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
  664. memory_order __order) {
  665. _Tp __ret;
  666. __atomic_exchange(&__a->__a_value, &__value, &__ret,
  667. __to_gcc_order(__order));
  668. return __ret;
  669. }
  670. template <typename _Tp>
  671. _LIBCPP_INLINE_VISIBILITY
  672. bool __cxx_atomic_compare_exchange_strong(
  673. volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
  674. memory_order __success, memory_order __failure) {
  675. return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
  676. false,
  677. __to_gcc_order(__success),
  678. __to_gcc_failure_order(__failure));
  679. }
  680. template <typename _Tp>
  681. _LIBCPP_INLINE_VISIBILITY
  682. bool __cxx_atomic_compare_exchange_strong(
  683. __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
  684. memory_order __failure) {
  685. return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
  686. false,
  687. __to_gcc_order(__success),
  688. __to_gcc_failure_order(__failure));
  689. }
  690. template <typename _Tp>
  691. _LIBCPP_INLINE_VISIBILITY
  692. bool __cxx_atomic_compare_exchange_weak(
  693. volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
  694. memory_order __success, memory_order __failure) {
  695. return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
  696. true,
  697. __to_gcc_order(__success),
  698. __to_gcc_failure_order(__failure));
  699. }
  700. template <typename _Tp>
  701. _LIBCPP_INLINE_VISIBILITY
  702. bool __cxx_atomic_compare_exchange_weak(
  703. __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
  704. memory_order __failure) {
  705. return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
  706. true,
  707. __to_gcc_order(__success),
  708. __to_gcc_failure_order(__failure));
  709. }
  710. template <typename _Tp>
  711. struct __skip_amt { enum {value = 1}; };
  712. template <typename _Tp>
  713. struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
  714. // FIXME: Haven't figured out what the spec says about using arrays with
  715. // atomic_fetch_add. Force a failure rather than creating bad behavior.
  716. template <typename _Tp>
  717. struct __skip_amt<_Tp[]> { };
  718. template <typename _Tp, int n>
  719. struct __skip_amt<_Tp[n]> { };
  720. template <typename _Tp, typename _Td>
  721. _LIBCPP_INLINE_VISIBILITY
  722. _Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
  723. _Td __delta, memory_order __order) {
  724. return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
  725. __to_gcc_order(__order));
  726. }
  727. template <typename _Tp, typename _Td>
  728. _LIBCPP_INLINE_VISIBILITY
  729. _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
  730. memory_order __order) {
  731. return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
  732. __to_gcc_order(__order));
  733. }
  734. template <typename _Tp, typename _Td>
  735. _LIBCPP_INLINE_VISIBILITY
  736. _Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
  737. _Td __delta, memory_order __order) {
  738. return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
  739. __to_gcc_order(__order));
  740. }
  741. template <typename _Tp, typename _Td>
  742. _LIBCPP_INLINE_VISIBILITY
  743. _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
  744. memory_order __order) {
  745. return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
  746. __to_gcc_order(__order));
  747. }
  748. template <typename _Tp>
  749. _LIBCPP_INLINE_VISIBILITY
  750. _Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
  751. _Tp __pattern, memory_order __order) {
  752. return __atomic_fetch_and(&__a->__a_value, __pattern,
  753. __to_gcc_order(__order));
  754. }
  755. template <typename _Tp>
  756. _LIBCPP_INLINE_VISIBILITY
  757. _Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
  758. _Tp __pattern, memory_order __order) {
  759. return __atomic_fetch_and(&__a->__a_value, __pattern,
  760. __to_gcc_order(__order));
  761. }
  762. template <typename _Tp>
  763. _LIBCPP_INLINE_VISIBILITY
  764. _Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
  765. _Tp __pattern, memory_order __order) {
  766. return __atomic_fetch_or(&__a->__a_value, __pattern,
  767. __to_gcc_order(__order));
  768. }
  769. template <typename _Tp>
  770. _LIBCPP_INLINE_VISIBILITY
  771. _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
  772. memory_order __order) {
  773. return __atomic_fetch_or(&__a->__a_value, __pattern,
  774. __to_gcc_order(__order));
  775. }
  776. template <typename _Tp>
  777. _LIBCPP_INLINE_VISIBILITY
  778. _Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
  779. _Tp __pattern, memory_order __order) {
  780. return __atomic_fetch_xor(&__a->__a_value, __pattern,
  781. __to_gcc_order(__order));
  782. }
  783. template <typename _Tp>
  784. _LIBCPP_INLINE_VISIBILITY
  785. _Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
  786. memory_order __order) {
  787. return __atomic_fetch_xor(&__a->__a_value, __pattern,
  788. __to_gcc_order(__order));
  789. }
  790. #define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
  791. #elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
  792. template <typename _Tp>
  793. struct __cxx_atomic_base_impl {
  794. _LIBCPP_INLINE_VISIBILITY
  795. #ifndef _LIBCPP_CXX03_LANG
  796. __cxx_atomic_base_impl() _NOEXCEPT = default;
  797. #else
  798. __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
  799. #endif // _LIBCPP_CXX03_LANG
  800. _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT
  801. : __a_value(__value) {}
  802. _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
  803. };
  804. #define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
  805. _LIBCPP_INLINE_VISIBILITY inline
  806. void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
  807. __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
  808. }
  809. _LIBCPP_INLINE_VISIBILITY inline
  810. void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
  811. __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
  812. }
  813. template<class _Tp>
  814. _LIBCPP_INLINE_VISIBILITY
  815. void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
  816. __c11_atomic_init(&__a->__a_value, __val);
  817. }
  818. template<class _Tp>
  819. _LIBCPP_INLINE_VISIBILITY
  820. void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
  821. __c11_atomic_init(&__a->__a_value, __val);
  822. }
  823. template<class _Tp>
  824. _LIBCPP_INLINE_VISIBILITY
  825. void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
  826. __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
  827. }
  828. template<class _Tp>
  829. _LIBCPP_INLINE_VISIBILITY
  830. void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
  831. __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
  832. }
  833. template<class _Tp>
  834. _LIBCPP_INLINE_VISIBILITY
  835. _Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
  836. using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
  837. return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
  838. }
  839. template<class _Tp>
  840. _LIBCPP_INLINE_VISIBILITY
  841. _Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
  842. using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
  843. return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
  844. }
  845. template<class _Tp>
  846. _LIBCPP_INLINE_VISIBILITY
  847. _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
  848. return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
  849. }
  850. template<class _Tp>
  851. _LIBCPP_INLINE_VISIBILITY
  852. _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
  853. return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
  854. }
  855. _LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
  856. // Avoid switch statement to make this a constexpr.
  857. return __order == memory_order_release ? memory_order_relaxed:
  858. (__order == memory_order_acq_rel ? memory_order_acquire:
  859. __order);
  860. }
  861. template<class _Tp>
  862. _LIBCPP_INLINE_VISIBILITY
  863. bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
  864. return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
  865. }
  866. template<class _Tp>
  867. _LIBCPP_INLINE_VISIBILITY
  868. bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
  869. return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
  870. }
  871. template<class _Tp>
  872. _LIBCPP_INLINE_VISIBILITY
  873. bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
  874. return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
  875. }
  876. template<class _Tp>
  877. _LIBCPP_INLINE_VISIBILITY
  878. bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
  879. return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
  880. }
  881. template<class _Tp>
  882. _LIBCPP_INLINE_VISIBILITY
  883. _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
  884. return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
  885. }
  886. template<class _Tp>
  887. _LIBCPP_INLINE_VISIBILITY
  888. _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
  889. return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
  890. }
  891. template<class _Tp>
  892. _LIBCPP_INLINE_VISIBILITY
  893. _Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
  894. return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
  895. }
  896. template<class _Tp>
  897. _LIBCPP_INLINE_VISIBILITY
  898. _Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
  899. return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
  900. }
  901. template<class _Tp>
  902. _LIBCPP_INLINE_VISIBILITY
  903. _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
  904. return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
  905. }
  906. template<class _Tp>
  907. _LIBCPP_INLINE_VISIBILITY
  908. _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
  909. return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
  910. }
  911. template<class _Tp>
  912. _LIBCPP_INLINE_VISIBILITY
  913. _Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
  914. return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
  915. }
  916. template<class _Tp>
  917. _LIBCPP_INLINE_VISIBILITY
  918. _Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
  919. return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
  920. }
  921. template<class _Tp>
  922. _LIBCPP_INLINE_VISIBILITY
  923. _Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
  924. return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
  925. }
  926. template<class _Tp>
  927. _LIBCPP_INLINE_VISIBILITY
  928. _Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
  929. return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
  930. }
  931. template<class _Tp>
  932. _LIBCPP_INLINE_VISIBILITY
  933. _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
  934. return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
  935. }
  936. template<class _Tp>
  937. _LIBCPP_INLINE_VISIBILITY
  938. _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
  939. return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
  940. }
  941. template<class _Tp>
  942. _LIBCPP_INLINE_VISIBILITY
  943. _Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
  944. return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
  945. }
  946. template<class _Tp>
  947. _LIBCPP_INLINE_VISIBILITY
  948. _Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
  949. return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
  950. }
  951. #endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
  952. template <class _Tp>
  953. _LIBCPP_INLINE_VISIBILITY
  954. _Tp kill_dependency(_Tp __y) _NOEXCEPT
  955. {
  956. return __y;
  957. }
  958. #if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
  959. # define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
  960. # define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
  961. #ifndef _LIBCPP_HAS_NO_CHAR8_T
  962. # define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
  963. #endif
  964. # define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
  965. # define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
  966. # define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
  967. # define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
  968. # define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
  969. # define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
  970. # define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
  971. # define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
  972. #elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
  973. # define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
  974. # define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
  975. #ifndef _LIBCPP_HAS_NO_CHAR8_T
  976. # define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
  977. #endif
  978. # define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
  979. # define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
  980. # define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
  981. # define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
  982. # define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
  983. # define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
  984. # define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
  985. # define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
  986. #endif
  987. template <class _Tp>
  988. struct __libcpp_is_always_lock_free {
  989. // __atomic_always_lock_free is available in all Standard modes
  990. static const bool __value = __atomic_always_lock_free(sizeof(_Tp), 0);
  991. };
  992. #ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
  993. template<typename _Tp>
  994. struct __cxx_atomic_lock_impl {
  995. _LIBCPP_INLINE_VISIBILITY
  996. __cxx_atomic_lock_impl() _NOEXCEPT
  997. : __a_value(), __a_lock(0) {}
  998. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit
  999. __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
  1000. : __a_value(value), __a_lock(0) {}
  1001. _Tp __a_value;
  1002. mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
  1003. _LIBCPP_INLINE_VISIBILITY void __lock() const volatile {
  1004. while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
  1005. /*spin*/;
  1006. }
  1007. _LIBCPP_INLINE_VISIBILITY void __lock() const {
  1008. while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
  1009. /*spin*/;
  1010. }
  1011. _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile {
  1012. __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
  1013. }
  1014. _LIBCPP_INLINE_VISIBILITY void __unlock() const {
  1015. __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
  1016. }
  1017. _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile {
  1018. __lock();
  1019. _Tp __old;
  1020. __cxx_atomic_assign_volatile(__old, __a_value);
  1021. __unlock();
  1022. return __old;
  1023. }
  1024. _LIBCPP_INLINE_VISIBILITY _Tp __read() const {
  1025. __lock();
  1026. _Tp __old = __a_value;
  1027. __unlock();
  1028. return __old;
  1029. }
  1030. };
  1031. template <typename _Tp>
  1032. _LIBCPP_INLINE_VISIBILITY
  1033. void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
  1034. __cxx_atomic_assign_volatile(__a->__a_value, __val);
  1035. }
  1036. template <typename _Tp>
  1037. _LIBCPP_INLINE_VISIBILITY
  1038. void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
  1039. __a->__a_value = __val;
  1040. }
  1041. template <typename _Tp>
  1042. _LIBCPP_INLINE_VISIBILITY
  1043. void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
  1044. __a->__lock();
  1045. __cxx_atomic_assign_volatile(__a->__a_value, __val);
  1046. __a->__unlock();
  1047. }
  1048. template <typename _Tp>
  1049. _LIBCPP_INLINE_VISIBILITY
  1050. void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
  1051. __a->__lock();
  1052. __a->__a_value = __val;
  1053. __a->__unlock();
  1054. }
  1055. template <typename _Tp>
  1056. _LIBCPP_INLINE_VISIBILITY
  1057. _Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
  1058. return __a->__read();
  1059. }
  1060. template <typename _Tp>
  1061. _LIBCPP_INLINE_VISIBILITY
  1062. _Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
  1063. return __a->__read();
  1064. }
  1065. template <typename _Tp>
  1066. _LIBCPP_INLINE_VISIBILITY
  1067. _Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
  1068. __a->__lock();
  1069. _Tp __old;
  1070. __cxx_atomic_assign_volatile(__old, __a->__a_value);
  1071. __cxx_atomic_assign_volatile(__a->__a_value, __value);
  1072. __a->__unlock();
  1073. return __old;
  1074. }
  1075. template <typename _Tp>
  1076. _LIBCPP_INLINE_VISIBILITY
  1077. _Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
  1078. __a->__lock();
  1079. _Tp __old = __a->__a_value;
  1080. __a->__a_value = __value;
  1081. __a->__unlock();
  1082. return __old;
  1083. }
  1084. template <typename _Tp>
  1085. _LIBCPP_INLINE_VISIBILITY
  1086. bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
  1087. _Tp* __expected, _Tp __value, memory_order, memory_order) {
  1088. _Tp __temp;
  1089. __a->__lock();
  1090. __cxx_atomic_assign_volatile(__temp, __a->__a_value);
  1091. bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
  1092. if(__ret)
  1093. __cxx_atomic_assign_volatile(__a->__a_value, __value);
  1094. else
  1095. __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
  1096. __a->__unlock();
  1097. return __ret;
  1098. }
  1099. template <typename _Tp>
  1100. _LIBCPP_INLINE_VISIBILITY
  1101. bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
  1102. _Tp* __expected, _Tp __value, memory_order, memory_order) {
  1103. __a->__lock();
  1104. bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
  1105. if(__ret)
  1106. _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
  1107. else
  1108. _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
  1109. __a->__unlock();
  1110. return __ret;
  1111. }
  1112. template <typename _Tp>
  1113. _LIBCPP_INLINE_VISIBILITY
  1114. bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
  1115. _Tp* __expected, _Tp __value, memory_order, memory_order) {
  1116. _Tp __temp;
  1117. __a->__lock();
  1118. __cxx_atomic_assign_volatile(__temp, __a->__a_value);
  1119. bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
  1120. if(__ret)
  1121. __cxx_atomic_assign_volatile(__a->__a_value, __value);
  1122. else
  1123. __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
  1124. __a->__unlock();
  1125. return __ret;
  1126. }
  1127. template <typename _Tp>
  1128. _LIBCPP_INLINE_VISIBILITY
  1129. bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
  1130. _Tp* __expected, _Tp __value, memory_order, memory_order) {
  1131. __a->__lock();
  1132. bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
  1133. if(__ret)
  1134. _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
  1135. else
  1136. _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
  1137. __a->__unlock();
  1138. return __ret;
  1139. }
  1140. template <typename _Tp, typename _Td>
  1141. _LIBCPP_INLINE_VISIBILITY
  1142. _Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
  1143. _Td __delta, memory_order) {
  1144. __a->__lock();
  1145. _Tp __old;
  1146. __cxx_atomic_assign_volatile(__old, __a->__a_value);
  1147. __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
  1148. __a->__unlock();
  1149. return __old;
  1150. }
  1151. template <typename _Tp, typename _Td>
  1152. _LIBCPP_INLINE_VISIBILITY
  1153. _Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
  1154. _Td __delta, memory_order) {
  1155. __a->__lock();
  1156. _Tp __old = __a->__a_value;
  1157. __a->__a_value += __delta;
  1158. __a->__unlock();
  1159. return __old;
  1160. }
  1161. template <typename _Tp, typename _Td>
  1162. _LIBCPP_INLINE_VISIBILITY
  1163. _Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
  1164. ptrdiff_t __delta, memory_order) {
  1165. __a->__lock();
  1166. _Tp* __old;
  1167. __cxx_atomic_assign_volatile(__old, __a->__a_value);
  1168. __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
  1169. __a->__unlock();
  1170. return __old;
  1171. }
  1172. template <typename _Tp, typename _Td>
  1173. _LIBCPP_INLINE_VISIBILITY
  1174. _Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
  1175. ptrdiff_t __delta, memory_order) {
  1176. __a->__lock();
  1177. _Tp* __old = __a->__a_value;
  1178. __a->__a_value += __delta;
  1179. __a->__unlock();
  1180. return __old;
  1181. }
  1182. template <typename _Tp, typename _Td>
  1183. _LIBCPP_INLINE_VISIBILITY
  1184. _Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
  1185. _Td __delta, memory_order) {
  1186. __a->__lock();
  1187. _Tp __old;
  1188. __cxx_atomic_assign_volatile(__old, __a->__a_value);
  1189. __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
  1190. __a->__unlock();
  1191. return __old;
  1192. }
  1193. template <typename _Tp, typename _Td>
  1194. _LIBCPP_INLINE_VISIBILITY
  1195. _Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
  1196. _Td __delta, memory_order) {
  1197. __a->__lock();
  1198. _Tp __old = __a->__a_value;
  1199. __a->__a_value -= __delta;
  1200. __a->__unlock();
  1201. return __old;
  1202. }
  1203. template <typename _Tp>
  1204. _LIBCPP_INLINE_VISIBILITY
  1205. _Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
  1206. _Tp __pattern, memory_order) {
  1207. __a->__lock();
  1208. _Tp __old;
  1209. __cxx_atomic_assign_volatile(__old, __a->__a_value);
  1210. __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
  1211. __a->__unlock();
  1212. return __old;
  1213. }
  1214. template <typename _Tp>
  1215. _LIBCPP_INLINE_VISIBILITY
  1216. _Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
  1217. _Tp __pattern, memory_order) {
  1218. __a->__lock();
  1219. _Tp __old = __a->__a_value;
  1220. __a->__a_value &= __pattern;
  1221. __a->__unlock();
  1222. return __old;
  1223. }
  1224. template <typename _Tp>
  1225. _LIBCPP_INLINE_VISIBILITY
  1226. _Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
  1227. _Tp __pattern, memory_order) {
  1228. __a->__lock();
  1229. _Tp __old;
  1230. __cxx_atomic_assign_volatile(__old, __a->__a_value);
  1231. __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
  1232. __a->__unlock();
  1233. return __old;
  1234. }
  1235. template <typename _Tp>
  1236. _LIBCPP_INLINE_VISIBILITY
  1237. _Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
  1238. _Tp __pattern, memory_order) {
  1239. __a->__lock();
  1240. _Tp __old = __a->__a_value;
  1241. __a->__a_value |= __pattern;
  1242. __a->__unlock();
  1243. return __old;
  1244. }
  1245. template <typename _Tp>
  1246. _LIBCPP_INLINE_VISIBILITY
  1247. _Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
  1248. _Tp __pattern, memory_order) {
  1249. __a->__lock();
  1250. _Tp __old;
  1251. __cxx_atomic_assign_volatile(__old, __a->__a_value);
  1252. __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
  1253. __a->__unlock();
  1254. return __old;
  1255. }
  1256. template <typename _Tp>
  1257. _LIBCPP_INLINE_VISIBILITY
  1258. _Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
  1259. _Tp __pattern, memory_order) {
  1260. __a->__lock();
  1261. _Tp __old = __a->__a_value;
  1262. __a->__a_value ^= __pattern;
  1263. __a->__unlock();
  1264. return __old;
  1265. }
  1266. template <typename _Tp,
  1267. typename _Base = typename conditional<__libcpp_is_always_lock_free<_Tp>::__value,
  1268. __cxx_atomic_base_impl<_Tp>,
  1269. __cxx_atomic_lock_impl<_Tp> >::type>
  1270. #else
  1271. template <typename _Tp,
  1272. typename _Base = __cxx_atomic_base_impl<_Tp> >
  1273. #endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
  1274. struct __cxx_atomic_impl : public _Base {
  1275. static_assert(is_trivially_copyable<_Tp>::value,
  1276. "std::atomic<T> requires that 'T' be a trivially copyable type");
  1277. _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT = default;
  1278. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT
  1279. : _Base(__value) {}
  1280. };
  1281. #if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
  1282. using __cxx_contention_t = int32_t;
  1283. #else
  1284. using __cxx_contention_t = int64_t;
  1285. #endif // __linux__ || (_AIX && !__64BIT__)
  1286. using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
  1287. #ifndef _LIBCPP_HAS_NO_THREADS
  1288. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
  1289. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
  1290. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
  1291. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
  1292. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
  1293. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
  1294. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
  1295. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t);
  1296. template <class _Atp, class _Fn>
  1297. struct __libcpp_atomic_wait_backoff_impl {
  1298. _Atp* __a;
  1299. _Fn __test_fn;
  1300. _LIBCPP_AVAILABILITY_SYNC
  1301. _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const
  1302. {
  1303. if(__elapsed > chrono::microseconds(64))
  1304. {
  1305. auto const __monitor = std::__libcpp_atomic_monitor(__a);
  1306. if(__test_fn())
  1307. return true;
  1308. std::__libcpp_atomic_wait(__a, __monitor);
  1309. }
  1310. else if(__elapsed > chrono::microseconds(4))
  1311. __libcpp_thread_yield();
  1312. else
  1313. {} // poll
  1314. return false;
  1315. }
  1316. };
  1317. template <class _Atp, class _Fn>
  1318. _LIBCPP_AVAILABILITY_SYNC
  1319. _LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
  1320. {
  1321. __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn};
  1322. return std::__libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
  1323. }
  1324. #else // _LIBCPP_HAS_NO_THREADS
  1325. template <class _Tp>
  1326. _LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
  1327. template <class _Tp>
  1328. _LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
  1329. template <class _Atp, class _Fn>
  1330. _LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
  1331. {
  1332. return __libcpp_thread_poll_with_backoff(__test_fn, __spinning_backoff_policy());
  1333. }
  1334. #endif // _LIBCPP_HAS_NO_THREADS
  1335. template <class _Atp, class _Tp>
  1336. struct __cxx_atomic_wait_test_fn_impl {
  1337. _Atp* __a;
  1338. _Tp __val;
  1339. memory_order __order;
  1340. _LIBCPP_INLINE_VISIBILITY bool operator()() const
  1341. {
  1342. return !std::__cxx_nonatomic_compare_equal(std::__cxx_atomic_load(__a, __order), __val);
  1343. }
  1344. };
  1345. template <class _Atp, class _Tp>
  1346. _LIBCPP_AVAILABILITY_SYNC
  1347. _LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
  1348. {
  1349. __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
  1350. return std::__cxx_atomic_wait(__a, __test_fn);
  1351. }
  1352. // general atomic<T>
  1353. template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
  1354. struct __atomic_base // false
  1355. {
  1356. mutable __cxx_atomic_impl<_Tp> __a_;
  1357. #if defined(__cpp_lib_atomic_is_always_lock_free)
  1358. static _LIBCPP_CONSTEXPR bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value;
  1359. #endif
  1360. _LIBCPP_INLINE_VISIBILITY
  1361. bool is_lock_free() const volatile _NOEXCEPT
  1362. {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
  1363. _LIBCPP_INLINE_VISIBILITY
  1364. bool is_lock_free() const _NOEXCEPT
  1365. {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
  1366. _LIBCPP_INLINE_VISIBILITY
  1367. void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
  1368. _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
  1369. {std::__cxx_atomic_store(&__a_, __d, __m);}
  1370. _LIBCPP_INLINE_VISIBILITY
  1371. void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
  1372. _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
  1373. {std::__cxx_atomic_store(&__a_, __d, __m);}
  1374. _LIBCPP_INLINE_VISIBILITY
  1375. _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
  1376. _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
  1377. {return std::__cxx_atomic_load(&__a_, __m);}
  1378. _LIBCPP_INLINE_VISIBILITY
  1379. _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
  1380. _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
  1381. {return std::__cxx_atomic_load(&__a_, __m);}
  1382. _LIBCPP_INLINE_VISIBILITY
  1383. operator _Tp() const volatile _NOEXCEPT {return load();}
  1384. _LIBCPP_INLINE_VISIBILITY
  1385. operator _Tp() const _NOEXCEPT {return load();}
  1386. _LIBCPP_INLINE_VISIBILITY
  1387. _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
  1388. {return std::__cxx_atomic_exchange(&__a_, __d, __m);}
  1389. _LIBCPP_INLINE_VISIBILITY
  1390. _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
  1391. {return std::__cxx_atomic_exchange(&__a_, __d, __m);}
  1392. _LIBCPP_INLINE_VISIBILITY
  1393. bool compare_exchange_weak(_Tp& __e, _Tp __d,
  1394. memory_order __s, memory_order __f) volatile _NOEXCEPT
  1395. _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
  1396. {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
  1397. _LIBCPP_INLINE_VISIBILITY
  1398. bool compare_exchange_weak(_Tp& __e, _Tp __d,
  1399. memory_order __s, memory_order __f) _NOEXCEPT
  1400. _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
  1401. {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
  1402. _LIBCPP_INLINE_VISIBILITY
  1403. bool compare_exchange_strong(_Tp& __e, _Tp __d,
  1404. memory_order __s, memory_order __f) volatile _NOEXCEPT
  1405. _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
  1406. {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
  1407. _LIBCPP_INLINE_VISIBILITY
  1408. bool compare_exchange_strong(_Tp& __e, _Tp __d,
  1409. memory_order __s, memory_order __f) _NOEXCEPT
  1410. _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
  1411. {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
  1412. _LIBCPP_INLINE_VISIBILITY
  1413. bool compare_exchange_weak(_Tp& __e, _Tp __d,
  1414. memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
  1415. {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
  1416. _LIBCPP_INLINE_VISIBILITY
  1417. bool compare_exchange_weak(_Tp& __e, _Tp __d,
  1418. memory_order __m = memory_order_seq_cst) _NOEXCEPT
  1419. {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
  1420. _LIBCPP_INLINE_VISIBILITY
  1421. bool compare_exchange_strong(_Tp& __e, _Tp __d,
  1422. memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
  1423. {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
  1424. _LIBCPP_INLINE_VISIBILITY
  1425. bool compare_exchange_strong(_Tp& __e, _Tp __d,
  1426. memory_order __m = memory_order_seq_cst) _NOEXCEPT
  1427. {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
  1428. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
  1429. {std::__cxx_atomic_wait(&__a_, __v, __m);}
  1430. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
  1431. {std::__cxx_atomic_wait(&__a_, __v, __m);}
  1432. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT
  1433. {std::__cxx_atomic_notify_one(&__a_);}
  1434. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT
  1435. {std::__cxx_atomic_notify_one(&__a_);}
  1436. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT
  1437. {std::__cxx_atomic_notify_all(&__a_);}
  1438. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
  1439. {std::__cxx_atomic_notify_all(&__a_);}
  1440. #if _LIBCPP_STD_VER > 17
  1441. _LIBCPP_INLINE_VISIBILITY constexpr
  1442. __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
  1443. #else
  1444. _LIBCPP_INLINE_VISIBILITY
  1445. __atomic_base() _NOEXCEPT = default;
  1446. #endif
  1447. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
  1448. __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
  1449. __atomic_base(const __atomic_base&) = delete;
  1450. };
  1451. #if defined(__cpp_lib_atomic_is_always_lock_free)
  1452. template <class _Tp, bool __b>
  1453. _LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
  1454. #endif
  1455. // atomic<Integral>
  1456. template <class _Tp>
  1457. struct __atomic_base<_Tp, true>
  1458. : public __atomic_base<_Tp, false>
  1459. {
  1460. typedef __atomic_base<_Tp, false> __base;
  1461. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
  1462. __atomic_base() _NOEXCEPT = default;
  1463. _LIBCPP_INLINE_VISIBILITY
  1464. _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
  1465. _LIBCPP_INLINE_VISIBILITY
  1466. _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
  1467. {return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);}
  1468. _LIBCPP_INLINE_VISIBILITY
  1469. _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
  1470. {return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);}
  1471. _LIBCPP_INLINE_VISIBILITY
  1472. _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
  1473. {return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
  1474. _LIBCPP_INLINE_VISIBILITY
  1475. _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
  1476. {return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
  1477. _LIBCPP_INLINE_VISIBILITY
  1478. _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
  1479. {return std::__cxx_atomic_fetch_and(&this->__a_, __op, __m);}
  1480. _LIBCPP_INLINE_VISIBILITY
  1481. _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
  1482. {return std::__cxx_atomic_fetch_and(&this->__a_, __op, __m);}
  1483. _LIBCPP_INLINE_VISIBILITY
  1484. _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
  1485. {return std::__cxx_atomic_fetch_or(&this->__a_, __op, __m);}
  1486. _LIBCPP_INLINE_VISIBILITY
  1487. _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
  1488. {return std::__cxx_atomic_fetch_or(&this->__a_, __op, __m);}
  1489. _LIBCPP_INLINE_VISIBILITY
  1490. _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
  1491. {return std::__cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
  1492. _LIBCPP_INLINE_VISIBILITY
  1493. _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
  1494. {return std::__cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
  1495. _LIBCPP_INLINE_VISIBILITY
  1496. _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));}
  1497. _LIBCPP_INLINE_VISIBILITY
  1498. _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));}
  1499. _LIBCPP_INLINE_VISIBILITY
  1500. _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));}
  1501. _LIBCPP_INLINE_VISIBILITY
  1502. _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));}
  1503. _LIBCPP_INLINE_VISIBILITY
  1504. _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
  1505. _LIBCPP_INLINE_VISIBILITY
  1506. _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
  1507. _LIBCPP_INLINE_VISIBILITY
  1508. _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
  1509. _LIBCPP_INLINE_VISIBILITY
  1510. _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
  1511. _LIBCPP_INLINE_VISIBILITY
  1512. _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
  1513. _LIBCPP_INLINE_VISIBILITY
  1514. _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;}
  1515. _LIBCPP_INLINE_VISIBILITY
  1516. _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
  1517. _LIBCPP_INLINE_VISIBILITY
  1518. _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
  1519. _LIBCPP_INLINE_VISIBILITY
  1520. _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
  1521. _LIBCPP_INLINE_VISIBILITY
  1522. _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;}
  1523. _LIBCPP_INLINE_VISIBILITY
  1524. _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
  1525. _LIBCPP_INLINE_VISIBILITY
  1526. _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;}
  1527. _LIBCPP_INLINE_VISIBILITY
  1528. _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
  1529. _LIBCPP_INLINE_VISIBILITY
  1530. _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;}
  1531. };
  1532. // atomic<T>
  1533. template <class _Tp>
  1534. struct atomic
  1535. : public __atomic_base<_Tp>
  1536. {
  1537. typedef __atomic_base<_Tp> __base;
  1538. typedef _Tp value_type;
  1539. typedef value_type difference_type;
  1540. #if _LIBCPP_STD_VER > 17
  1541. _LIBCPP_INLINE_VISIBILITY
  1542. atomic() = default;
  1543. #else
  1544. _LIBCPP_INLINE_VISIBILITY
  1545. atomic() _NOEXCEPT = default;
  1546. #endif
  1547. _LIBCPP_INLINE_VISIBILITY
  1548. _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
  1549. _LIBCPP_INLINE_VISIBILITY
  1550. _Tp operator=(_Tp __d) volatile _NOEXCEPT
  1551. {__base::store(__d); return __d;}
  1552. _LIBCPP_INLINE_VISIBILITY
  1553. _Tp operator=(_Tp __d) _NOEXCEPT
  1554. {__base::store(__d); return __d;}
  1555. atomic& operator=(const atomic&) = delete;
  1556. atomic& operator=(const atomic&) volatile = delete;
  1557. };
  1558. // atomic<T*>
  1559. template <class _Tp>
  1560. struct atomic<_Tp*>
  1561. : public __atomic_base<_Tp*>
  1562. {
  1563. typedef __atomic_base<_Tp*> __base;
  1564. typedef _Tp* value_type;
  1565. typedef ptrdiff_t difference_type;
  1566. _LIBCPP_INLINE_VISIBILITY
  1567. atomic() _NOEXCEPT = default;
  1568. _LIBCPP_INLINE_VISIBILITY
  1569. _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
  1570. _LIBCPP_INLINE_VISIBILITY
  1571. _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
  1572. {__base::store(__d); return __d;}
  1573. _LIBCPP_INLINE_VISIBILITY
  1574. _Tp* operator=(_Tp* __d) _NOEXCEPT
  1575. {__base::store(__d); return __d;}
  1576. _LIBCPP_INLINE_VISIBILITY
  1577. _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
  1578. // __atomic_fetch_add accepts function pointers, guard against them.
  1579. static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
  1580. return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);
  1581. }
  1582. _LIBCPP_INLINE_VISIBILITY
  1583. _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
  1584. // __atomic_fetch_add accepts function pointers, guard against them.
  1585. static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
  1586. return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);
  1587. }
  1588. _LIBCPP_INLINE_VISIBILITY
  1589. _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
  1590. // __atomic_fetch_add accepts function pointers, guard against them.
  1591. static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
  1592. return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);
  1593. }
  1594. _LIBCPP_INLINE_VISIBILITY
  1595. _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
  1596. // __atomic_fetch_add accepts function pointers, guard against them.
  1597. static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
  1598. return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);
  1599. }
  1600. _LIBCPP_INLINE_VISIBILITY
  1601. _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);}
  1602. _LIBCPP_INLINE_VISIBILITY
  1603. _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);}
  1604. _LIBCPP_INLINE_VISIBILITY
  1605. _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);}
  1606. _LIBCPP_INLINE_VISIBILITY
  1607. _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);}
  1608. _LIBCPP_INLINE_VISIBILITY
  1609. _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;}
  1610. _LIBCPP_INLINE_VISIBILITY
  1611. _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;}
  1612. _LIBCPP_INLINE_VISIBILITY
  1613. _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;}
  1614. _LIBCPP_INLINE_VISIBILITY
  1615. _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;}
  1616. _LIBCPP_INLINE_VISIBILITY
  1617. _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
  1618. _LIBCPP_INLINE_VISIBILITY
  1619. _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;}
  1620. _LIBCPP_INLINE_VISIBILITY
  1621. _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
  1622. _LIBCPP_INLINE_VISIBILITY
  1623. _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
  1624. atomic& operator=(const atomic&) = delete;
  1625. atomic& operator=(const atomic&) volatile = delete;
  1626. };
  1627. // atomic_is_lock_free
  1628. template <class _Tp>
  1629. _LIBCPP_INLINE_VISIBILITY
  1630. bool
  1631. atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
  1632. {
  1633. return __o->is_lock_free();
  1634. }
  1635. template <class _Tp>
  1636. _LIBCPP_INLINE_VISIBILITY
  1637. bool
  1638. atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
  1639. {
  1640. return __o->is_lock_free();
  1641. }
  1642. // atomic_init
  1643. template <class _Tp>
  1644. _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
  1645. void
  1646. atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
  1647. {
  1648. std::__cxx_atomic_init(&__o->__a_, __d);
  1649. }
  1650. template <class _Tp>
  1651. _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
  1652. void
  1653. atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
  1654. {
  1655. std::__cxx_atomic_init(&__o->__a_, __d);
  1656. }
  1657. // atomic_store
  1658. template <class _Tp>
  1659. _LIBCPP_INLINE_VISIBILITY
  1660. void
  1661. atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
  1662. {
  1663. __o->store(__d);
  1664. }
  1665. template <class _Tp>
  1666. _LIBCPP_INLINE_VISIBILITY
  1667. void
  1668. atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
  1669. {
  1670. __o->store(__d);
  1671. }
  1672. // atomic_store_explicit
  1673. template <class _Tp>
  1674. _LIBCPP_INLINE_VISIBILITY
  1675. void
  1676. atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
  1677. _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
  1678. {
  1679. __o->store(__d, __m);
  1680. }
  1681. template <class _Tp>
  1682. _LIBCPP_INLINE_VISIBILITY
  1683. void
  1684. atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
  1685. _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
  1686. {
  1687. __o->store(__d, __m);
  1688. }
  1689. // atomic_load
  1690. template <class _Tp>
  1691. _LIBCPP_INLINE_VISIBILITY
  1692. _Tp
  1693. atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
  1694. {
  1695. return __o->load();
  1696. }
  1697. template <class _Tp>
  1698. _LIBCPP_INLINE_VISIBILITY
  1699. _Tp
  1700. atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
  1701. {
  1702. return __o->load();
  1703. }
  1704. // atomic_load_explicit
  1705. template <class _Tp>
  1706. _LIBCPP_INLINE_VISIBILITY
  1707. _Tp
  1708. atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
  1709. _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
  1710. {
  1711. return __o->load(__m);
  1712. }
  1713. template <class _Tp>
  1714. _LIBCPP_INLINE_VISIBILITY
  1715. _Tp
  1716. atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
  1717. _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
  1718. {
  1719. return __o->load(__m);
  1720. }
  1721. // atomic_exchange
  1722. template <class _Tp>
  1723. _LIBCPP_INLINE_VISIBILITY
  1724. _Tp
  1725. atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
  1726. {
  1727. return __o->exchange(__d);
  1728. }
  1729. template <class _Tp>
  1730. _LIBCPP_INLINE_VISIBILITY
  1731. _Tp
  1732. atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
  1733. {
  1734. return __o->exchange(__d);
  1735. }
  1736. // atomic_exchange_explicit
  1737. template <class _Tp>
  1738. _LIBCPP_INLINE_VISIBILITY
  1739. _Tp
  1740. atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
  1741. {
  1742. return __o->exchange(__d, __m);
  1743. }
  1744. template <class _Tp>
  1745. _LIBCPP_INLINE_VISIBILITY
  1746. _Tp
  1747. atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
  1748. {
  1749. return __o->exchange(__d, __m);
  1750. }
  1751. // atomic_compare_exchange_weak
  1752. template <class _Tp>
  1753. _LIBCPP_INLINE_VISIBILITY
  1754. bool
  1755. atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
  1756. {
  1757. return __o->compare_exchange_weak(*__e, __d);
  1758. }
  1759. template <class _Tp>
  1760. _LIBCPP_INLINE_VISIBILITY
  1761. bool
  1762. atomic_compare_exchange_weak(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
  1763. {
  1764. return __o->compare_exchange_weak(*__e, __d);
  1765. }
  1766. // atomic_compare_exchange_strong
  1767. template <class _Tp>
  1768. _LIBCPP_INLINE_VISIBILITY
  1769. bool
  1770. atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
  1771. {
  1772. return __o->compare_exchange_strong(*__e, __d);
  1773. }
  1774. template <class _Tp>
  1775. _LIBCPP_INLINE_VISIBILITY
  1776. bool
  1777. atomic_compare_exchange_strong(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
  1778. {
  1779. return __o->compare_exchange_strong(*__e, __d);
  1780. }
  1781. // atomic_compare_exchange_weak_explicit
  1782. template <class _Tp>
  1783. _LIBCPP_INLINE_VISIBILITY
  1784. bool
  1785. atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
  1786. typename atomic<_Tp>::value_type __d,
  1787. memory_order __s, memory_order __f) _NOEXCEPT
  1788. _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
  1789. {
  1790. return __o->compare_exchange_weak(*__e, __d, __s, __f);
  1791. }
  1792. template <class _Tp>
  1793. _LIBCPP_INLINE_VISIBILITY
  1794. bool
  1795. atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
  1796. memory_order __s, memory_order __f) _NOEXCEPT
  1797. _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
  1798. {
  1799. return __o->compare_exchange_weak(*__e, __d, __s, __f);
  1800. }
  1801. // atomic_compare_exchange_strong_explicit
  1802. template <class _Tp>
  1803. _LIBCPP_INLINE_VISIBILITY
  1804. bool
  1805. atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
  1806. typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
  1807. memory_order __s, memory_order __f) _NOEXCEPT
  1808. _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
  1809. {
  1810. return __o->compare_exchange_strong(*__e, __d, __s, __f);
  1811. }
  1812. template <class _Tp>
  1813. _LIBCPP_INLINE_VISIBILITY
  1814. bool
  1815. atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
  1816. typename atomic<_Tp>::value_type __d,
  1817. memory_order __s, memory_order __f) _NOEXCEPT
  1818. _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
  1819. {
  1820. return __o->compare_exchange_strong(*__e, __d, __s, __f);
  1821. }
  1822. // atomic_wait
  1823. template <class _Tp>
  1824. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
  1825. void atomic_wait(const volatile atomic<_Tp>* __o,
  1826. typename atomic<_Tp>::value_type __v) _NOEXCEPT
  1827. {
  1828. return __o->wait(__v);
  1829. }
  1830. template <class _Tp>
  1831. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
  1832. void atomic_wait(const atomic<_Tp>* __o,
  1833. typename atomic<_Tp>::value_type __v) _NOEXCEPT
  1834. {
  1835. return __o->wait(__v);
  1836. }
  1837. // atomic_wait_explicit
  1838. template <class _Tp>
  1839. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
  1840. void atomic_wait_explicit(const volatile atomic<_Tp>* __o,
  1841. typename atomic<_Tp>::value_type __v,
  1842. memory_order __m) _NOEXCEPT
  1843. _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
  1844. {
  1845. return __o->wait(__v, __m);
  1846. }
  1847. template <class _Tp>
  1848. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
  1849. void atomic_wait_explicit(const atomic<_Tp>* __o,
  1850. typename atomic<_Tp>::value_type __v,
  1851. memory_order __m) _NOEXCEPT
  1852. _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
  1853. {
  1854. return __o->wait(__v, __m);
  1855. }
  1856. // atomic_notify_one
  1857. template <class _Tp>
  1858. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
  1859. void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
  1860. {
  1861. __o->notify_one();
  1862. }
  1863. template <class _Tp>
  1864. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
  1865. void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
  1866. {
  1867. __o->notify_one();
  1868. }
  1869. // atomic_notify_all
  1870. template <class _Tp>
  1871. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
  1872. void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
  1873. {
  1874. __o->notify_all();
  1875. }
  1876. template <class _Tp>
  1877. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
  1878. void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
  1879. {
  1880. __o->notify_all();
  1881. }
  1882. // atomic_fetch_add
  1883. template <class _Tp>
  1884. _LIBCPP_INLINE_VISIBILITY
  1885. _Tp
  1886. atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
  1887. {
  1888. return __o->fetch_add(__op);
  1889. }
  1890. template <class _Tp>
  1891. _LIBCPP_INLINE_VISIBILITY
  1892. _Tp
  1893. atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
  1894. {
  1895. return __o->fetch_add(__op);
  1896. }
  1897. // atomic_fetch_add_explicit
  1898. template <class _Tp>
  1899. _LIBCPP_INLINE_VISIBILITY
  1900. _Tp atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
  1901. {
  1902. return __o->fetch_add(__op, __m);
  1903. }
  1904. template <class _Tp>
  1905. _LIBCPP_INLINE_VISIBILITY
  1906. _Tp atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
  1907. {
  1908. return __o->fetch_add(__op, __m);
  1909. }
  1910. // atomic_fetch_sub
  1911. template <class _Tp>
  1912. _LIBCPP_INLINE_VISIBILITY
  1913. _Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
  1914. {
  1915. return __o->fetch_sub(__op);
  1916. }
  1917. template <class _Tp>
  1918. _LIBCPP_INLINE_VISIBILITY
  1919. _Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
  1920. {
  1921. return __o->fetch_sub(__op);
  1922. }
  1923. // atomic_fetch_sub_explicit
  1924. template <class _Tp>
  1925. _LIBCPP_INLINE_VISIBILITY
  1926. _Tp atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
  1927. {
  1928. return __o->fetch_sub(__op, __m);
  1929. }
  1930. template <class _Tp>
  1931. _LIBCPP_INLINE_VISIBILITY
  1932. _Tp atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
  1933. {
  1934. return __o->fetch_sub(__op, __m);
  1935. }
  1936. // atomic_fetch_and
  1937. template <class _Tp>
  1938. _LIBCPP_INLINE_VISIBILITY
  1939. typename enable_if
  1940. <
  1941. is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
  1942. _Tp
  1943. >::type
  1944. atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
  1945. {
  1946. return __o->fetch_and(__op);
  1947. }
  1948. template <class _Tp>
  1949. _LIBCPP_INLINE_VISIBILITY
  1950. typename enable_if
  1951. <
  1952. is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
  1953. _Tp
  1954. >::type
  1955. atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
  1956. {
  1957. return __o->fetch_and(__op);
  1958. }
  1959. // atomic_fetch_and_explicit
  1960. template <class _Tp>
  1961. _LIBCPP_INLINE_VISIBILITY
  1962. typename enable_if
  1963. <
  1964. is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
  1965. _Tp
  1966. >::type
  1967. atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
  1968. {
  1969. return __o->fetch_and(__op, __m);
  1970. }
  1971. template <class _Tp>
  1972. _LIBCPP_INLINE_VISIBILITY
  1973. typename enable_if
  1974. <
  1975. is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
  1976. _Tp
  1977. >::type
  1978. atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
  1979. {
  1980. return __o->fetch_and(__op, __m);
  1981. }
  1982. // atomic_fetch_or
  1983. template <class _Tp>
  1984. _LIBCPP_INLINE_VISIBILITY
  1985. typename enable_if
  1986. <
  1987. is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
  1988. _Tp
  1989. >::type
  1990. atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
  1991. {
  1992. return __o->fetch_or(__op);
  1993. }
  1994. template <class _Tp>
  1995. _LIBCPP_INLINE_VISIBILITY
  1996. typename enable_if
  1997. <
  1998. is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
  1999. _Tp
  2000. >::type
  2001. atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
  2002. {
  2003. return __o->fetch_or(__op);
  2004. }
  2005. // atomic_fetch_or_explicit
  2006. template <class _Tp>
  2007. _LIBCPP_INLINE_VISIBILITY
  2008. typename enable_if
  2009. <
  2010. is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
  2011. _Tp
  2012. >::type
  2013. atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
  2014. {
  2015. return __o->fetch_or(__op, __m);
  2016. }
  2017. template <class _Tp>
  2018. _LIBCPP_INLINE_VISIBILITY
  2019. typename enable_if
  2020. <
  2021. is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
  2022. _Tp
  2023. >::type
  2024. atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
  2025. {
  2026. return __o->fetch_or(__op, __m);
  2027. }
  2028. // atomic_fetch_xor
  2029. template <class _Tp>
  2030. _LIBCPP_INLINE_VISIBILITY
  2031. typename enable_if
  2032. <
  2033. is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
  2034. _Tp
  2035. >::type
  2036. atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
  2037. {
  2038. return __o->fetch_xor(__op);
  2039. }
  2040. template <class _Tp>
  2041. _LIBCPP_INLINE_VISIBILITY
  2042. typename enable_if
  2043. <
  2044. is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
  2045. _Tp
  2046. >::type
  2047. atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
  2048. {
  2049. return __o->fetch_xor(__op);
  2050. }
  2051. // atomic_fetch_xor_explicit
  2052. template <class _Tp>
  2053. _LIBCPP_INLINE_VISIBILITY
  2054. typename enable_if
  2055. <
  2056. is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
  2057. _Tp
  2058. >::type
  2059. atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
  2060. {
  2061. return __o->fetch_xor(__op, __m);
  2062. }
  2063. template <class _Tp>
  2064. _LIBCPP_INLINE_VISIBILITY
  2065. typename enable_if
  2066. <
  2067. is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
  2068. _Tp
  2069. >::type
  2070. atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
  2071. {
  2072. return __o->fetch_xor(__op, __m);
  2073. }
  2074. // flag type and operations
  2075. typedef struct atomic_flag
  2076. {
  2077. __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
  2078. _LIBCPP_INLINE_VISIBILITY
  2079. bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
  2080. {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
  2081. _LIBCPP_INLINE_VISIBILITY
  2082. bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
  2083. {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
  2084. _LIBCPP_INLINE_VISIBILITY
  2085. bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
  2086. {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
  2087. _LIBCPP_INLINE_VISIBILITY
  2088. bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
  2089. {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
  2090. _LIBCPP_INLINE_VISIBILITY
  2091. void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
  2092. {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
  2093. _LIBCPP_INLINE_VISIBILITY
  2094. void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
  2095. {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
  2096. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
  2097. void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
  2098. {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
  2099. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
  2100. void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
  2101. {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
  2102. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
  2103. void notify_one() volatile _NOEXCEPT
  2104. {__cxx_atomic_notify_one(&__a_);}
  2105. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
  2106. void notify_one() _NOEXCEPT
  2107. {__cxx_atomic_notify_one(&__a_);}
  2108. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
  2109. void notify_all() volatile _NOEXCEPT
  2110. {__cxx_atomic_notify_all(&__a_);}
  2111. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
  2112. void notify_all() _NOEXCEPT
  2113. {__cxx_atomic_notify_all(&__a_);}
  2114. #if _LIBCPP_STD_VER > 17
  2115. _LIBCPP_INLINE_VISIBILITY constexpr
  2116. atomic_flag() _NOEXCEPT : __a_(false) {}
  2117. #else
  2118. _LIBCPP_INLINE_VISIBILITY
  2119. atomic_flag() _NOEXCEPT = default;
  2120. #endif
  2121. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
  2122. atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
  2123. atomic_flag(const atomic_flag&) = delete;
  2124. atomic_flag& operator=(const atomic_flag&) = delete;
  2125. atomic_flag& operator=(const atomic_flag&) volatile = delete;
  2126. } atomic_flag;
  2127. inline _LIBCPP_INLINE_VISIBILITY
  2128. bool
  2129. atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
  2130. {
  2131. return __o->test();
  2132. }
  2133. inline _LIBCPP_INLINE_VISIBILITY
  2134. bool
  2135. atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
  2136. {
  2137. return __o->test();
  2138. }
  2139. inline _LIBCPP_INLINE_VISIBILITY
  2140. bool
  2141. atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
  2142. {
  2143. return __o->test(__m);
  2144. }
  2145. inline _LIBCPP_INLINE_VISIBILITY
  2146. bool
  2147. atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
  2148. {
  2149. return __o->test(__m);
  2150. }
  2151. inline _LIBCPP_INLINE_VISIBILITY
  2152. bool
  2153. atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
  2154. {
  2155. return __o->test_and_set();
  2156. }
  2157. inline _LIBCPP_INLINE_VISIBILITY
  2158. bool
  2159. atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
  2160. {
  2161. return __o->test_and_set();
  2162. }
  2163. inline _LIBCPP_INLINE_VISIBILITY
  2164. bool
  2165. atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
  2166. {
  2167. return __o->test_and_set(__m);
  2168. }
  2169. inline _LIBCPP_INLINE_VISIBILITY
  2170. bool
  2171. atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
  2172. {
  2173. return __o->test_and_set(__m);
  2174. }
  2175. inline _LIBCPP_INLINE_VISIBILITY
  2176. void
  2177. atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
  2178. {
  2179. __o->clear();
  2180. }
  2181. inline _LIBCPP_INLINE_VISIBILITY
  2182. void
  2183. atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
  2184. {
  2185. __o->clear();
  2186. }
  2187. inline _LIBCPP_INLINE_VISIBILITY
  2188. void
  2189. atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
  2190. {
  2191. __o->clear(__m);
  2192. }
  2193. inline _LIBCPP_INLINE_VISIBILITY
  2194. void
  2195. atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
  2196. {
  2197. __o->clear(__m);
  2198. }
  2199. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
  2200. void
  2201. atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
  2202. {
  2203. __o->wait(__v);
  2204. }
  2205. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
  2206. void
  2207. atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
  2208. {
  2209. __o->wait(__v);
  2210. }
  2211. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
  2212. void
  2213. atomic_flag_wait_explicit(const volatile atomic_flag* __o,
  2214. bool __v, memory_order __m) _NOEXCEPT
  2215. {
  2216. __o->wait(__v, __m);
  2217. }
  2218. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
  2219. void
  2220. atomic_flag_wait_explicit(const atomic_flag* __o,
  2221. bool __v, memory_order __m) _NOEXCEPT
  2222. {
  2223. __o->wait(__v, __m);
  2224. }
  2225. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
  2226. void
  2227. atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
  2228. {
  2229. __o->notify_one();
  2230. }
  2231. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
  2232. void
  2233. atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
  2234. {
  2235. __o->notify_one();
  2236. }
  2237. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
  2238. void
  2239. atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
  2240. {
  2241. __o->notify_all();
  2242. }
  2243. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
  2244. void
  2245. atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
  2246. {
  2247. __o->notify_all();
  2248. }
  2249. // fences
  2250. inline _LIBCPP_INLINE_VISIBILITY
  2251. void
  2252. atomic_thread_fence(memory_order __m) _NOEXCEPT
  2253. {
  2254. __cxx_atomic_thread_fence(__m);
  2255. }
  2256. inline _LIBCPP_INLINE_VISIBILITY
  2257. void
  2258. atomic_signal_fence(memory_order __m) _NOEXCEPT
  2259. {
  2260. __cxx_atomic_signal_fence(__m);
  2261. }
  2262. // Atomics for standard typedef types
  2263. typedef atomic<bool> atomic_bool;
  2264. typedef atomic<char> atomic_char;
  2265. typedef atomic<signed char> atomic_schar;
  2266. typedef atomic<unsigned char> atomic_uchar;
  2267. typedef atomic<short> atomic_short;
  2268. typedef atomic<unsigned short> atomic_ushort;
  2269. typedef atomic<int> atomic_int;
  2270. typedef atomic<unsigned int> atomic_uint;
  2271. typedef atomic<long> atomic_long;
  2272. typedef atomic<unsigned long> atomic_ulong;
  2273. typedef atomic<long long> atomic_llong;
  2274. typedef atomic<unsigned long long> atomic_ullong;
  2275. #ifndef _LIBCPP_HAS_NO_CHAR8_T
  2276. typedef atomic<char8_t> atomic_char8_t;
  2277. #endif
  2278. typedef atomic<char16_t> atomic_char16_t;
  2279. typedef atomic<char32_t> atomic_char32_t;
  2280. #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
  2281. typedef atomic<wchar_t> atomic_wchar_t;
  2282. #endif
  2283. typedef atomic<int_least8_t> atomic_int_least8_t;
  2284. typedef atomic<uint_least8_t> atomic_uint_least8_t;
  2285. typedef atomic<int_least16_t> atomic_int_least16_t;
  2286. typedef atomic<uint_least16_t> atomic_uint_least16_t;
  2287. typedef atomic<int_least32_t> atomic_int_least32_t;
  2288. typedef atomic<uint_least32_t> atomic_uint_least32_t;
  2289. typedef atomic<int_least64_t> atomic_int_least64_t;
  2290. typedef atomic<uint_least64_t> atomic_uint_least64_t;
  2291. typedef atomic<int_fast8_t> atomic_int_fast8_t;
  2292. typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
  2293. typedef atomic<int_fast16_t> atomic_int_fast16_t;
  2294. typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
  2295. typedef atomic<int_fast32_t> atomic_int_fast32_t;
  2296. typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
  2297. typedef atomic<int_fast64_t> atomic_int_fast64_t;
  2298. typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
  2299. typedef atomic< int8_t> atomic_int8_t;
  2300. typedef atomic<uint8_t> atomic_uint8_t;
  2301. typedef atomic< int16_t> atomic_int16_t;
  2302. typedef atomic<uint16_t> atomic_uint16_t;
  2303. typedef atomic< int32_t> atomic_int32_t;
  2304. typedef atomic<uint32_t> atomic_uint32_t;
  2305. typedef atomic< int64_t> atomic_int64_t;
  2306. typedef atomic<uint64_t> atomic_uint64_t;
  2307. typedef atomic<intptr_t> atomic_intptr_t;
  2308. typedef atomic<uintptr_t> atomic_uintptr_t;
  2309. typedef atomic<size_t> atomic_size_t;
  2310. typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
  2311. typedef atomic<intmax_t> atomic_intmax_t;
  2312. typedef atomic<uintmax_t> atomic_uintmax_t;
  2313. // atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
  2314. #ifdef __cpp_lib_atomic_is_always_lock_free
  2315. # define _LIBCPP_CONTENTION_LOCK_FREE ::std::__libcpp_is_always_lock_free<__cxx_contention_t>::__value
  2316. #else
  2317. # define _LIBCPP_CONTENTION_LOCK_FREE false
  2318. #endif
  2319. #if ATOMIC_LLONG_LOCK_FREE == 2
  2320. typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long> __libcpp_signed_lock_free;
  2321. typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long> __libcpp_unsigned_lock_free;
  2322. #elif ATOMIC_INT_LOCK_FREE == 2
  2323. typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int> __libcpp_signed_lock_free;
  2324. typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int> __libcpp_unsigned_lock_free;
  2325. #elif ATOMIC_SHORT_LOCK_FREE == 2
  2326. typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short> __libcpp_signed_lock_free;
  2327. typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short> __libcpp_unsigned_lock_free;
  2328. #elif ATOMIC_CHAR_LOCK_FREE == 2
  2329. typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char> __libcpp_signed_lock_free;
  2330. typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char> __libcpp_unsigned_lock_free;
  2331. #else
  2332. // No signed/unsigned lock-free types
  2333. #define _LIBCPP_NO_LOCK_FREE_TYPES
  2334. #endif
  2335. #if !defined(_LIBCPP_NO_LOCK_FREE_TYPES)
  2336. typedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free;
  2337. typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
  2338. #endif
  2339. #define ATOMIC_FLAG_INIT {false}
  2340. #define ATOMIC_VAR_INIT(__v) {__v}
  2341. #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
  2342. # if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1400
  2343. # pragma clang deprecated(ATOMIC_VAR_INIT)
  2344. # endif
  2345. #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
  2346. _LIBCPP_END_NAMESPACE_STD
  2347. #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
  2348. # include <cmath>
  2349. # include <compare>
  2350. # include <type_traits>
  2351. #endif
  2352. #endif // _LIBCPP_ATOMIC