12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735 |
- // -*- C++ -*-
- //===----------------------------------------------------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #ifndef _LIBCPP_ATOMIC
- #define _LIBCPP_ATOMIC
- /*
- atomic synopsis
- namespace std
- {
- // feature test macro [version.syn]
- #define __cpp_lib_atomic_is_always_lock_free
- #define __cpp_lib_atomic_flag_test
- #define __cpp_lib_atomic_lock_free_type_aliases
- #define __cpp_lib_atomic_wait
- // order and consistency
- enum memory_order: unspecified // enum class in C++20
- {
- relaxed,
- consume, // load-consume
- acquire, // load-acquire
- release, // store-release
- acq_rel, // store-release load-acquire
- seq_cst // store-release load-acquire
- };
- inline constexpr auto memory_order_relaxed = memory_order::relaxed;
- inline constexpr auto memory_order_consume = memory_order::consume;
- inline constexpr auto memory_order_acquire = memory_order::acquire;
- inline constexpr auto memory_order_release = memory_order::release;
- inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
- inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
- template <class T> T kill_dependency(T y) noexcept;
- // lock-free property
- #define ATOMIC_BOOL_LOCK_FREE unspecified
- #define ATOMIC_CHAR_LOCK_FREE unspecified
- #define ATOMIC_CHAR8_T_LOCK_FREE unspecified // C++20
- #define ATOMIC_CHAR16_T_LOCK_FREE unspecified
- #define ATOMIC_CHAR32_T_LOCK_FREE unspecified
- #define ATOMIC_WCHAR_T_LOCK_FREE unspecified
- #define ATOMIC_SHORT_LOCK_FREE unspecified
- #define ATOMIC_INT_LOCK_FREE unspecified
- #define ATOMIC_LONG_LOCK_FREE unspecified
- #define ATOMIC_LLONG_LOCK_FREE unspecified
- #define ATOMIC_POINTER_LOCK_FREE unspecified
- template <class T>
- struct atomic
- {
- using value_type = T;
- static constexpr bool is_always_lock_free;
- bool is_lock_free() const volatile noexcept;
- bool is_lock_free() const noexcept;
- atomic() noexcept = default; // until C++20
- constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>); // since C++20
- constexpr atomic(T desr) noexcept;
- atomic(const atomic&) = delete;
- atomic& operator=(const atomic&) = delete;
- atomic& operator=(const atomic&) volatile = delete;
- T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
- T load(memory_order m = memory_order_seq_cst) const noexcept;
- operator T() const volatile noexcept;
- operator T() const noexcept;
- void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
- void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
- T operator=(T) volatile noexcept;
- T operator=(T) noexcept;
- T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
- T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
- bool compare_exchange_weak(T& expc, T desr,
- memory_order s, memory_order f) volatile noexcept;
- bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
- bool compare_exchange_strong(T& expc, T desr,
- memory_order s, memory_order f) volatile noexcept;
- bool compare_exchange_strong(T& expc, T desr,
- memory_order s, memory_order f) noexcept;
- bool compare_exchange_weak(T& expc, T desr,
- memory_order m = memory_order_seq_cst) volatile noexcept;
- bool compare_exchange_weak(T& expc, T desr,
- memory_order m = memory_order_seq_cst) noexcept;
- bool compare_exchange_strong(T& expc, T desr,
- memory_order m = memory_order_seq_cst) volatile noexcept;
- bool compare_exchange_strong(T& expc, T desr,
- memory_order m = memory_order_seq_cst) noexcept;
- void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept;
- void wait(T, memory_order = memory_order::seq_cst) const noexcept;
- void notify_one() volatile noexcept;
- void notify_one() noexcept;
- void notify_all() volatile noexcept;
- void notify_all() noexcept;
- };
- template <>
- struct atomic<integral>
- {
- using value_type = integral;
- using difference_type = value_type;
- static constexpr bool is_always_lock_free;
- bool is_lock_free() const volatile noexcept;
- bool is_lock_free() const noexcept;
- atomic() noexcept = default;
- constexpr atomic(integral desr) noexcept;
- atomic(const atomic&) = delete;
- atomic& operator=(const atomic&) = delete;
- atomic& operator=(const atomic&) volatile = delete;
- integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
- integral load(memory_order m = memory_order_seq_cst) const noexcept;
- operator integral() const volatile noexcept;
- operator integral() const noexcept;
- void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
- void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
- integral operator=(integral desr) volatile noexcept;
- integral operator=(integral desr) noexcept;
- integral exchange(integral desr,
- memory_order m = memory_order_seq_cst) volatile noexcept;
- integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
- bool compare_exchange_weak(integral& expc, integral desr,
- memory_order s, memory_order f) volatile noexcept;
- bool compare_exchange_weak(integral& expc, integral desr,
- memory_order s, memory_order f) noexcept;
- bool compare_exchange_strong(integral& expc, integral desr,
- memory_order s, memory_order f) volatile noexcept;
- bool compare_exchange_strong(integral& expc, integral desr,
- memory_order s, memory_order f) noexcept;
- bool compare_exchange_weak(integral& expc, integral desr,
- memory_order m = memory_order_seq_cst) volatile noexcept;
- bool compare_exchange_weak(integral& expc, integral desr,
- memory_order m = memory_order_seq_cst) noexcept;
- bool compare_exchange_strong(integral& expc, integral desr,
- memory_order m = memory_order_seq_cst) volatile noexcept;
- bool compare_exchange_strong(integral& expc, integral desr,
- memory_order m = memory_order_seq_cst) noexcept;
- integral fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
- integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
- integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
- integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
- integral fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
- integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
- integral fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
- integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
- integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
- integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
- integral operator++(int) volatile noexcept;
- integral operator++(int) noexcept;
- integral operator--(int) volatile noexcept;
- integral operator--(int) noexcept;
- integral operator++() volatile noexcept;
- integral operator++() noexcept;
- integral operator--() volatile noexcept;
- integral operator--() noexcept;
- integral operator+=(integral op) volatile noexcept;
- integral operator+=(integral op) noexcept;
- integral operator-=(integral op) volatile noexcept;
- integral operator-=(integral op) noexcept;
- integral operator&=(integral op) volatile noexcept;
- integral operator&=(integral op) noexcept;
- integral operator|=(integral op) volatile noexcept;
- integral operator|=(integral op) noexcept;
- integral operator^=(integral op) volatile noexcept;
- integral operator^=(integral op) noexcept;
- void wait(integral, memory_order = memory_order::seq_cst) const volatile noexcept;
- void wait(integral, memory_order = memory_order::seq_cst) const noexcept;
- void notify_one() volatile noexcept;
- void notify_one() noexcept;
- void notify_all() volatile noexcept;
- void notify_all() noexcept;
- };
- template <class T>
- struct atomic<T*>
- {
- using value_type = T*;
- using difference_type = ptrdiff_t;
- static constexpr bool is_always_lock_free;
- bool is_lock_free() const volatile noexcept;
- bool is_lock_free() const noexcept;
- atomic() noexcept = default; // until C++20
- constexpr atomic() noexcept; // since C++20
- constexpr atomic(T* desr) noexcept;
- atomic(const atomic&) = delete;
- atomic& operator=(const atomic&) = delete;
- atomic& operator=(const atomic&) volatile = delete;
- T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
- T* load(memory_order m = memory_order_seq_cst) const noexcept;
- operator T*() const volatile noexcept;
- operator T*() const noexcept;
- void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
- void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
- T* operator=(T*) volatile noexcept;
- T* operator=(T*) noexcept;
- T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
- T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
- bool compare_exchange_weak(T*& expc, T* desr,
- memory_order s, memory_order f) volatile noexcept;
- bool compare_exchange_weak(T*& expc, T* desr,
- memory_order s, memory_order f) noexcept;
- bool compare_exchange_strong(T*& expc, T* desr,
- memory_order s, memory_order f) volatile noexcept;
- bool compare_exchange_strong(T*& expc, T* desr,
- memory_order s, memory_order f) noexcept;
- bool compare_exchange_weak(T*& expc, T* desr,
- memory_order m = memory_order_seq_cst) volatile noexcept;
- bool compare_exchange_weak(T*& expc, T* desr,
- memory_order m = memory_order_seq_cst) noexcept;
- bool compare_exchange_strong(T*& expc, T* desr,
- memory_order m = memory_order_seq_cst) volatile noexcept;
- bool compare_exchange_strong(T*& expc, T* desr,
- memory_order m = memory_order_seq_cst) noexcept;
- T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
- T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
- T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
- T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
- T* operator++(int) volatile noexcept;
- T* operator++(int) noexcept;
- T* operator--(int) volatile noexcept;
- T* operator--(int) noexcept;
- T* operator++() volatile noexcept;
- T* operator++() noexcept;
- T* operator--() volatile noexcept;
- T* operator--() noexcept;
- T* operator+=(ptrdiff_t op) volatile noexcept;
- T* operator+=(ptrdiff_t op) noexcept;
- T* operator-=(ptrdiff_t op) volatile noexcept;
- T* operator-=(ptrdiff_t op) noexcept;
- void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept;
- void wait(T*, memory_order = memory_order::seq_cst) const noexcept;
- void notify_one() volatile noexcept;
- void notify_one() noexcept;
- void notify_all() volatile noexcept;
- void notify_all() noexcept;
- };
- // [atomics.nonmembers], non-member functions
- template<class T>
- bool atomic_is_lock_free(const volatile atomic<T>*) noexcept;
- template<class T>
- bool atomic_is_lock_free(const atomic<T>*) noexcept;
- template<class T>
- void atomic_store(volatile atomic<T>*, atomic<T>::value_type) noexcept;
- template<class T>
- void atomic_store(atomic<T>*, atomic<T>::value_type) noexcept;
- template<class T>
- void atomic_store_explicit(volatile atomic<T>*, atomic<T>::value_type,
- memory_order) noexcept;
- template<class T>
- void atomic_store_explicit(atomic<T>*, atomic<T>::value_type,
- memory_order) noexcept;
- template<class T>
- T atomic_load(const volatile atomic<T>*) noexcept;
- template<class T>
- T atomic_load(const atomic<T>*) noexcept;
- template<class T>
- T atomic_load_explicit(const volatile atomic<T>*, memory_order) noexcept;
- template<class T>
- T atomic_load_explicit(const atomic<T>*, memory_order) noexcept;
- template<class T>
- T atomic_exchange(volatile atomic<T>*, atomic<T>::value_type) noexcept;
- template<class T>
- T atomic_exchange(atomic<T>*, atomic<T>::value_type) noexcept;
- template<class T>
- T atomic_exchange_explicit(volatile atomic<T>*, atomic<T>::value_type,
- memory_order) noexcept;
- template<class T>
- T atomic_exchange_explicit(atomic<T>*, atomic<T>::value_type,
- memory_order) noexcept;
- template<class T>
- bool atomic_compare_exchange_weak(volatile atomic<T>*, atomic<T>::value_type*,
- atomic<T>::value_type) noexcept;
- template<class T>
- bool atomic_compare_exchange_weak(atomic<T>*, atomic<T>::value_type*,
- atomic<T>::value_type) noexcept;
- template<class T>
- bool atomic_compare_exchange_strong(volatile atomic<T>*, atomic<T>::value_type*,
- atomic<T>::value_type) noexcept;
- template<class T>
- bool atomic_compare_exchange_strong(atomic<T>*, atomic<T>::value_type*,
- atomic<T>::value_type) noexcept;
- template<class T>
- bool atomic_compare_exchange_weak_explicit(volatile atomic<T>*, atomic<T>::value_type*,
- atomic<T>::value_type,
- memory_order, memory_order) noexcept;
- template<class T>
- bool atomic_compare_exchange_weak_explicit(atomic<T>*, atomic<T>::value_type*,
- atomic<T>::value_type,
- memory_order, memory_order) noexcept;
- template<class T>
- bool atomic_compare_exchange_strong_explicit(volatile atomic<T>*, atomic<T>::value_type*,
- atomic<T>::value_type,
- memory_order, memory_order) noexcept;
- template<class T>
- bool atomic_compare_exchange_strong_explicit(atomic<T>*, atomic<T>::value_type*,
- atomic<T>::value_type,
- memory_order, memory_order) noexcept;
- template<class T>
- T atomic_fetch_add(volatile atomic<T>*, atomic<T>::difference_type) noexcept;
- template<class T>
- T atomic_fetch_add(atomic<T>*, atomic<T>::difference_type) noexcept;
- template<class T>
- T atomic_fetch_add_explicit(volatile atomic<T>*, atomic<T>::difference_type,
- memory_order) noexcept;
- template<class T>
- T atomic_fetch_add_explicit(atomic<T>*, atomic<T>::difference_type,
- memory_order) noexcept;
- template<class T>
- T atomic_fetch_sub(volatile atomic<T>*, atomic<T>::difference_type) noexcept;
- template<class T>
- T atomic_fetch_sub(atomic<T>*, atomic<T>::difference_type) noexcept;
- template<class T>
- T atomic_fetch_sub_explicit(volatile atomic<T>*, atomic<T>::difference_type,
- memory_order) noexcept;
- template<class T>
- T atomic_fetch_sub_explicit(atomic<T>*, atomic<T>::difference_type,
- memory_order) noexcept;
- template<class T>
- T atomic_fetch_and(volatile atomic<T>*, atomic<T>::value_type) noexcept;
- template<class T>
- T atomic_fetch_and(atomic<T>*, atomic<T>::value_type) noexcept;
- template<class T>
- T atomic_fetch_and_explicit(volatile atomic<T>*, atomic<T>::value_type,
- memory_order) noexcept;
- template<class T>
- T atomic_fetch_and_explicit(atomic<T>*, atomic<T>::value_type,
- memory_order) noexcept;
- template<class T>
- T atomic_fetch_or(volatile atomic<T>*, atomic<T>::value_type) noexcept;
- template<class T>
- T atomic_fetch_or(atomic<T>*, atomic<T>::value_type) noexcept;
- template<class T>
- T atomic_fetch_or_explicit(volatile atomic<T>*, atomic<T>::value_type,
- memory_order) noexcept;
- template<class T>
- T atomic_fetch_or_explicit(atomic<T>*, atomic<T>::value_type,
- memory_order) noexcept;
- template<class T>
- T atomic_fetch_xor(volatile atomic<T>*, atomic<T>::value_type) noexcept;
- template<class T>
- T atomic_fetch_xor(atomic<T>*, atomic<T>::value_type) noexcept;
- template<class T>
- T atomic_fetch_xor_explicit(volatile atomic<T>*, atomic<T>::value_type,
- memory_order) noexcept;
- template<class T>
- T atomic_fetch_xor_explicit(atomic<T>*, atomic<T>::value_type,
- memory_order) noexcept;
- template<class T>
- void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type);
- template<class T>
- void atomic_wait(const atomic<T>*, atomic<T>::value_type);
- template<class T>
- void atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type,
- memory_order);
- template<class T>
- void atomic_wait_explicit(const atomic<T>*, atomic<T>::value_type,
- memory_order);
- template<class T>
- void atomic_notify_one(volatile atomic<T>*);
- template<class T>
- void atomic_notify_one(atomic<T>*);
- template<class T>
- void atomic_notify_all(volatile atomic<T>*);
- template<class T>
- void atomic_notify_all(atomic<T>*);
- // Atomics for standard typedef types
- typedef atomic<bool> atomic_bool;
- typedef atomic<char> atomic_char;
- typedef atomic<signed char> atomic_schar;
- typedef atomic<unsigned char> atomic_uchar;
- typedef atomic<short> atomic_short;
- typedef atomic<unsigned short> atomic_ushort;
- typedef atomic<int> atomic_int;
- typedef atomic<unsigned int> atomic_uint;
- typedef atomic<long> atomic_long;
- typedef atomic<unsigned long> atomic_ulong;
- typedef atomic<long long> atomic_llong;
- typedef atomic<unsigned long long> atomic_ullong;
- typedef atomic<char8_t> atomic_char8_t; // C++20
- typedef atomic<char16_t> atomic_char16_t;
- typedef atomic<char32_t> atomic_char32_t;
- typedef atomic<wchar_t> atomic_wchar_t;
- typedef atomic<int_least8_t> atomic_int_least8_t;
- typedef atomic<uint_least8_t> atomic_uint_least8_t;
- typedef atomic<int_least16_t> atomic_int_least16_t;
- typedef atomic<uint_least16_t> atomic_uint_least16_t;
- typedef atomic<int_least32_t> atomic_int_least32_t;
- typedef atomic<uint_least32_t> atomic_uint_least32_t;
- typedef atomic<int_least64_t> atomic_int_least64_t;
- typedef atomic<uint_least64_t> atomic_uint_least64_t;
- typedef atomic<int_fast8_t> atomic_int_fast8_t;
- typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
- typedef atomic<int_fast16_t> atomic_int_fast16_t;
- typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
- typedef atomic<int_fast32_t> atomic_int_fast32_t;
- typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
- typedef atomic<int_fast64_t> atomic_int_fast64_t;
- typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
- typedef atomic<int8_t> atomic_int8_t;
- typedef atomic<uint8_t> atomic_uint8_t;
- typedef atomic<int16_t> atomic_int16_t;
- typedef atomic<uint16_t> atomic_uint16_t;
- typedef atomic<int32_t> atomic_int32_t;
- typedef atomic<uint32_t> atomic_uint32_t;
- typedef atomic<int64_t> atomic_int64_t;
- typedef atomic<uint64_t> atomic_uint64_t;
- typedef atomic<intptr_t> atomic_intptr_t;
- typedef atomic<uintptr_t> atomic_uintptr_t;
- typedef atomic<size_t> atomic_size_t;
- typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
- typedef atomic<intmax_t> atomic_intmax_t;
- typedef atomic<uintmax_t> atomic_uintmax_t;
- // flag type and operations
- typedef struct atomic_flag
- {
- atomic_flag() noexcept = default; // until C++20
- constexpr atomic_flag() noexcept; // since C++20
- atomic_flag(const atomic_flag&) = delete;
- atomic_flag& operator=(const atomic_flag&) = delete;
- atomic_flag& operator=(const atomic_flag&) volatile = delete;
- bool test(memory_order m = memory_order_seq_cst) volatile noexcept;
- bool test(memory_order m = memory_order_seq_cst) noexcept;
- bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
- bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
- void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
- void clear(memory_order m = memory_order_seq_cst) noexcept;
- void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept;
- void wait(bool, memory_order = memory_order::seq_cst) const noexcept;
- void notify_one() volatile noexcept;
- void notify_one() noexcept;
- void notify_all() volatile noexcept;
- void notify_all() noexcept;
- } atomic_flag;
- bool atomic_flag_test(volatile atomic_flag* obj) noexcept;
- bool atomic_flag_test(atomic_flag* obj) noexcept;
- bool atomic_flag_test_explicit(volatile atomic_flag* obj,
- memory_order m) noexcept;
- bool atomic_flag_test_explicit(atomic_flag* obj, memory_order m) noexcept;
- bool atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
- bool atomic_flag_test_and_set(atomic_flag* obj) noexcept;
- bool atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
- memory_order m) noexcept;
- bool atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
- void atomic_flag_clear(volatile atomic_flag* obj) noexcept;
- void atomic_flag_clear(atomic_flag* obj) noexcept;
- void atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
- void atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
- void atomic_wait(const volatile atomic_flag* obj, T old) noexcept;
- void atomic_wait(const atomic_flag* obj, T old) noexcept;
- void atomic_wait_explicit(const volatile atomic_flag* obj, T old, memory_order m) noexcept;
- void atomic_wait_explicit(const atomic_flag* obj, T old, memory_order m) noexcept;
- void atomic_one(volatile atomic_flag* obj) noexcept;
- void atomic_one(atomic_flag* obj) noexcept;
- void atomic_all(volatile atomic_flag* obj) noexcept;
- void atomic_all(atomic_flag* obj) noexcept;
- // fences
- void atomic_thread_fence(memory_order m) noexcept;
- void atomic_signal_fence(memory_order m) noexcept;
- // deprecated
- template <class T>
- void atomic_init(volatile atomic<T>* obj, atomic<T>::value_type desr) noexcept;
- template <class T>
- void atomic_init(atomic<T>* obj, atomic<T>::value_type desr) noexcept;
- #define ATOMIC_VAR_INIT(value) see below
- #define ATOMIC_FLAG_INIT see below
- } // std
- */
- #include <__availability>
- #include <__config>
- #include <__thread/poll_with_backoff.h>
- #include <__thread/timed_backoff_policy.h>
- #include <cstddef>
- #include <cstdint>
- #include <cstring>
- #include <type_traits>
- #include <version>
- #ifndef _LIBCPP_HAS_NO_THREADS
- # include <__threading_support>
- #endif
- #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
- # pragma GCC system_header
- #endif
- #ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
- # error <atomic> is not implemented
- #endif
- #ifdef kill_dependency
- # error C++ standard library is incompatible with <stdatomic.h>
- #endif
- #define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
- _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
- __m == memory_order_acquire || \
- __m == memory_order_acq_rel, \
- "memory order argument to atomic operation is invalid")
- #define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
- _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
- __m == memory_order_acq_rel, \
- "memory order argument to atomic operation is invalid")
- #define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
- _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
- __f == memory_order_acq_rel, \
- "memory order argument to atomic operation is invalid")
- _LIBCPP_BEGIN_NAMESPACE_STD
- // Figure out what the underlying type for `memory_order` would be if it were
- // declared as an unscoped enum (accounting for -fshort-enums). Use this result
- // to pin the underlying type in C++20.
- enum __legacy_memory_order {
- __mo_relaxed,
- __mo_consume,
- __mo_acquire,
- __mo_release,
- __mo_acq_rel,
- __mo_seq_cst
- };
- typedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t;
- #if _LIBCPP_STD_VER > 17
- enum class memory_order : __memory_order_underlying_t {
- relaxed = __mo_relaxed,
- consume = __mo_consume,
- acquire = __mo_acquire,
- release = __mo_release,
- acq_rel = __mo_acq_rel,
- seq_cst = __mo_seq_cst
- };
- inline constexpr auto memory_order_relaxed = memory_order::relaxed;
- inline constexpr auto memory_order_consume = memory_order::consume;
- inline constexpr auto memory_order_acquire = memory_order::acquire;
- inline constexpr auto memory_order_release = memory_order::release;
- inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
- inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
- #else
- typedef enum memory_order {
- memory_order_relaxed = __mo_relaxed,
- memory_order_consume = __mo_consume,
- memory_order_acquire = __mo_acquire,
- memory_order_release = __mo_release,
- memory_order_acq_rel = __mo_acq_rel,
- memory_order_seq_cst = __mo_seq_cst,
- } memory_order;
- #endif // _LIBCPP_STD_VER > 17
- template <typename _Tp> _LIBCPP_INLINE_VISIBILITY
- bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
- return _VSTD::memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0;
- }
- static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
- "unexpected underlying type for std::memory_order");
- #if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
- defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
- // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
- // the default operator= in an object is not volatile, a byte-by-byte copy
- // is required.
- template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
- typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
- __cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
- __a_value = __val;
- }
- template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
- typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
- __cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
- volatile char* __to = reinterpret_cast<volatile char*>(&__a_value);
- volatile char* __end = __to + sizeof(_Tp);
- volatile const char* __from = reinterpret_cast<volatile const char*>(&__val);
- while (__to != __end)
- *__to++ = *__from++;
- }
- #endif
- #if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
- template <typename _Tp>
- struct __cxx_atomic_base_impl {
- _LIBCPP_INLINE_VISIBILITY
- #ifndef _LIBCPP_CXX03_LANG
- __cxx_atomic_base_impl() _NOEXCEPT = default;
- #else
- __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
- #endif // _LIBCPP_CXX03_LANG
- _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
- : __a_value(value) {}
- _Tp __a_value;
- };
- _LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
- // Avoid switch statement to make this a constexpr.
- return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
- (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
- (__order == memory_order_release ? __ATOMIC_RELEASE:
- (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
- (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
- __ATOMIC_CONSUME))));
- }
- _LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
- // Avoid switch statement to make this a constexpr.
- return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
- (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
- (__order == memory_order_release ? __ATOMIC_RELAXED:
- (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
- (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
- __ATOMIC_CONSUME))));
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
- __cxx_atomic_assign_volatile(__a->__a_value, __val);
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
- __a->__a_value = __val;
- }
- _LIBCPP_INLINE_VISIBILITY inline
- void __cxx_atomic_thread_fence(memory_order __order) {
- __atomic_thread_fence(__to_gcc_order(__order));
- }
- _LIBCPP_INLINE_VISIBILITY inline
- void __cxx_atomic_signal_fence(memory_order __order) {
- __atomic_signal_fence(__to_gcc_order(__order));
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
- memory_order __order) {
- __atomic_store(&__a->__a_value, &__val,
- __to_gcc_order(__order));
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
- memory_order __order) {
- __atomic_store(&__a->__a_value, &__val,
- __to_gcc_order(__order));
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
- memory_order __order) {
- _Tp __ret;
- __atomic_load(&__a->__a_value, &__ret,
- __to_gcc_order(__order));
- return __ret;
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
- _Tp __ret;
- __atomic_load(&__a->__a_value, &__ret,
- __to_gcc_order(__order));
- return __ret;
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
- _Tp __value, memory_order __order) {
- _Tp __ret;
- __atomic_exchange(&__a->__a_value, &__value, &__ret,
- __to_gcc_order(__order));
- return __ret;
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
- memory_order __order) {
- _Tp __ret;
- __atomic_exchange(&__a->__a_value, &__value, &__ret,
- __to_gcc_order(__order));
- return __ret;
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool __cxx_atomic_compare_exchange_strong(
- volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
- memory_order __success, memory_order __failure) {
- return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
- false,
- __to_gcc_order(__success),
- __to_gcc_failure_order(__failure));
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool __cxx_atomic_compare_exchange_strong(
- __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
- memory_order __failure) {
- return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
- false,
- __to_gcc_order(__success),
- __to_gcc_failure_order(__failure));
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool __cxx_atomic_compare_exchange_weak(
- volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
- memory_order __success, memory_order __failure) {
- return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
- true,
- __to_gcc_order(__success),
- __to_gcc_failure_order(__failure));
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool __cxx_atomic_compare_exchange_weak(
- __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
- memory_order __failure) {
- return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
- true,
- __to_gcc_order(__success),
- __to_gcc_failure_order(__failure));
- }
- template <typename _Tp>
- struct __skip_amt { enum {value = 1}; };
- template <typename _Tp>
- struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
- // FIXME: Haven't figured out what the spec says about using arrays with
- // atomic_fetch_add. Force a failure rather than creating bad behavior.
- template <typename _Tp>
- struct __skip_amt<_Tp[]> { };
- template <typename _Tp, int n>
- struct __skip_amt<_Tp[n]> { };
- template <typename _Tp, typename _Td>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
- _Td __delta, memory_order __order) {
- return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
- __to_gcc_order(__order));
- }
- template <typename _Tp, typename _Td>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
- memory_order __order) {
- return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
- __to_gcc_order(__order));
- }
- template <typename _Tp, typename _Td>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
- _Td __delta, memory_order __order) {
- return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
- __to_gcc_order(__order));
- }
- template <typename _Tp, typename _Td>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
- memory_order __order) {
- return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
- __to_gcc_order(__order));
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
- _Tp __pattern, memory_order __order) {
- return __atomic_fetch_and(&__a->__a_value, __pattern,
- __to_gcc_order(__order));
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
- _Tp __pattern, memory_order __order) {
- return __atomic_fetch_and(&__a->__a_value, __pattern,
- __to_gcc_order(__order));
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
- _Tp __pattern, memory_order __order) {
- return __atomic_fetch_or(&__a->__a_value, __pattern,
- __to_gcc_order(__order));
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
- memory_order __order) {
- return __atomic_fetch_or(&__a->__a_value, __pattern,
- __to_gcc_order(__order));
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
- _Tp __pattern, memory_order __order) {
- return __atomic_fetch_xor(&__a->__a_value, __pattern,
- __to_gcc_order(__order));
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
- memory_order __order) {
- return __atomic_fetch_xor(&__a->__a_value, __pattern,
- __to_gcc_order(__order));
- }
- #define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
- #elif defined(_LIBCPP_HAS_C_ATOMIC_IMP) || defined(_LIBCPP_COMPILER_MSVC)
- #if defined(_LIBCPP_COMPILER_MSVC)
- _LIBCPP_END_NAMESPACE_STD
- #include <__support/win32/atomic_win32.h>
- _LIBCPP_BEGIN_NAMESPACE_STD
- #endif
- template <typename _Tp>
- struct __cxx_atomic_base_impl {
- _LIBCPP_INLINE_VISIBILITY
- #ifndef _LIBCPP_CXX03_LANG
- __cxx_atomic_base_impl() _NOEXCEPT = default;
- #else
- __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
- #endif // _LIBCPP_CXX03_LANG
- _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
- : __a_value(value) {}
- _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
- };
- #define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
- #ifdef _LIBCPP_COMPILER_MSVC
- #pragma warning ( push )
- #pragma warning ( disable : 4141 )
- #endif
- _LIBCPP_INLINE_VISIBILITY inline
- void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
- __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
- }
- _LIBCPP_INLINE_VISIBILITY inline
- void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
- __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
- }
- #ifdef _LIBCPP_COMPILER_MSVC
- #pragma warning ( pop )
- #endif
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
- __c11_atomic_init(&__a->__a_value, __val);
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
- __c11_atomic_init(&__a->__a_value, __val);
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
- __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
- __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
- using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
- return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
- using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
- return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
- return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
- return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
- }
- // Disable double inline warning
- #ifdef _LIBCPP_COMPILER_MSVC
- #pragma warning ( push )
- #pragma warning ( disable : 4141 )
- #endif
- _LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
- // Avoid switch statement to make this a constexpr.
- return __order == memory_order_release ? memory_order_relaxed:
- (__order == memory_order_acq_rel ? memory_order_acquire:
- __order);
- }
- #ifdef _LIBCPP_COMPILER_MSVC
- #pragma warning ( pop )
- #endif
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
- 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)));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
- 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)));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
- 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)));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
- 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)));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
- return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
- return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
- return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
- return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
- return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
- return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
- return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
- return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
- return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
- return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
- return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
- return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
- return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
- }
- template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
- return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
- }
- #endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp kill_dependency(_Tp __y) _NOEXCEPT
- {
- return __y;
- }
- #if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
- # define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
- # define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
- #ifndef _LIBCPP_HAS_NO_CHAR8_T
- # define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
- #endif
- # define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
- # define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
- # define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
- # define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
- # define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
- # define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
- # define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
- # define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
- #elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
- # define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
- # define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
- #ifndef _LIBCPP_HAS_NO_CHAR8_T
- # define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
- #endif
- # define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
- # define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
- # define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
- # define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
- # define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
- # define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
- # define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
- # define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
- #endif
- #ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
- template<typename _Tp>
- struct __cxx_atomic_lock_impl {
- _LIBCPP_INLINE_VISIBILITY
- __cxx_atomic_lock_impl() _NOEXCEPT
- : __a_value(), __a_lock(0) {}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit
- __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
- : __a_value(value), __a_lock(0) {}
- _Tp __a_value;
- mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
- _LIBCPP_INLINE_VISIBILITY void __lock() const volatile {
- while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
- /*spin*/;
- }
- _LIBCPP_INLINE_VISIBILITY void __lock() const {
- while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
- /*spin*/;
- }
- _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile {
- __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
- }
- _LIBCPP_INLINE_VISIBILITY void __unlock() const {
- __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
- }
- _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile {
- __lock();
- _Tp __old;
- __cxx_atomic_assign_volatile(__old, __a_value);
- __unlock();
- return __old;
- }
- _LIBCPP_INLINE_VISIBILITY _Tp __read() const {
- __lock();
- _Tp __old = __a_value;
- __unlock();
- return __old;
- }
- };
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
- __cxx_atomic_assign_volatile(__a->__a_value, __val);
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
- __a->__a_value = __val;
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
- __a->__lock();
- __cxx_atomic_assign_volatile(__a->__a_value, __val);
- __a->__unlock();
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
- __a->__lock();
- __a->__a_value = __val;
- __a->__unlock();
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
- return __a->__read();
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
- return __a->__read();
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
- __a->__lock();
- _Tp __old;
- __cxx_atomic_assign_volatile(__old, __a->__a_value);
- __cxx_atomic_assign_volatile(__a->__a_value, __value);
- __a->__unlock();
- return __old;
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
- __a->__lock();
- _Tp __old = __a->__a_value;
- __a->__a_value = __value;
- __a->__unlock();
- return __old;
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
- _Tp* __expected, _Tp __value, memory_order, memory_order) {
- _Tp __temp;
- __a->__lock();
- __cxx_atomic_assign_volatile(__temp, __a->__a_value);
- bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
- if(__ret)
- __cxx_atomic_assign_volatile(__a->__a_value, __value);
- else
- __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
- __a->__unlock();
- return __ret;
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
- _Tp* __expected, _Tp __value, memory_order, memory_order) {
- __a->__lock();
- bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
- if(__ret)
- _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
- else
- _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
- __a->__unlock();
- return __ret;
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
- _Tp* __expected, _Tp __value, memory_order, memory_order) {
- _Tp __temp;
- __a->__lock();
- __cxx_atomic_assign_volatile(__temp, __a->__a_value);
- bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
- if(__ret)
- __cxx_atomic_assign_volatile(__a->__a_value, __value);
- else
- __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
- __a->__unlock();
- return __ret;
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
- _Tp* __expected, _Tp __value, memory_order, memory_order) {
- __a->__lock();
- bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
- if(__ret)
- _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
- else
- _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
- __a->__unlock();
- return __ret;
- }
- template <typename _Tp, typename _Td>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
- _Td __delta, memory_order) {
- __a->__lock();
- _Tp __old;
- __cxx_atomic_assign_volatile(__old, __a->__a_value);
- __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
- __a->__unlock();
- return __old;
- }
- template <typename _Tp, typename _Td>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
- _Td __delta, memory_order) {
- __a->__lock();
- _Tp __old = __a->__a_value;
- __a->__a_value += __delta;
- __a->__unlock();
- return __old;
- }
- template <typename _Tp, typename _Td>
- _LIBCPP_INLINE_VISIBILITY
- _Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
- ptrdiff_t __delta, memory_order) {
- __a->__lock();
- _Tp* __old;
- __cxx_atomic_assign_volatile(__old, __a->__a_value);
- __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
- __a->__unlock();
- return __old;
- }
- template <typename _Tp, typename _Td>
- _LIBCPP_INLINE_VISIBILITY
- _Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
- ptrdiff_t __delta, memory_order) {
- __a->__lock();
- _Tp* __old = __a->__a_value;
- __a->__a_value += __delta;
- __a->__unlock();
- return __old;
- }
- template <typename _Tp, typename _Td>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
- _Td __delta, memory_order) {
- __a->__lock();
- _Tp __old;
- __cxx_atomic_assign_volatile(__old, __a->__a_value);
- __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
- __a->__unlock();
- return __old;
- }
- template <typename _Tp, typename _Td>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
- _Td __delta, memory_order) {
- __a->__lock();
- _Tp __old = __a->__a_value;
- __a->__a_value -= __delta;
- __a->__unlock();
- return __old;
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
- _Tp __pattern, memory_order) {
- __a->__lock();
- _Tp __old;
- __cxx_atomic_assign_volatile(__old, __a->__a_value);
- __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
- __a->__unlock();
- return __old;
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
- _Tp __pattern, memory_order) {
- __a->__lock();
- _Tp __old = __a->__a_value;
- __a->__a_value &= __pattern;
- __a->__unlock();
- return __old;
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
- _Tp __pattern, memory_order) {
- __a->__lock();
- _Tp __old;
- __cxx_atomic_assign_volatile(__old, __a->__a_value);
- __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
- __a->__unlock();
- return __old;
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
- _Tp __pattern, memory_order) {
- __a->__lock();
- _Tp __old = __a->__a_value;
- __a->__a_value |= __pattern;
- __a->__unlock();
- return __old;
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
- _Tp __pattern, memory_order) {
- __a->__lock();
- _Tp __old;
- __cxx_atomic_assign_volatile(__old, __a->__a_value);
- __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
- __a->__unlock();
- return __old;
- }
- template <typename _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
- _Tp __pattern, memory_order) {
- __a->__lock();
- _Tp __old = __a->__a_value;
- __a->__a_value ^= __pattern;
- __a->__unlock();
- return __old;
- }
- #ifdef __cpp_lib_atomic_is_always_lock_free
- template<typename _Tp> struct __cxx_is_always_lock_free {
- enum { __value = __atomic_always_lock_free(sizeof(_Tp), 0) }; };
- #else
- template<typename _Tp> struct __cxx_is_always_lock_free { enum { __value = false }; };
- // Implementations must match the C ATOMIC_*_LOCK_FREE macro values.
- template<> struct __cxx_is_always_lock_free<bool> { enum { __value = 2 == ATOMIC_BOOL_LOCK_FREE }; };
- template<> struct __cxx_is_always_lock_free<char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
- template<> struct __cxx_is_always_lock_free<signed char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
- template<> struct __cxx_is_always_lock_free<unsigned char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
- #ifndef _LIBCPP_HAS_NO_CHAR8_T
- template<> struct __cxx_is_always_lock_free<char8_t> { enum { __value = 2 == ATOMIC_CHAR8_T_LOCK_FREE }; };
- #endif
- template<> struct __cxx_is_always_lock_free<char16_t> { enum { __value = 2 == ATOMIC_CHAR16_T_LOCK_FREE }; };
- template<> struct __cxx_is_always_lock_free<char32_t> { enum { __value = 2 == ATOMIC_CHAR32_T_LOCK_FREE }; };
- #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
- template<> struct __cxx_is_always_lock_free<wchar_t> { enum { __value = 2 == ATOMIC_WCHAR_T_LOCK_FREE }; };
- #endif
- template<> struct __cxx_is_always_lock_free<short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
- template<> struct __cxx_is_always_lock_free<unsigned short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
- template<> struct __cxx_is_always_lock_free<int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
- template<> struct __cxx_is_always_lock_free<unsigned int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
- template<> struct __cxx_is_always_lock_free<long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
- template<> struct __cxx_is_always_lock_free<unsigned long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
- template<> struct __cxx_is_always_lock_free<long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
- template<> struct __cxx_is_always_lock_free<unsigned long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
- template<typename _Tp> struct __cxx_is_always_lock_free<_Tp*> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
- template<> struct __cxx_is_always_lock_free<std::nullptr_t> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
- #endif //__cpp_lib_atomic_is_always_lock_free
- template <typename _Tp,
- typename _Base = typename conditional<__cxx_is_always_lock_free<_Tp>::__value,
- __cxx_atomic_base_impl<_Tp>,
- __cxx_atomic_lock_impl<_Tp> >::type>
- #else
- template <typename _Tp,
- typename _Base = __cxx_atomic_base_impl<_Tp> >
- #endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
- struct __cxx_atomic_impl : public _Base {
- static_assert(is_trivially_copyable<_Tp>::value,
- "std::atomic<T> requires that 'T' be a trivially copyable type");
- _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT = default;
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT
- : _Base(value) {}
- };
- #ifdef __linux__
- using __cxx_contention_t = int32_t;
- #else
- using __cxx_contention_t = int64_t;
- #endif //__linux__
- using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
- #if defined(_LIBCPP_HAS_NO_THREADS)
- # define _LIBCPP_HAS_NO_PLATFORM_WAIT
- #endif
- // TODO:
- // _LIBCPP_HAS_NO_PLATFORM_WAIT is currently a "dead" macro, in the sense that
- // it is not tied anywhere into the build system or even documented. We should
- // clean it up because it is technically never defined except when threads are
- // disabled. We should clean it up in its own changeset in case we break "bad"
- // users.
- #ifndef _LIBCPP_HAS_NO_PLATFORM_WAIT
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t);
- template <class _Atp, class _Fn>
- struct __libcpp_atomic_wait_backoff_impl {
- _Atp* __a;
- _Fn __test_fn;
- _LIBCPP_AVAILABILITY_SYNC
- _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const
- {
- if(__elapsed > chrono::microseconds(64))
- {
- auto const __monitor = __libcpp_atomic_monitor(__a);
- if(__test_fn())
- return true;
- __libcpp_atomic_wait(__a, __monitor);
- }
- else if(__elapsed > chrono::microseconds(4))
- __libcpp_thread_yield();
- else
- {} // poll
- return false;
- }
- };
- template <class _Atp, class _Fn>
- _LIBCPP_AVAILABILITY_SYNC
- _LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
- {
- __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn};
- return __libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
- }
- #else // _LIBCPP_HAS_NO_PLATFORM_WAIT
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
- template <class _Atp, class _Fn>
- _LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
- {
- #if defined(_LIBCPP_HAS_NO_THREADS)
- using _Policy = __spinning_backoff_policy;
- #else
- using _Policy = __libcpp_timed_backoff_policy;
- #endif
- return __libcpp_thread_poll_with_backoff(__test_fn, _Policy());
- }
- #endif // _LIBCPP_HAS_NO_PLATFORM_WAIT
- template <class _Atp, class _Tp>
- struct __cxx_atomic_wait_test_fn_impl {
- _Atp* __a;
- _Tp __val;
- memory_order __order;
- _LIBCPP_INLINE_VISIBILITY bool operator()() const
- {
- return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__a, __order), __val);
- }
- };
- template <class _Atp, class _Tp>
- _LIBCPP_AVAILABILITY_SYNC
- _LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
- {
- __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
- return __cxx_atomic_wait(__a, __test_fn);
- }
- // general atomic<T>
- template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
- struct __atomic_base // false
- {
- mutable __cxx_atomic_impl<_Tp> __a_;
- #if defined(__cpp_lib_atomic_is_always_lock_free)
- static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0);
- #endif
- _LIBCPP_INLINE_VISIBILITY
- bool is_lock_free() const volatile _NOEXCEPT
- {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
- _LIBCPP_INLINE_VISIBILITY
- bool is_lock_free() const _NOEXCEPT
- {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
- _LIBCPP_INLINE_VISIBILITY
- void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
- {__cxx_atomic_store(&__a_, __d, __m);}
- _LIBCPP_INLINE_VISIBILITY
- void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
- _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
- {__cxx_atomic_store(&__a_, __d, __m);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
- _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
- {return __cxx_atomic_load(&__a_, __m);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
- _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
- {return __cxx_atomic_load(&__a_, __m);}
- _LIBCPP_INLINE_VISIBILITY
- operator _Tp() const volatile _NOEXCEPT {return load();}
- _LIBCPP_INLINE_VISIBILITY
- operator _Tp() const _NOEXCEPT {return load();}
- _LIBCPP_INLINE_VISIBILITY
- _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- {return __cxx_atomic_exchange(&__a_, __d, __m);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
- {return __cxx_atomic_exchange(&__a_, __d, __m);}
- _LIBCPP_INLINE_VISIBILITY
- bool compare_exchange_weak(_Tp& __e, _Tp __d,
- memory_order __s, memory_order __f) volatile _NOEXCEPT
- _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
- {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
- _LIBCPP_INLINE_VISIBILITY
- bool compare_exchange_weak(_Tp& __e, _Tp __d,
- memory_order __s, memory_order __f) _NOEXCEPT
- _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
- {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
- _LIBCPP_INLINE_VISIBILITY
- bool compare_exchange_strong(_Tp& __e, _Tp __d,
- memory_order __s, memory_order __f) volatile _NOEXCEPT
- _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
- {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
- _LIBCPP_INLINE_VISIBILITY
- bool compare_exchange_strong(_Tp& __e, _Tp __d,
- memory_order __s, memory_order __f) _NOEXCEPT
- _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
- {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
- _LIBCPP_INLINE_VISIBILITY
- bool compare_exchange_weak(_Tp& __e, _Tp __d,
- memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
- _LIBCPP_INLINE_VISIBILITY
- bool compare_exchange_weak(_Tp& __e, _Tp __d,
- memory_order __m = memory_order_seq_cst) _NOEXCEPT
- {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
- _LIBCPP_INLINE_VISIBILITY
- bool compare_exchange_strong(_Tp& __e, _Tp __d,
- memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
- _LIBCPP_INLINE_VISIBILITY
- bool compare_exchange_strong(_Tp& __e, _Tp __d,
- memory_order __m = memory_order_seq_cst) _NOEXCEPT
- {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
- {__cxx_atomic_wait(&__a_, __v, __m);}
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
- {__cxx_atomic_wait(&__a_, __v, __m);}
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT
- {__cxx_atomic_notify_one(&__a_);}
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT
- {__cxx_atomic_notify_one(&__a_);}
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT
- {__cxx_atomic_notify_all(&__a_);}
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
- {__cxx_atomic_notify_all(&__a_);}
- #if _LIBCPP_STD_VER > 17
- _LIBCPP_INLINE_VISIBILITY constexpr
- __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
- #else
- _LIBCPP_INLINE_VISIBILITY
- __atomic_base() _NOEXCEPT = default;
- #endif
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
- __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
- #ifdef _LIBCPP_COMPILER_MSVC
- #pragma warning ( push )
- #pragma warning ( disable : 4522 )
- #endif
- __atomic_base(const __atomic_base&) = delete;
- #ifdef _LIBCPP_COMPILER_MSVC
- #pragma warning ( pop )
- #endif
- };
- #if defined(__cpp_lib_atomic_is_always_lock_free)
- template <class _Tp, bool __b>
- _LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
- #endif
- // atomic<Integral>
- template <class _Tp>
- struct __atomic_base<_Tp, true>
- : public __atomic_base<_Tp, false>
- {
- typedef __atomic_base<_Tp, false> __base;
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
- __atomic_base() _NOEXCEPT = default;
- _LIBCPP_INLINE_VISIBILITY
- _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
- _LIBCPP_INLINE_VISIBILITY
- _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
- {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
- {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
- {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
- {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
- {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;}
- };
- // atomic<T>
- template <class _Tp>
- struct atomic
- : public __atomic_base<_Tp>
- {
- typedef __atomic_base<_Tp> __base;
- typedef _Tp value_type;
- typedef value_type difference_type;
- #if _LIBCPP_STD_VER > 17
- _LIBCPP_INLINE_VISIBILITY
- atomic() = default;
- #else
- _LIBCPP_INLINE_VISIBILITY
- atomic() _NOEXCEPT = default;
- #endif
- _LIBCPP_INLINE_VISIBILITY
- _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator=(_Tp __d) volatile _NOEXCEPT
- {__base::store(__d); return __d;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp operator=(_Tp __d) _NOEXCEPT
- {__base::store(__d); return __d;}
- atomic& operator=(const atomic&) = delete;
- atomic& operator=(const atomic&) volatile = delete;
- };
- // atomic<T*>
- template <class _Tp>
- struct atomic<_Tp*>
- : public __atomic_base<_Tp*>
- {
- typedef __atomic_base<_Tp*> __base;
- typedef _Tp* value_type;
- typedef ptrdiff_t difference_type;
- _LIBCPP_INLINE_VISIBILITY
- atomic() _NOEXCEPT = default;
- _LIBCPP_INLINE_VISIBILITY
- _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
- _LIBCPP_INLINE_VISIBILITY
- _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
- {__base::store(__d); return __d;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp* operator=(_Tp* __d) _NOEXCEPT
- {__base::store(__d); return __d;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
- // __atomic_fetch_add accepts function pointers, guard against them.
- static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
- return __cxx_atomic_fetch_add(&this->__a_, __op, __m);
- }
- _LIBCPP_INLINE_VISIBILITY
- _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
- // __atomic_fetch_add accepts function pointers, guard against them.
- static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
- return __cxx_atomic_fetch_add(&this->__a_, __op, __m);
- }
- _LIBCPP_INLINE_VISIBILITY
- _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
- // __atomic_fetch_add accepts function pointers, guard against them.
- static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
- return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);
- }
- _LIBCPP_INLINE_VISIBILITY
- _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
- // __atomic_fetch_add accepts function pointers, guard against them.
- static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
- return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);
- }
- _LIBCPP_INLINE_VISIBILITY
- _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);}
- _LIBCPP_INLINE_VISIBILITY
- _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
- _LIBCPP_INLINE_VISIBILITY
- _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
- atomic& operator=(const atomic&) = delete;
- atomic& operator=(const atomic&) volatile = delete;
- };
- // atomic_is_lock_free
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool
- atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
- {
- return __o->is_lock_free();
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool
- atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
- {
- return __o->is_lock_free();
- }
- // atomic_init
- template <class _Tp>
- _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
- void
- atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
- {
- __cxx_atomic_init(&__o->__a_, __d);
- }
- template <class _Tp>
- _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
- void
- atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
- {
- __cxx_atomic_init(&__o->__a_, __d);
- }
- // atomic_store
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- void
- atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
- {
- __o->store(__d);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- void
- atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
- {
- __o->store(__d);
- }
- // atomic_store_explicit
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- void
- atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
- _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
- {
- __o->store(__d, __m);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- void
- atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
- _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
- {
- __o->store(__d, __m);
- }
- // atomic_load
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp
- atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
- {
- return __o->load();
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp
- atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
- {
- return __o->load();
- }
- // atomic_load_explicit
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp
- atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
- _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
- {
- return __o->load(__m);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp
- atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
- _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
- {
- return __o->load(__m);
- }
- // atomic_exchange
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp
- atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
- {
- return __o->exchange(__d);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp
- atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
- {
- return __o->exchange(__d);
- }
- // atomic_exchange_explicit
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp
- atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
- {
- return __o->exchange(__d, __m);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp
- atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
- {
- return __o->exchange(__d, __m);
- }
- // atomic_compare_exchange_weak
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool
- atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
- {
- return __o->compare_exchange_weak(*__e, __d);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool
- atomic_compare_exchange_weak(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
- {
- return __o->compare_exchange_weak(*__e, __d);
- }
- // atomic_compare_exchange_strong
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool
- atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
- {
- return __o->compare_exchange_strong(*__e, __d);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool
- atomic_compare_exchange_strong(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
- {
- return __o->compare_exchange_strong(*__e, __d);
- }
- // atomic_compare_exchange_weak_explicit
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool
- atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
- typename atomic<_Tp>::value_type __d,
- memory_order __s, memory_order __f) _NOEXCEPT
- _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
- {
- return __o->compare_exchange_weak(*__e, __d, __s, __f);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool
- atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
- memory_order __s, memory_order __f) _NOEXCEPT
- _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
- {
- return __o->compare_exchange_weak(*__e, __d, __s, __f);
- }
- // atomic_compare_exchange_strong_explicit
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool
- atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
- typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
- memory_order __s, memory_order __f) _NOEXCEPT
- _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
- {
- return __o->compare_exchange_strong(*__e, __d, __s, __f);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- bool
- atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
- typename atomic<_Tp>::value_type __d,
- memory_order __s, memory_order __f) _NOEXCEPT
- _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
- {
- return __o->compare_exchange_strong(*__e, __d, __s, __f);
- }
- // atomic_wait
- template <class _Tp>
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
- void atomic_wait(const volatile atomic<_Tp>* __o,
- typename atomic<_Tp>::value_type __v) _NOEXCEPT
- {
- return __o->wait(__v);
- }
- template <class _Tp>
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
- void atomic_wait(const atomic<_Tp>* __o,
- typename atomic<_Tp>::value_type __v) _NOEXCEPT
- {
- return __o->wait(__v);
- }
- // atomic_wait_explicit
- template <class _Tp>
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
- void atomic_wait_explicit(const volatile atomic<_Tp>* __o,
- typename atomic<_Tp>::value_type __v,
- memory_order __m) _NOEXCEPT
- _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
- {
- return __o->wait(__v, __m);
- }
- template <class _Tp>
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
- void atomic_wait_explicit(const atomic<_Tp>* __o,
- typename atomic<_Tp>::value_type __v,
- memory_order __m) _NOEXCEPT
- _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
- {
- return __o->wait(__v, __m);
- }
- // atomic_notify_one
- template <class _Tp>
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
- void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
- {
- __o->notify_one();
- }
- template <class _Tp>
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
- void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
- {
- __o->notify_one();
- }
- // atomic_notify_one
- template <class _Tp>
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
- void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
- {
- __o->notify_all();
- }
- template <class _Tp>
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
- void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
- {
- __o->notify_all();
- }
- // atomic_fetch_add
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp
- atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
- {
- return __o->fetch_add(__op);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp
- atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
- {
- return __o->fetch_add(__op);
- }
- // atomic_fetch_add_explicit
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
- {
- return __o->fetch_add(__op, __m);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
- {
- return __o->fetch_add(__op, __m);
- }
- // atomic_fetch_sub
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
- {
- return __o->fetch_sub(__op);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
- {
- return __o->fetch_sub(__op);
- }
- // atomic_fetch_sub_explicit
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
- {
- return __o->fetch_sub(__op, __m);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- _Tp atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
- {
- return __o->fetch_sub(__op, __m);
- }
- // atomic_fetch_and
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- typename enable_if
- <
- is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
- _Tp
- >::type
- atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
- {
- return __o->fetch_and(__op);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- typename enable_if
- <
- is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
- _Tp
- >::type
- atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
- {
- return __o->fetch_and(__op);
- }
- // atomic_fetch_and_explicit
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- typename enable_if
- <
- is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
- _Tp
- >::type
- atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
- {
- return __o->fetch_and(__op, __m);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- typename enable_if
- <
- is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
- _Tp
- >::type
- atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
- {
- return __o->fetch_and(__op, __m);
- }
- // atomic_fetch_or
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- typename enable_if
- <
- is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
- _Tp
- >::type
- atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
- {
- return __o->fetch_or(__op);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- typename enable_if
- <
- is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
- _Tp
- >::type
- atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
- {
- return __o->fetch_or(__op);
- }
- // atomic_fetch_or_explicit
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- typename enable_if
- <
- is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
- _Tp
- >::type
- atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
- {
- return __o->fetch_or(__op, __m);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- typename enable_if
- <
- is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
- _Tp
- >::type
- atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
- {
- return __o->fetch_or(__op, __m);
- }
- // atomic_fetch_xor
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- typename enable_if
- <
- is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
- _Tp
- >::type
- atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
- {
- return __o->fetch_xor(__op);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- typename enable_if
- <
- is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
- _Tp
- >::type
- atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
- {
- return __o->fetch_xor(__op);
- }
- // atomic_fetch_xor_explicit
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- typename enable_if
- <
- is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
- _Tp
- >::type
- atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
- {
- return __o->fetch_xor(__op, __m);
- }
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY
- typename enable_if
- <
- is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
- _Tp
- >::type
- atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
- {
- return __o->fetch_xor(__op, __m);
- }
- // flag type and operations
- typedef struct atomic_flag
- {
- __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
- _LIBCPP_INLINE_VISIBILITY
- bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
- {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
- _LIBCPP_INLINE_VISIBILITY
- bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
- {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
- _LIBCPP_INLINE_VISIBILITY
- bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
- _LIBCPP_INLINE_VISIBILITY
- bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
- {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
- _LIBCPP_INLINE_VISIBILITY
- void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
- _LIBCPP_INLINE_VISIBILITY
- void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
- {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
- void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
- {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
- void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
- {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
- void notify_one() volatile _NOEXCEPT
- {__cxx_atomic_notify_one(&__a_);}
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
- void notify_one() _NOEXCEPT
- {__cxx_atomic_notify_one(&__a_);}
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
- void notify_all() volatile _NOEXCEPT
- {__cxx_atomic_notify_all(&__a_);}
- _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
- void notify_all() _NOEXCEPT
- {__cxx_atomic_notify_all(&__a_);}
- #if _LIBCPP_STD_VER > 17
- _LIBCPP_INLINE_VISIBILITY constexpr
- atomic_flag() _NOEXCEPT : __a_(false) {}
- #else
- _LIBCPP_INLINE_VISIBILITY
- atomic_flag() _NOEXCEPT = default;
- #endif
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
- atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
- #ifdef _LIBCPP_COMPILER_MSVC
- #pragma warning ( push )
- #pragma warning ( disable : 4522 )
- #endif
- atomic_flag(const atomic_flag&) = delete;
- atomic_flag& operator=(const atomic_flag&) = delete;
- atomic_flag& operator=(const atomic_flag&) volatile = delete;
- #ifdef _LIBCPP_COMPILER_MSVC
- #pragma warning ( pop )
- #endif
- } atomic_flag;
- inline _LIBCPP_INLINE_VISIBILITY
- bool
- atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
- {
- return __o->test();
- }
- inline _LIBCPP_INLINE_VISIBILITY
- bool
- atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
- {
- return __o->test();
- }
- inline _LIBCPP_INLINE_VISIBILITY
- bool
- atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
- {
- return __o->test(__m);
- }
- inline _LIBCPP_INLINE_VISIBILITY
- bool
- atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
- {
- return __o->test(__m);
- }
- inline _LIBCPP_INLINE_VISIBILITY
- bool
- atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
- {
- return __o->test_and_set();
- }
- inline _LIBCPP_INLINE_VISIBILITY
- bool
- atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
- {
- return __o->test_and_set();
- }
- inline _LIBCPP_INLINE_VISIBILITY
- bool
- atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
- {
- return __o->test_and_set(__m);
- }
- inline _LIBCPP_INLINE_VISIBILITY
- bool
- atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
- {
- return __o->test_and_set(__m);
- }
- inline _LIBCPP_INLINE_VISIBILITY
- void
- atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
- {
- __o->clear();
- }
- inline _LIBCPP_INLINE_VISIBILITY
- void
- atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
- {
- __o->clear();
- }
- inline _LIBCPP_INLINE_VISIBILITY
- void
- atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
- {
- __o->clear(__m);
- }
- inline _LIBCPP_INLINE_VISIBILITY
- void
- atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
- {
- __o->clear(__m);
- }
- inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
- void
- atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
- {
- __o->wait(__v);
- }
- inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
- void
- atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
- {
- __o->wait(__v);
- }
- inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
- void
- atomic_flag_wait_explicit(const volatile atomic_flag* __o,
- bool __v, memory_order __m) _NOEXCEPT
- {
- __o->wait(__v, __m);
- }
- inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
- void
- atomic_flag_wait_explicit(const atomic_flag* __o,
- bool __v, memory_order __m) _NOEXCEPT
- {
- __o->wait(__v, __m);
- }
- inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
- void
- atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
- {
- __o->notify_one();
- }
- inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
- void
- atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
- {
- __o->notify_one();
- }
- inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
- void
- atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
- {
- __o->notify_all();
- }
- inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
- void
- atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
- {
- __o->notify_all();
- }
- // fences
- inline _LIBCPP_INLINE_VISIBILITY
- void
- atomic_thread_fence(memory_order __m) _NOEXCEPT
- {
- __cxx_atomic_thread_fence(__m);
- }
- inline _LIBCPP_INLINE_VISIBILITY
- void
- atomic_signal_fence(memory_order __m) _NOEXCEPT
- {
- __cxx_atomic_signal_fence(__m);
- }
- // Atomics for standard typedef types
- typedef atomic<bool> atomic_bool;
- typedef atomic<char> atomic_char;
- typedef atomic<signed char> atomic_schar;
- typedef atomic<unsigned char> atomic_uchar;
- typedef atomic<short> atomic_short;
- typedef atomic<unsigned short> atomic_ushort;
- typedef atomic<int> atomic_int;
- typedef atomic<unsigned int> atomic_uint;
- typedef atomic<long> atomic_long;
- typedef atomic<unsigned long> atomic_ulong;
- typedef atomic<long long> atomic_llong;
- typedef atomic<unsigned long long> atomic_ullong;
- #ifndef _LIBCPP_HAS_NO_CHAR8_T
- typedef atomic<char8_t> atomic_char8_t;
- #endif
- typedef atomic<char16_t> atomic_char16_t;
- typedef atomic<char32_t> atomic_char32_t;
- #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
- typedef atomic<wchar_t> atomic_wchar_t;
- #endif
- typedef atomic<int_least8_t> atomic_int_least8_t;
- typedef atomic<uint_least8_t> atomic_uint_least8_t;
- typedef atomic<int_least16_t> atomic_int_least16_t;
- typedef atomic<uint_least16_t> atomic_uint_least16_t;
- typedef atomic<int_least32_t> atomic_int_least32_t;
- typedef atomic<uint_least32_t> atomic_uint_least32_t;
- typedef atomic<int_least64_t> atomic_int_least64_t;
- typedef atomic<uint_least64_t> atomic_uint_least64_t;
- typedef atomic<int_fast8_t> atomic_int_fast8_t;
- typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
- typedef atomic<int_fast16_t> atomic_int_fast16_t;
- typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
- typedef atomic<int_fast32_t> atomic_int_fast32_t;
- typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
- typedef atomic<int_fast64_t> atomic_int_fast64_t;
- typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
- typedef atomic< int8_t> atomic_int8_t;
- typedef atomic<uint8_t> atomic_uint8_t;
- typedef atomic< int16_t> atomic_int16_t;
- typedef atomic<uint16_t> atomic_uint16_t;
- typedef atomic< int32_t> atomic_int32_t;
- typedef atomic<uint32_t> atomic_uint32_t;
- typedef atomic< int64_t> atomic_int64_t;
- typedef atomic<uint64_t> atomic_uint64_t;
- typedef atomic<intptr_t> atomic_intptr_t;
- typedef atomic<uintptr_t> atomic_uintptr_t;
- typedef atomic<size_t> atomic_size_t;
- typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
- typedef atomic<intmax_t> atomic_intmax_t;
- typedef atomic<uintmax_t> atomic_uintmax_t;
- // atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
- #ifdef __cpp_lib_atomic_is_always_lock_free
- # define _LIBCPP_CONTENTION_LOCK_FREE __atomic_always_lock_free(sizeof(__cxx_contention_t), 0)
- #else
- # define _LIBCPP_CONTENTION_LOCK_FREE false
- #endif
- #if ATOMIC_LLONG_LOCK_FREE == 2
- typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>::type __libcpp_signed_lock_free;
- typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>::type __libcpp_unsigned_lock_free;
- #elif ATOMIC_INT_LOCK_FREE == 2
- typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>::type __libcpp_signed_lock_free;
- typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>::type __libcpp_unsigned_lock_free;
- #elif ATOMIC_SHORT_LOCK_FREE == 2
- typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>::type __libcpp_signed_lock_free;
- typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>::type __libcpp_unsigned_lock_free;
- #elif ATOMIC_CHAR_LOCK_FREE == 2
- typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>::type __libcpp_signed_lock_free;
- typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>::type __libcpp_unsigned_lock_free;
- #else
- // No signed/unsigned lock-free types
- #define _LIBCPP_NO_LOCK_FREE_TYPES
- #endif
- #if !defined(_LIBCPP_NO_LOCK_FREE_TYPES)
- typedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free;
- typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
- #endif
- #define ATOMIC_FLAG_INIT {false}
- #define ATOMIC_VAR_INIT(__v) {__v}
- #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
- # if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1400
- # pragma clang deprecated(ATOMIC_FLAG_INIT)
- # pragma clang deprecated(ATOMIC_VAR_INIT)
- # endif
- #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
- _LIBCPP_END_NAMESPACE_STD
- #endif // _LIBCPP_ATOMIC
|