diff options
author | Tom <tomut@yahoo.com> | 2020-07-02 08:11:06 -0600 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-07-03 19:32:34 +0200 |
commit | 137e1dc7bd93d23af53dafa44a7ab95746a03cef (patch) | |
tree | 8fda7cfeffc8bd1e29b31af96ffbd24de32080bf /AK | |
parent | 6af3fff0c25b70f966ab9f2b2d3dfba3f633c9a7 (diff) | |
download | serenity-137e1dc7bd93d23af53dafa44a7ab95746a03cef.zip |
AK: Fixes for atomic pointers
Diffstat (limited to 'AK')
-rw-r--r-- | AK/Atomic.h | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/AK/Atomic.h b/AK/Atomic.h index 2bfc3e9ded..23cc6b797b 100644 --- a/AK/Atomic.h +++ b/AK/Atomic.h @@ -46,6 +46,18 @@ static inline T atomic_exchange(volatile T* var, T desired, MemoryOrder order = return __atomic_exchange_n(var, desired, order); } +template<typename T, typename V = typename RemoveVolatile<T>::Type> +static inline V* atomic_exchange(volatile T** var, V* desired, MemoryOrder order = memory_order_seq_cst) noexcept +{ + return __atomic_exchange_n(var, desired, order); +} + +template<typename T, typename V = typename RemoveVolatile<T>::Type> +static inline V* atomic_exchange(volatile T** var, std::nullptr_t, MemoryOrder order = memory_order_seq_cst) noexcept +{ + return __atomic_exchange_n(const_cast<V**>(var), nullptr, order); +} + template<typename T> static inline bool atomic_compare_exchange_strong(volatile T* var, T& expected, T desired, MemoryOrder order = memory_order_seq_cst) noexcept { @@ -55,6 +67,25 @@ static inline bool atomic_compare_exchange_strong(volatile T* var, T& expected, return __atomic_compare_exchange_n(var, &expected, desired, false, order, order); } +template<typename T, typename V = typename RemoveVolatile<T>::Type> +static inline bool atomic_compare_exchange_strong(volatile T** var, V*& expected, V* desired, MemoryOrder order = memory_order_seq_cst) noexcept +{ + if (order == memory_order_acq_rel || order == memory_order_release) + return __atomic_compare_exchange_n(var, &expected, desired, false, memory_order_release, memory_order_acquire); + else + return __atomic_compare_exchange_n(var, &expected, desired, false, order, order); +} + +template<typename T, typename V = typename RemoveVolatile<T>::Type> +static inline bool atomic_compare_exchange_strong(volatile T** var, V*& expected, std::nullptr_t, MemoryOrder order = memory_order_seq_cst) noexcept +{ + if (order == memory_order_acq_rel || order == memory_order_release) + return __atomic_compare_exchange_n(const_cast<V**>(var), &expected, nullptr, false, memory_order_release, memory_order_acquire); + else + return __atomic_compare_exchange_n(const_cast<V**>(var), &expected, nullptr, false, order, order); +} + + template<typename T> static inline T atomic_fetch_add(volatile T* var, T val, MemoryOrder order = memory_order_seq_cst) noexcept { @@ -91,12 +122,30 @@ static inline T atomic_load(volatile T* var, MemoryOrder order = memory_order_se return __atomic_load_n(var, order); } +template<typename T, typename V = typename RemoveVolatile<T>::Type> +static inline V* atomic_load(volatile T** var, MemoryOrder order = memory_order_seq_cst) noexcept +{ + return __atomic_load_n(const_cast<V**>(var), order); +} + template<typename T> static inline void atomic_store(volatile T* var, T desired, MemoryOrder order = memory_order_seq_cst) noexcept { __atomic_store_n(var, desired, order); } +template<typename T, typename V = typename RemoveVolatile<T>::Type> +static inline void atomic_store(volatile T** var, V* desired, MemoryOrder order = memory_order_seq_cst) noexcept +{ + __atomic_store_n(var, desired, order); +} + +template<typename T, typename V = typename RemoveVolatile<T>::Type> +static inline void atomic_store(volatile T** var, std::nullptr_t, MemoryOrder order = memory_order_seq_cst) noexcept +{ + __atomic_store_n(const_cast<V**>(var), nullptr, order); +} + template<typename T> class Atomic { T m_value { 0 }; @@ -111,7 +160,7 @@ public: { } - volatile T* ptr() + volatile T* ptr() noexcept { return &m_value; } @@ -240,7 +289,7 @@ public: { } - volatile T** ptr() + volatile T** ptr() noexcept { return &m_value; } |