10b57cec5SDimitry Andric// -*- C++ -*- 2349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 30b57cec5SDimitry Andric// 40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric// 80b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric#ifndef _LIBCPP_ATOMIC 110b57cec5SDimitry Andric#define _LIBCPP_ATOMIC 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric/* 140b57cec5SDimitry Andric atomic synopsis 150b57cec5SDimitry Andric 160b57cec5SDimitry Andricnamespace std 170b57cec5SDimitry Andric{ 180b57cec5SDimitry Andric 19e8d8bef9SDimitry Andric// feature test macro [version.syn] 200b57cec5SDimitry Andric 21e8d8bef9SDimitry Andric#define __cpp_lib_atomic_is_always_lock_free 22e8d8bef9SDimitry Andric#define __cpp_lib_atomic_flag_test 23e8d8bef9SDimitry Andric#define __cpp_lib_atomic_lock_free_type_aliases 24e8d8bef9SDimitry Andric#define __cpp_lib_atomic_wait 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric // order and consistency 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric enum memory_order: unspecified // enum class in C++20 290b57cec5SDimitry Andric { 300b57cec5SDimitry Andric relaxed, 310b57cec5SDimitry Andric consume, // load-consume 320b57cec5SDimitry Andric acquire, // load-acquire 330b57cec5SDimitry Andric release, // store-release 340b57cec5SDimitry Andric acq_rel, // store-release load-acquire 350b57cec5SDimitry Andric seq_cst // store-release load-acquire 360b57cec5SDimitry Andric }; 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric inline constexpr auto memory_order_relaxed = memory_order::relaxed; 390b57cec5SDimitry Andric inline constexpr auto memory_order_consume = memory_order::consume; 400b57cec5SDimitry Andric inline constexpr auto memory_order_acquire = memory_order::acquire; 410b57cec5SDimitry Andric inline constexpr auto memory_order_release = memory_order::release; 420b57cec5SDimitry Andric inline constexpr auto memory_order_acq_rel = memory_order::acq_rel; 430b57cec5SDimitry Andric inline constexpr auto memory_order_seq_cst = memory_order::seq_cst; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andrictemplate <class T> T kill_dependency(T y) noexcept; 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric// lock-free property 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric#define ATOMIC_BOOL_LOCK_FREE unspecified 500b57cec5SDimitry Andric#define ATOMIC_CHAR_LOCK_FREE unspecified 51e8d8bef9SDimitry Andric#define ATOMIC_CHAR8_T_LOCK_FREE unspecified // C++20 520b57cec5SDimitry Andric#define ATOMIC_CHAR16_T_LOCK_FREE unspecified 530b57cec5SDimitry Andric#define ATOMIC_CHAR32_T_LOCK_FREE unspecified 540b57cec5SDimitry Andric#define ATOMIC_WCHAR_T_LOCK_FREE unspecified 550b57cec5SDimitry Andric#define ATOMIC_SHORT_LOCK_FREE unspecified 560b57cec5SDimitry Andric#define ATOMIC_INT_LOCK_FREE unspecified 570b57cec5SDimitry Andric#define ATOMIC_LONG_LOCK_FREE unspecified 580b57cec5SDimitry Andric#define ATOMIC_LLONG_LOCK_FREE unspecified 590b57cec5SDimitry Andric#define ATOMIC_POINTER_LOCK_FREE unspecified 600b57cec5SDimitry Andric 610b57cec5SDimitry Andrictemplate <class T> 620b57cec5SDimitry Andricstruct atomic 630b57cec5SDimitry Andric{ 645ffd83dbSDimitry Andric using value_type = T; 655ffd83dbSDimitry Andric 660b57cec5SDimitry Andric static constexpr bool is_always_lock_free; 670b57cec5SDimitry Andric bool is_lock_free() const volatile noexcept; 680b57cec5SDimitry Andric bool is_lock_free() const noexcept; 695ffd83dbSDimitry Andric 70fe6060f1SDimitry Andric atomic() noexcept = default; // until C++20 71fe6060f1SDimitry Andric constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>); // since C++20 725ffd83dbSDimitry Andric constexpr atomic(T desr) noexcept; 735ffd83dbSDimitry Andric atomic(const atomic&) = delete; 745ffd83dbSDimitry Andric atomic& operator=(const atomic&) = delete; 755ffd83dbSDimitry Andric atomic& operator=(const atomic&) volatile = delete; 765ffd83dbSDimitry Andric 770b57cec5SDimitry Andric T load(memory_order m = memory_order_seq_cst) const volatile noexcept; 780b57cec5SDimitry Andric T load(memory_order m = memory_order_seq_cst) const noexcept; 790b57cec5SDimitry Andric operator T() const volatile noexcept; 800b57cec5SDimitry Andric operator T() const noexcept; 815ffd83dbSDimitry Andric void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; 825ffd83dbSDimitry Andric void store(T desr, memory_order m = memory_order_seq_cst) noexcept; 835ffd83dbSDimitry Andric T operator=(T) volatile noexcept; 845ffd83dbSDimitry Andric T operator=(T) noexcept; 855ffd83dbSDimitry Andric 860b57cec5SDimitry Andric T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; 870b57cec5SDimitry Andric T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept; 880b57cec5SDimitry Andric bool compare_exchange_weak(T& expc, T desr, 890b57cec5SDimitry Andric memory_order s, memory_order f) volatile noexcept; 900b57cec5SDimitry Andric bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept; 910b57cec5SDimitry Andric bool compare_exchange_strong(T& expc, T desr, 920b57cec5SDimitry Andric memory_order s, memory_order f) volatile noexcept; 930b57cec5SDimitry Andric bool compare_exchange_strong(T& expc, T desr, 940b57cec5SDimitry Andric memory_order s, memory_order f) noexcept; 950b57cec5SDimitry Andric bool compare_exchange_weak(T& expc, T desr, 960b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) volatile noexcept; 970b57cec5SDimitry Andric bool compare_exchange_weak(T& expc, T desr, 980b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) noexcept; 990b57cec5SDimitry Andric bool compare_exchange_strong(T& expc, T desr, 1000b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) volatile noexcept; 1010b57cec5SDimitry Andric bool compare_exchange_strong(T& expc, T desr, 1020b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) noexcept; 1030b57cec5SDimitry Andric 1045ffd83dbSDimitry Andric void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept; 1055ffd83dbSDimitry Andric void wait(T, memory_order = memory_order::seq_cst) const noexcept; 1065ffd83dbSDimitry Andric void notify_one() volatile noexcept; 1075ffd83dbSDimitry Andric void notify_one() noexcept; 1085ffd83dbSDimitry Andric void notify_all() volatile noexcept; 1095ffd83dbSDimitry Andric void notify_all() noexcept; 1100b57cec5SDimitry Andric}; 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andrictemplate <> 1130b57cec5SDimitry Andricstruct atomic<integral> 1140b57cec5SDimitry Andric{ 1155ffd83dbSDimitry Andric using value_type = integral; 116e8d8bef9SDimitry Andric using difference_type = value_type; 1175ffd83dbSDimitry Andric 1180b57cec5SDimitry Andric static constexpr bool is_always_lock_free; 1190b57cec5SDimitry Andric bool is_lock_free() const volatile noexcept; 1200b57cec5SDimitry Andric bool is_lock_free() const noexcept; 1215ffd83dbSDimitry Andric 1225ffd83dbSDimitry Andric atomic() noexcept = default; 1235ffd83dbSDimitry Andric constexpr atomic(integral desr) noexcept; 1245ffd83dbSDimitry Andric atomic(const atomic&) = delete; 1255ffd83dbSDimitry Andric atomic& operator=(const atomic&) = delete; 1265ffd83dbSDimitry Andric atomic& operator=(const atomic&) volatile = delete; 1275ffd83dbSDimitry Andric 1280b57cec5SDimitry Andric integral load(memory_order m = memory_order_seq_cst) const volatile noexcept; 1290b57cec5SDimitry Andric integral load(memory_order m = memory_order_seq_cst) const noexcept; 1300b57cec5SDimitry Andric operator integral() const volatile noexcept; 1310b57cec5SDimitry Andric operator integral() const noexcept; 1325ffd83dbSDimitry Andric void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept; 1335ffd83dbSDimitry Andric void store(integral desr, memory_order m = memory_order_seq_cst) noexcept; 1345ffd83dbSDimitry Andric integral operator=(integral desr) volatile noexcept; 1355ffd83dbSDimitry Andric integral operator=(integral desr) noexcept; 1365ffd83dbSDimitry Andric 1370b57cec5SDimitry Andric integral exchange(integral desr, 1380b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) volatile noexcept; 1390b57cec5SDimitry Andric integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept; 1400b57cec5SDimitry Andric bool compare_exchange_weak(integral& expc, integral desr, 1410b57cec5SDimitry Andric memory_order s, memory_order f) volatile noexcept; 1420b57cec5SDimitry Andric bool compare_exchange_weak(integral& expc, integral desr, 1430b57cec5SDimitry Andric memory_order s, memory_order f) noexcept; 1440b57cec5SDimitry Andric bool compare_exchange_strong(integral& expc, integral desr, 1450b57cec5SDimitry Andric memory_order s, memory_order f) volatile noexcept; 1460b57cec5SDimitry Andric bool compare_exchange_strong(integral& expc, integral desr, 1470b57cec5SDimitry Andric memory_order s, memory_order f) noexcept; 1480b57cec5SDimitry Andric bool compare_exchange_weak(integral& expc, integral desr, 1490b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) volatile noexcept; 1500b57cec5SDimitry Andric bool compare_exchange_weak(integral& expc, integral desr, 1510b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) noexcept; 1520b57cec5SDimitry Andric bool compare_exchange_strong(integral& expc, integral desr, 1530b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) volatile noexcept; 1540b57cec5SDimitry Andric bool compare_exchange_strong(integral& expc, integral desr, 1550b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) noexcept; 1560b57cec5SDimitry Andric 1575ffd83dbSDimitry Andric integral fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 1580b57cec5SDimitry Andric integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept; 1595ffd83dbSDimitry Andric integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 1600b57cec5SDimitry Andric integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept; 1615ffd83dbSDimitry Andric integral fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 1620b57cec5SDimitry Andric integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept; 1635ffd83dbSDimitry Andric integral fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 1640b57cec5SDimitry Andric integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept; 1655ffd83dbSDimitry Andric integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 1660b57cec5SDimitry Andric integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept; 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric integral operator++(int) volatile noexcept; 1690b57cec5SDimitry Andric integral operator++(int) noexcept; 1700b57cec5SDimitry Andric integral operator--(int) volatile noexcept; 1710b57cec5SDimitry Andric integral operator--(int) noexcept; 1720b57cec5SDimitry Andric integral operator++() volatile noexcept; 1730b57cec5SDimitry Andric integral operator++() noexcept; 1740b57cec5SDimitry Andric integral operator--() volatile noexcept; 1750b57cec5SDimitry Andric integral operator--() noexcept; 1760b57cec5SDimitry Andric integral operator+=(integral op) volatile noexcept; 1770b57cec5SDimitry Andric integral operator+=(integral op) noexcept; 1780b57cec5SDimitry Andric integral operator-=(integral op) volatile noexcept; 1790b57cec5SDimitry Andric integral operator-=(integral op) noexcept; 1800b57cec5SDimitry Andric integral operator&=(integral op) volatile noexcept; 1810b57cec5SDimitry Andric integral operator&=(integral op) noexcept; 1820b57cec5SDimitry Andric integral operator|=(integral op) volatile noexcept; 1830b57cec5SDimitry Andric integral operator|=(integral op) noexcept; 1840b57cec5SDimitry Andric integral operator^=(integral op) volatile noexcept; 1850b57cec5SDimitry Andric integral operator^=(integral op) noexcept; 1865ffd83dbSDimitry Andric 1875ffd83dbSDimitry Andric void wait(integral, memory_order = memory_order::seq_cst) const volatile noexcept; 1885ffd83dbSDimitry Andric void wait(integral, memory_order = memory_order::seq_cst) const noexcept; 1895ffd83dbSDimitry Andric void notify_one() volatile noexcept; 1905ffd83dbSDimitry Andric void notify_one() noexcept; 1915ffd83dbSDimitry Andric void notify_all() volatile noexcept; 1925ffd83dbSDimitry Andric void notify_all() noexcept; 1930b57cec5SDimitry Andric}; 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andrictemplate <class T> 1960b57cec5SDimitry Andricstruct atomic<T*> 1970b57cec5SDimitry Andric{ 1985ffd83dbSDimitry Andric using value_type = T*; 199e8d8bef9SDimitry Andric using difference_type = ptrdiff_t; 2005ffd83dbSDimitry Andric 2010b57cec5SDimitry Andric static constexpr bool is_always_lock_free; 2020b57cec5SDimitry Andric bool is_lock_free() const volatile noexcept; 2030b57cec5SDimitry Andric bool is_lock_free() const noexcept; 2045ffd83dbSDimitry Andric 205fe6060f1SDimitry Andric atomic() noexcept = default; // until C++20 206fe6060f1SDimitry Andric constexpr atomic() noexcept; // since C++20 2075ffd83dbSDimitry Andric constexpr atomic(T* desr) noexcept; 2085ffd83dbSDimitry Andric atomic(const atomic&) = delete; 2095ffd83dbSDimitry Andric atomic& operator=(const atomic&) = delete; 2105ffd83dbSDimitry Andric atomic& operator=(const atomic&) volatile = delete; 2115ffd83dbSDimitry Andric 2120b57cec5SDimitry Andric T* load(memory_order m = memory_order_seq_cst) const volatile noexcept; 2130b57cec5SDimitry Andric T* load(memory_order m = memory_order_seq_cst) const noexcept; 2140b57cec5SDimitry Andric operator T*() const volatile noexcept; 2150b57cec5SDimitry Andric operator T*() const noexcept; 2165ffd83dbSDimitry Andric void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; 2175ffd83dbSDimitry Andric void store(T* desr, memory_order m = memory_order_seq_cst) noexcept; 2185ffd83dbSDimitry Andric T* operator=(T*) volatile noexcept; 2195ffd83dbSDimitry Andric T* operator=(T*) noexcept; 2205ffd83dbSDimitry Andric 2210b57cec5SDimitry Andric T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; 2220b57cec5SDimitry Andric T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept; 2230b57cec5SDimitry Andric bool compare_exchange_weak(T*& expc, T* desr, 2240b57cec5SDimitry Andric memory_order s, memory_order f) volatile noexcept; 2250b57cec5SDimitry Andric bool compare_exchange_weak(T*& expc, T* desr, 2260b57cec5SDimitry Andric memory_order s, memory_order f) noexcept; 2270b57cec5SDimitry Andric bool compare_exchange_strong(T*& expc, T* desr, 2280b57cec5SDimitry Andric memory_order s, memory_order f) volatile noexcept; 2290b57cec5SDimitry Andric bool compare_exchange_strong(T*& expc, T* desr, 2300b57cec5SDimitry Andric memory_order s, memory_order f) noexcept; 2310b57cec5SDimitry Andric bool compare_exchange_weak(T*& expc, T* desr, 2320b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) volatile noexcept; 2330b57cec5SDimitry Andric bool compare_exchange_weak(T*& expc, T* desr, 2340b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) noexcept; 2350b57cec5SDimitry Andric bool compare_exchange_strong(T*& expc, T* desr, 2360b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) volatile noexcept; 2370b57cec5SDimitry Andric bool compare_exchange_strong(T*& expc, T* desr, 2380b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) noexcept; 2390b57cec5SDimitry Andric T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept; 2400b57cec5SDimitry Andric T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept; 2410b57cec5SDimitry Andric T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept; 2420b57cec5SDimitry Andric T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept; 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric T* operator++(int) volatile noexcept; 2450b57cec5SDimitry Andric T* operator++(int) noexcept; 2460b57cec5SDimitry Andric T* operator--(int) volatile noexcept; 2470b57cec5SDimitry Andric T* operator--(int) noexcept; 2480b57cec5SDimitry Andric T* operator++() volatile noexcept; 2490b57cec5SDimitry Andric T* operator++() noexcept; 2500b57cec5SDimitry Andric T* operator--() volatile noexcept; 2510b57cec5SDimitry Andric T* operator--() noexcept; 2520b57cec5SDimitry Andric T* operator+=(ptrdiff_t op) volatile noexcept; 2530b57cec5SDimitry Andric T* operator+=(ptrdiff_t op) noexcept; 2540b57cec5SDimitry Andric T* operator-=(ptrdiff_t op) volatile noexcept; 2550b57cec5SDimitry Andric T* operator-=(ptrdiff_t op) noexcept; 2565ffd83dbSDimitry Andric 2575ffd83dbSDimitry Andric void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept; 2585ffd83dbSDimitry Andric void wait(T*, memory_order = memory_order::seq_cst) const noexcept; 2595ffd83dbSDimitry Andric void notify_one() volatile noexcept; 2605ffd83dbSDimitry Andric void notify_one() noexcept; 2615ffd83dbSDimitry Andric void notify_all() volatile noexcept; 2625ffd83dbSDimitry Andric void notify_all() noexcept; 2630b57cec5SDimitry Andric}; 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric 266349cc55cSDimitry Andric// [atomics.nonmembers], non-member functions 2670b57cec5SDimitry Andrictemplate<class T> 268349cc55cSDimitry Andric bool atomic_is_lock_free(const volatile atomic<T>*) noexcept; 269349cc55cSDimitry Andrictemplate<class T> 270349cc55cSDimitry Andric bool atomic_is_lock_free(const atomic<T>*) noexcept; 271349cc55cSDimitry Andrictemplate<class T> 272349cc55cSDimitry Andric void atomic_store(volatile atomic<T>*, atomic<T>::value_type) noexcept; 273349cc55cSDimitry Andrictemplate<class T> 274349cc55cSDimitry Andric void atomic_store(atomic<T>*, atomic<T>::value_type) noexcept; 275349cc55cSDimitry Andrictemplate<class T> 276349cc55cSDimitry Andric void atomic_store_explicit(volatile atomic<T>*, atomic<T>::value_type, 277349cc55cSDimitry Andric memory_order) noexcept; 278349cc55cSDimitry Andrictemplate<class T> 279349cc55cSDimitry Andric void atomic_store_explicit(atomic<T>*, atomic<T>::value_type, 280349cc55cSDimitry Andric memory_order) noexcept; 281349cc55cSDimitry Andrictemplate<class T> 282349cc55cSDimitry Andric T atomic_load(const volatile atomic<T>*) noexcept; 283349cc55cSDimitry Andrictemplate<class T> 284349cc55cSDimitry Andric T atomic_load(const atomic<T>*) noexcept; 285349cc55cSDimitry Andrictemplate<class T> 286349cc55cSDimitry Andric T atomic_load_explicit(const volatile atomic<T>*, memory_order) noexcept; 287349cc55cSDimitry Andrictemplate<class T> 288349cc55cSDimitry Andric T atomic_load_explicit(const atomic<T>*, memory_order) noexcept; 289349cc55cSDimitry Andrictemplate<class T> 290349cc55cSDimitry Andric T atomic_exchange(volatile atomic<T>*, atomic<T>::value_type) noexcept; 291349cc55cSDimitry Andrictemplate<class T> 292349cc55cSDimitry Andric T atomic_exchange(atomic<T>*, atomic<T>::value_type) noexcept; 293349cc55cSDimitry Andrictemplate<class T> 294349cc55cSDimitry Andric T atomic_exchange_explicit(volatile atomic<T>*, atomic<T>::value_type, 295349cc55cSDimitry Andric memory_order) noexcept; 296349cc55cSDimitry Andrictemplate<class T> 297349cc55cSDimitry Andric T atomic_exchange_explicit(atomic<T>*, atomic<T>::value_type, 298349cc55cSDimitry Andric memory_order) noexcept; 299349cc55cSDimitry Andrictemplate<class T> 300349cc55cSDimitry Andric bool atomic_compare_exchange_weak(volatile atomic<T>*, atomic<T>::value_type*, 301349cc55cSDimitry Andric atomic<T>::value_type) noexcept; 302349cc55cSDimitry Andrictemplate<class T> 303349cc55cSDimitry Andric bool atomic_compare_exchange_weak(atomic<T>*, atomic<T>::value_type*, 304349cc55cSDimitry Andric atomic<T>::value_type) noexcept; 305349cc55cSDimitry Andrictemplate<class T> 306349cc55cSDimitry Andric bool atomic_compare_exchange_strong(volatile atomic<T>*, atomic<T>::value_type*, 307349cc55cSDimitry Andric atomic<T>::value_type) noexcept; 308349cc55cSDimitry Andrictemplate<class T> 309349cc55cSDimitry Andric bool atomic_compare_exchange_strong(atomic<T>*, atomic<T>::value_type*, 310349cc55cSDimitry Andric atomic<T>::value_type) noexcept; 311349cc55cSDimitry Andrictemplate<class T> 312349cc55cSDimitry Andric bool atomic_compare_exchange_weak_explicit(volatile atomic<T>*, atomic<T>::value_type*, 313349cc55cSDimitry Andric atomic<T>::value_type, 314349cc55cSDimitry Andric memory_order, memory_order) noexcept; 315349cc55cSDimitry Andrictemplate<class T> 316349cc55cSDimitry Andric bool atomic_compare_exchange_weak_explicit(atomic<T>*, atomic<T>::value_type*, 317349cc55cSDimitry Andric atomic<T>::value_type, 318349cc55cSDimitry Andric memory_order, memory_order) noexcept; 319349cc55cSDimitry Andrictemplate<class T> 320349cc55cSDimitry Andric bool atomic_compare_exchange_strong_explicit(volatile atomic<T>*, atomic<T>::value_type*, 321349cc55cSDimitry Andric atomic<T>::value_type, 322349cc55cSDimitry Andric memory_order, memory_order) noexcept; 323349cc55cSDimitry Andrictemplate<class T> 324349cc55cSDimitry Andric bool atomic_compare_exchange_strong_explicit(atomic<T>*, atomic<T>::value_type*, 325349cc55cSDimitry Andric atomic<T>::value_type, 326349cc55cSDimitry Andric memory_order, memory_order) noexcept; 3270b57cec5SDimitry Andric 3280b57cec5SDimitry Andrictemplate<class T> 329349cc55cSDimitry Andric T atomic_fetch_add(volatile atomic<T>*, atomic<T>::difference_type) noexcept; 330349cc55cSDimitry Andrictemplate<class T> 331349cc55cSDimitry Andric T atomic_fetch_add(atomic<T>*, atomic<T>::difference_type) noexcept; 332349cc55cSDimitry Andrictemplate<class T> 333349cc55cSDimitry Andric T atomic_fetch_add_explicit(volatile atomic<T>*, atomic<T>::difference_type, 334349cc55cSDimitry Andric memory_order) noexcept; 335349cc55cSDimitry Andrictemplate<class T> 336349cc55cSDimitry Andric T atomic_fetch_add_explicit(atomic<T>*, atomic<T>::difference_type, 337349cc55cSDimitry Andric memory_order) noexcept; 338349cc55cSDimitry Andrictemplate<class T> 339349cc55cSDimitry Andric T atomic_fetch_sub(volatile atomic<T>*, atomic<T>::difference_type) noexcept; 340349cc55cSDimitry Andrictemplate<class T> 341349cc55cSDimitry Andric T atomic_fetch_sub(atomic<T>*, atomic<T>::difference_type) noexcept; 342349cc55cSDimitry Andrictemplate<class T> 343349cc55cSDimitry Andric T atomic_fetch_sub_explicit(volatile atomic<T>*, atomic<T>::difference_type, 344349cc55cSDimitry Andric memory_order) noexcept; 345349cc55cSDimitry Andrictemplate<class T> 346349cc55cSDimitry Andric T atomic_fetch_sub_explicit(atomic<T>*, atomic<T>::difference_type, 347349cc55cSDimitry Andric memory_order) noexcept; 348349cc55cSDimitry Andrictemplate<class T> 349349cc55cSDimitry Andric T atomic_fetch_and(volatile atomic<T>*, atomic<T>::value_type) noexcept; 350349cc55cSDimitry Andrictemplate<class T> 351349cc55cSDimitry Andric T atomic_fetch_and(atomic<T>*, atomic<T>::value_type) noexcept; 352349cc55cSDimitry Andrictemplate<class T> 353349cc55cSDimitry Andric T atomic_fetch_and_explicit(volatile atomic<T>*, atomic<T>::value_type, 354349cc55cSDimitry Andric memory_order) noexcept; 355349cc55cSDimitry Andrictemplate<class T> 356349cc55cSDimitry Andric T atomic_fetch_and_explicit(atomic<T>*, atomic<T>::value_type, 357349cc55cSDimitry Andric memory_order) noexcept; 358349cc55cSDimitry Andrictemplate<class T> 359349cc55cSDimitry Andric T atomic_fetch_or(volatile atomic<T>*, atomic<T>::value_type) noexcept; 360349cc55cSDimitry Andrictemplate<class T> 361349cc55cSDimitry Andric T atomic_fetch_or(atomic<T>*, atomic<T>::value_type) noexcept; 362349cc55cSDimitry Andrictemplate<class T> 363349cc55cSDimitry Andric T atomic_fetch_or_explicit(volatile atomic<T>*, atomic<T>::value_type, 364349cc55cSDimitry Andric memory_order) noexcept; 365349cc55cSDimitry Andrictemplate<class T> 366349cc55cSDimitry Andric T atomic_fetch_or_explicit(atomic<T>*, atomic<T>::value_type, 367349cc55cSDimitry Andric memory_order) noexcept; 368349cc55cSDimitry Andrictemplate<class T> 369349cc55cSDimitry Andric T atomic_fetch_xor(volatile atomic<T>*, atomic<T>::value_type) noexcept; 370349cc55cSDimitry Andrictemplate<class T> 371349cc55cSDimitry Andric T atomic_fetch_xor(atomic<T>*, atomic<T>::value_type) noexcept; 372349cc55cSDimitry Andrictemplate<class T> 373349cc55cSDimitry Andric T atomic_fetch_xor_explicit(volatile atomic<T>*, atomic<T>::value_type, 374349cc55cSDimitry Andric memory_order) noexcept; 375349cc55cSDimitry Andrictemplate<class T> 376349cc55cSDimitry Andric T atomic_fetch_xor_explicit(atomic<T>*, atomic<T>::value_type, 377349cc55cSDimitry Andric memory_order) noexcept; 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andrictemplate<class T> 380bdd1243dSDimitry Andric void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type) noexcept; 3810b57cec5SDimitry Andrictemplate<class T> 382bdd1243dSDimitry Andric void atomic_wait(const atomic<T>*, atomic<T>::value_type) noexcept; 3830b57cec5SDimitry Andrictemplate<class T> 384349cc55cSDimitry Andric void atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type, 385bdd1243dSDimitry Andric memory_order) noexcept; 3860b57cec5SDimitry Andrictemplate<class T> 387349cc55cSDimitry Andric void atomic_wait_explicit(const atomic<T>*, atomic<T>::value_type, 388bdd1243dSDimitry Andric memory_order) noexcept; 3890b57cec5SDimitry Andrictemplate<class T> 390bdd1243dSDimitry Andric void atomic_notify_one(volatile atomic<T>*) noexcept; 3910b57cec5SDimitry Andrictemplate<class T> 392bdd1243dSDimitry Andric void atomic_notify_one(atomic<T>*) noexcept; 3930b57cec5SDimitry Andrictemplate<class T> 394bdd1243dSDimitry Andric void atomic_notify_all(volatile atomic<T>*) noexcept; 3950b57cec5SDimitry Andrictemplate<class T> 396bdd1243dSDimitry Andric void atomic_notify_all(atomic<T>*) noexcept; 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric// Atomics for standard typedef types 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andrictypedef atomic<bool> atomic_bool; 4010b57cec5SDimitry Andrictypedef atomic<char> atomic_char; 4020b57cec5SDimitry Andrictypedef atomic<signed char> atomic_schar; 4030b57cec5SDimitry Andrictypedef atomic<unsigned char> atomic_uchar; 4040b57cec5SDimitry Andrictypedef atomic<short> atomic_short; 4050b57cec5SDimitry Andrictypedef atomic<unsigned short> atomic_ushort; 4060b57cec5SDimitry Andrictypedef atomic<int> atomic_int; 4070b57cec5SDimitry Andrictypedef atomic<unsigned int> atomic_uint; 4080b57cec5SDimitry Andrictypedef atomic<long> atomic_long; 4090b57cec5SDimitry Andrictypedef atomic<unsigned long> atomic_ulong; 4100b57cec5SDimitry Andrictypedef atomic<long long> atomic_llong; 4110b57cec5SDimitry Andrictypedef atomic<unsigned long long> atomic_ullong; 412e8d8bef9SDimitry Andrictypedef atomic<char8_t> atomic_char8_t; // C++20 4130b57cec5SDimitry Andrictypedef atomic<char16_t> atomic_char16_t; 4140b57cec5SDimitry Andrictypedef atomic<char32_t> atomic_char32_t; 4150b57cec5SDimitry Andrictypedef atomic<wchar_t> atomic_wchar_t; 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andrictypedef atomic<int_least8_t> atomic_int_least8_t; 4180b57cec5SDimitry Andrictypedef atomic<uint_least8_t> atomic_uint_least8_t; 4190b57cec5SDimitry Andrictypedef atomic<int_least16_t> atomic_int_least16_t; 4200b57cec5SDimitry Andrictypedef atomic<uint_least16_t> atomic_uint_least16_t; 4210b57cec5SDimitry Andrictypedef atomic<int_least32_t> atomic_int_least32_t; 4220b57cec5SDimitry Andrictypedef atomic<uint_least32_t> atomic_uint_least32_t; 4230b57cec5SDimitry Andrictypedef atomic<int_least64_t> atomic_int_least64_t; 4240b57cec5SDimitry Andrictypedef atomic<uint_least64_t> atomic_uint_least64_t; 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andrictypedef atomic<int_fast8_t> atomic_int_fast8_t; 4270b57cec5SDimitry Andrictypedef atomic<uint_fast8_t> atomic_uint_fast8_t; 4280b57cec5SDimitry Andrictypedef atomic<int_fast16_t> atomic_int_fast16_t; 4290b57cec5SDimitry Andrictypedef atomic<uint_fast16_t> atomic_uint_fast16_t; 4300b57cec5SDimitry Andrictypedef atomic<int_fast32_t> atomic_int_fast32_t; 4310b57cec5SDimitry Andrictypedef atomic<uint_fast32_t> atomic_uint_fast32_t; 4320b57cec5SDimitry Andrictypedef atomic<int_fast64_t> atomic_int_fast64_t; 4330b57cec5SDimitry Andrictypedef atomic<uint_fast64_t> atomic_uint_fast64_t; 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andrictypedef atomic<int8_t> atomic_int8_t; 4360b57cec5SDimitry Andrictypedef atomic<uint8_t> atomic_uint8_t; 4370b57cec5SDimitry Andrictypedef atomic<int16_t> atomic_int16_t; 4380b57cec5SDimitry Andrictypedef atomic<uint16_t> atomic_uint16_t; 4390b57cec5SDimitry Andrictypedef atomic<int32_t> atomic_int32_t; 4400b57cec5SDimitry Andrictypedef atomic<uint32_t> atomic_uint32_t; 4410b57cec5SDimitry Andrictypedef atomic<int64_t> atomic_int64_t; 4420b57cec5SDimitry Andrictypedef atomic<uint64_t> atomic_uint64_t; 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andrictypedef atomic<intptr_t> atomic_intptr_t; 4450b57cec5SDimitry Andrictypedef atomic<uintptr_t> atomic_uintptr_t; 4460b57cec5SDimitry Andrictypedef atomic<size_t> atomic_size_t; 4470b57cec5SDimitry Andrictypedef atomic<ptrdiff_t> atomic_ptrdiff_t; 4480b57cec5SDimitry Andrictypedef atomic<intmax_t> atomic_intmax_t; 4490b57cec5SDimitry Andrictypedef atomic<uintmax_t> atomic_uintmax_t; 4500b57cec5SDimitry Andric 4515ffd83dbSDimitry Andric// flag type and operations 4525ffd83dbSDimitry Andric 4535ffd83dbSDimitry Andrictypedef struct atomic_flag 4545ffd83dbSDimitry Andric{ 455fe6060f1SDimitry Andric atomic_flag() noexcept = default; // until C++20 456fe6060f1SDimitry Andric constexpr atomic_flag() noexcept; // since C++20 4575ffd83dbSDimitry Andric atomic_flag(const atomic_flag&) = delete; 4585ffd83dbSDimitry Andric atomic_flag& operator=(const atomic_flag&) = delete; 4595ffd83dbSDimitry Andric atomic_flag& operator=(const atomic_flag&) volatile = delete; 4605ffd83dbSDimitry Andric 4615ffd83dbSDimitry Andric bool test(memory_order m = memory_order_seq_cst) volatile noexcept; 4625ffd83dbSDimitry Andric bool test(memory_order m = memory_order_seq_cst) noexcept; 4635ffd83dbSDimitry Andric bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept; 4645ffd83dbSDimitry Andric bool test_and_set(memory_order m = memory_order_seq_cst) noexcept; 4655ffd83dbSDimitry Andric void clear(memory_order m = memory_order_seq_cst) volatile noexcept; 4665ffd83dbSDimitry Andric void clear(memory_order m = memory_order_seq_cst) noexcept; 4675ffd83dbSDimitry Andric 4685ffd83dbSDimitry Andric void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept; 4695ffd83dbSDimitry Andric void wait(bool, memory_order = memory_order::seq_cst) const noexcept; 4705ffd83dbSDimitry Andric void notify_one() volatile noexcept; 4715ffd83dbSDimitry Andric void notify_one() noexcept; 4725ffd83dbSDimitry Andric void notify_all() volatile noexcept; 4735ffd83dbSDimitry Andric void notify_all() noexcept; 4745ffd83dbSDimitry Andric} atomic_flag; 4755ffd83dbSDimitry Andric 4765ffd83dbSDimitry Andricbool atomic_flag_test(volatile atomic_flag* obj) noexcept; 4775ffd83dbSDimitry Andricbool atomic_flag_test(atomic_flag* obj) noexcept; 4785ffd83dbSDimitry Andricbool atomic_flag_test_explicit(volatile atomic_flag* obj, 4795ffd83dbSDimitry Andric memory_order m) noexcept; 4805ffd83dbSDimitry Andricbool atomic_flag_test_explicit(atomic_flag* obj, memory_order m) noexcept; 4815ffd83dbSDimitry Andricbool atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept; 4825ffd83dbSDimitry Andricbool atomic_flag_test_and_set(atomic_flag* obj) noexcept; 4835ffd83dbSDimitry Andricbool atomic_flag_test_and_set_explicit(volatile atomic_flag* obj, 4845ffd83dbSDimitry Andric memory_order m) noexcept; 4855ffd83dbSDimitry Andricbool atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept; 4865ffd83dbSDimitry Andricvoid atomic_flag_clear(volatile atomic_flag* obj) noexcept; 4875ffd83dbSDimitry Andricvoid atomic_flag_clear(atomic_flag* obj) noexcept; 4885ffd83dbSDimitry Andricvoid atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept; 4895ffd83dbSDimitry Andricvoid atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept; 4905ffd83dbSDimitry Andric 4915ffd83dbSDimitry Andricvoid atomic_wait(const volatile atomic_flag* obj, T old) noexcept; 4925ffd83dbSDimitry Andricvoid atomic_wait(const atomic_flag* obj, T old) noexcept; 4935ffd83dbSDimitry Andricvoid atomic_wait_explicit(const volatile atomic_flag* obj, T old, memory_order m) noexcept; 4945ffd83dbSDimitry Andricvoid atomic_wait_explicit(const atomic_flag* obj, T old, memory_order m) noexcept; 4955ffd83dbSDimitry Andricvoid atomic_one(volatile atomic_flag* obj) noexcept; 4965ffd83dbSDimitry Andricvoid atomic_one(atomic_flag* obj) noexcept; 4975ffd83dbSDimitry Andricvoid atomic_all(volatile atomic_flag* obj) noexcept; 4985ffd83dbSDimitry Andricvoid atomic_all(atomic_flag* obj) noexcept; 4995ffd83dbSDimitry Andric 5000b57cec5SDimitry Andric// fences 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andricvoid atomic_thread_fence(memory_order m) noexcept; 5030b57cec5SDimitry Andricvoid atomic_signal_fence(memory_order m) noexcept; 5040b57cec5SDimitry Andric 5055ffd83dbSDimitry Andric// deprecated 5065ffd83dbSDimitry Andric 5075ffd83dbSDimitry Andrictemplate <class T> 508349cc55cSDimitry Andric void atomic_init(volatile atomic<T>* obj, atomic<T>::value_type desr) noexcept; 5095ffd83dbSDimitry Andric 5105ffd83dbSDimitry Andrictemplate <class T> 511349cc55cSDimitry Andric void atomic_init(atomic<T>* obj, atomic<T>::value_type desr) noexcept; 5125ffd83dbSDimitry Andric 5135ffd83dbSDimitry Andric#define ATOMIC_VAR_INIT(value) see below 5145ffd83dbSDimitry Andric 5155ffd83dbSDimitry Andric#define ATOMIC_FLAG_INIT see below 5165ffd83dbSDimitry Andric 5170b57cec5SDimitry Andric} // std 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andric*/ 5200b57cec5SDimitry Andric 52181ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler 522*06c3fb27SDimitry Andric#include <__atomic/aliases.h> 523*06c3fb27SDimitry Andric#include <__atomic/atomic.h> 524*06c3fb27SDimitry Andric#include <__atomic/atomic_base.h> 525*06c3fb27SDimitry Andric#include <__atomic/atomic_flag.h> 526*06c3fb27SDimitry Andric#include <__atomic/atomic_init.h> 527*06c3fb27SDimitry Andric#include <__atomic/atomic_lock_free.h> 528*06c3fb27SDimitry Andric#include <__atomic/atomic_sync.h> 529*06c3fb27SDimitry Andric#include <__atomic/check_memory_order.h> 530*06c3fb27SDimitry Andric#include <__atomic/contention_t.h> 531*06c3fb27SDimitry Andric#include <__atomic/cxx_atomic_impl.h> 532*06c3fb27SDimitry Andric#include <__atomic/fence.h> 533*06c3fb27SDimitry Andric#include <__atomic/is_always_lock_free.h> 534*06c3fb27SDimitry Andric#include <__atomic/kill_dependency.h> 535*06c3fb27SDimitry Andric#include <__atomic/memory_order.h> 536fe6060f1SDimitry Andric#include <__config> 5370b57cec5SDimitry Andric#include <version> 5380b57cec5SDimitry Andric 5390b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 5400b57cec5SDimitry Andric# pragma GCC system_header 5410b57cec5SDimitry Andric#endif 5420b57cec5SDimitry Andric 5430b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER 5440b57cec5SDimitry Andric# error <atomic> is not implemented 5450b57cec5SDimitry Andric#endif 546*06c3fb27SDimitry Andric 5470b57cec5SDimitry Andric#ifdef kill_dependency 54881ad6265SDimitry Andric# error <atomic> is incompatible with <stdatomic.h> before C++23. Please compile with -std=c++23. 5490b57cec5SDimitry Andric#endif 5500b57cec5SDimitry Andric 551bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 552bdd1243dSDimitry Andric# include <cmath> 553bdd1243dSDimitry Andric# include <compare> 554*06c3fb27SDimitry Andric# include <cstring> 555bdd1243dSDimitry Andric# include <type_traits> 556bdd1243dSDimitry Andric#endif 557bdd1243dSDimitry Andric 5580b57cec5SDimitry Andric#endif // _LIBCPP_ATOMIC 559