X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FAtomicStruct.h;h=a774d31500fd952afd49e1a326560d30e3c5eaa6;hb=39018ad5c77c53156cb7cd672c05a19fb75a6af7;hp=ce1dedd4876eaebd835947994067836c23e18f9d;hpb=275ca94d04e44f28cfa411668eb1c1dd8db90b80;p=folly.git diff --git a/folly/AtomicStruct.h b/folly/AtomicStruct.h index ce1dedd4..a774d315 100644 --- a/folly/AtomicStruct.h +++ b/folly/AtomicStruct.h @@ -1,5 +1,5 @@ /* - * Copyright 2015 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,26 +14,26 @@ * limitations under the License. */ -#ifndef FOLLY_ATOMIC_STRUCT_H_ -#define FOLLY_ATOMIC_STRUCT_H_ +#pragma once -#include -#include #include -#include +#include #include +#include +#include +#include namespace folly { namespace detail { template struct AtomicStructIntPick {}; -} +} // namespace detail /// AtomicStruct work like C++ atomics, but can be used on any POD /// type <= 8 bytes. template < typename T, - template class Atom = std::atomic, + template class Atom = std::atomic, typename Raw = typename detail::AtomicStructIntPick::type> class AtomicStruct { static_assert(alignof(T) <= alignof(Raw), @@ -44,7 +44,10 @@ class AtomicStruct { folly::IsTriviallyCopyable::value, "target type must be trivially copyable"); - Atom data; + union { + Atom data; + T typedData; + }; static Raw encode(T v) noexcept { // we expect the compiler to optimize away the memcpy, but without @@ -66,17 +69,26 @@ class AtomicStruct { AtomicStruct(AtomicStruct const &) = delete; AtomicStruct& operator= (AtomicStruct const &) = delete; - constexpr /* implicit */ AtomicStruct(T v) noexcept : data(encode(v)) {} + constexpr /* implicit */ AtomicStruct(T v) noexcept : typedData(v) {} bool is_lock_free() const noexcept { return data.is_lock_free(); } bool compare_exchange_strong( - T& v0, T v1, - std::memory_order mo = std::memory_order_seq_cst) noexcept { + T& v0, + T v1, + std::memory_order mo = std::memory_order_seq_cst) noexcept { + return compare_exchange_strong( + v0, v1, mo, detail::default_failure_memory_order(mo)); + } + bool compare_exchange_strong( + T& v0, + T v1, + std::memory_order success, + std::memory_order failure) noexcept { Raw d0 = encode(v0); - bool rv = data.compare_exchange_strong(d0, encode(v1), mo); + bool rv = data.compare_exchange_strong(d0, encode(v1), success, failure); if (!rv) { v0 = decode(d0); } @@ -84,10 +96,19 @@ class AtomicStruct { } bool compare_exchange_weak( - T& v0, T v1, - std::memory_order mo = std::memory_order_seq_cst) noexcept { + T& v0, + T v1, + std::memory_order mo = std::memory_order_seq_cst) noexcept { + return compare_exchange_weak( + v0, v1, mo, detail::default_failure_memory_order(mo)); + } + bool compare_exchange_weak( + T& v0, + T v1, + std::memory_order success, + std::memory_order failure) noexcept { Raw d0 = encode(v0); - bool rv = data.compare_exchange_weak(d0, encode(v1), mo); + bool rv = data.compare_exchange_weak(d0, encode(v1), success, failure); if (!rv) { v0 = decode(d0); } @@ -135,5 +156,3 @@ template <> struct AtomicStructIntPick<8> { typedef uint64_t type; }; } // namespace detail } // namespace folly - -#endif