35 #include "Honey/Thread/platform/Atomic.h"
60 static bool cas(
volatile T& dst, T newVal, T cmp,
Order o =
Order::seqCst) {
return Super::cas(dst, newVal, cmp, o); }
64 static T
swap(
volatile T& dst, T newVal,
Order o =
Order::seqCst) { T v;
do { v = dst; }
while (!
cas(dst, newVal, v, o));
return v; }
79 static T
add(
volatile T& val, T rhs,
Order o =
Order::seqCst) { T v;
do { v = val; }
while (!
cas(val, v+rhs, v, o));
return v; }
87 static T
or_(
volatile T& val, T rhs,
Order o =
Order::seqCst) { T v;
do { v = val; }
while (!
cas(val, v|rhs, v, o));
return v; }
110 static_assert(
sizeof(T) <=
sizeof(SwapMaxType),
"Type too large for atomic ops");
111 typedef typename std::conditional<
113 typename std::conditional<sizeof(T) <= sizeof(int64), int64, SwapMaxType>::type
118 template<class T, bool B = std::is_integral<T>::value>
132 SwapVal(T val) {
new (&this->val) T(val); }
137 static_assert(std::is_trivially_copyable<T>::value,
"Atomic type must be trivially copyable");
146 T
operator=(T val)
volatile { store(val);
return *
this; }
150 operator T()
const volatile {
return load(); }
152 void store(T val, Order o = Order::seqCst)
volatile { Op::store(_val, SwapVal(val).val, o); }
153 T
load(Order o = Order::seqCst)
const volatile {
auto ret = Op::load(_val, o);
return reinterpret_cast<T&
>(ret); }
156 bool cas(T newVal, T cmp, Order o = Order::seqCst)
volatile {
return Op::cas(_val, SwapVal(newVal).val, SwapVal(cmp).val, o); }
176 T
operator=(T val)
volatile { store(val);
return *
this; }
199 operator T()
const volatile {
return load(); }
201 void store(T val, Order o = Order::seqCst)
volatile { Op::store(_val, static_cast<SwapType>(val), o); }
202 T
load(Order o = Order::seqCst)
const volatile {
return static_cast<T
>(Op::load(_val, o)); }
203 T
add(T rhs, Order o = Order::seqCst)
volatile {
return Op::add(_val, static_cast<SwapType>(rhs), o) + rhs; }
204 T
sub(T rhs, Order o = Order::seqCst)
volatile {
return Op::add(_val, static_cast<SwapType>(-rhs), o) - rhs; }
205 T
and_(T rhs, Order o = Order::seqCst)
volatile {
return Op::and_(_val, static_cast<SwapType>(rhs), o) & rhs; }
206 T
or_(T rhs, Order o = Order::seqCst)
volatile {
return Op::or_(_val, static_cast<SwapType>(rhs), o) | rhs; }
207 T
xor_(T rhs, Order o = Order::seqCst)
volatile {
return Op::xor_(_val, static_cast<SwapType>(rhs), o) ^ rhs; }
210 bool cas(T newVal, T cmp, Order o = Order::seqCst)
volatile {
return Op::cas(_val, static_cast<SwapType>(newVal), static_cast<SwapType>(cmp), o); }
229 T*
operator=(T* val)
volatile { store(val);
return *
this; }
232 T*
operator++()
volatile {
return reinterpret_cast<T*
>(Op::add(_val,
sizeof(T))) + 1; }
233 T*
operator++(
int)
volatile {
return reinterpret_cast<T*
>(Op::add(_val,
sizeof(T))); }
234 T*
operator--()
volatile {
return reinterpret_cast<T*
>(Op::add(_val, -
sizeof(T))) - 1; }
235 T*
operator--(
int)
volatile {
return reinterpret_cast<T*
>(Op::add(_val, -
sizeof(T))); }
241 operator T*()
const volatile {
return load(); }
243 void store(T* val, Order o = Order::seqCst)
volatile { Op::store(_val, reinterpret_cast<SwapType>(val), o); }
244 T*
load(Order o = Order::seqCst)
const volatile {
return reinterpret_cast<T*
>(Op::load(_val, o)); }
245 T*
add(
sdt rhs, Order o = Order::seqCst)
volatile {
return reinterpret_cast<T*
>(Op::add(_val, rhs*
sizeof(T), o)) + rhs; }
246 T*
sub(
sdt rhs, Order o = Order::seqCst)
volatile {
return reinterpret_cast<T*
>(Op::add(_val, -rhs*
sizeof(T), o)) - rhs; }
248 bool cas(T* newVal, T* cmp, Order o = Order::seqCst)
volatile {
return Op::cas(_val, reinterpret_cast<SwapType>(newVal), reinterpret_cast<SwapType>(cmp), o); }
256 ostream& operator<<(ostream& os, const Atomic<T>& val) {
return os << val.load(); }
T operator++(int) volatile
Post-increment, returns initial value.
Definition: Atomic.h:182
void store(T *val, Order o=Order::seqCst) volatile
Definition: Atomic.h:243
static bool cas(volatile T &dst, T newVal, T cmp, Order o=Order::seqCst)
Compare and swap. If dst is equal to comparand cmp then dst is assigned to newVal and true is returne...
Definition: Atomic.h:60
Atomic(const Atomic &val)
Definition: Atomic.h:227
T operator&=(T rhs) volatile
And and return new value.
Definition: Atomic.h:192
static T xor_(volatile T &val, T rhs, Order o=Order::seqCst)
val ^= rhs. Returns the initial value.
Definition: Atomic.h:91
static T add(volatile T &val, T rhs, Order o=Order::seqCst)
val += rhs. Returns the initial value.
Definition: Atomic.h:79
ptrdiff_t sdt
Size difference type, shorthand for ptrdiff_t.
Definition: Core.h:92
T operator=(T val) volatile
Assign value.
Definition: Atomic.h:176
static T and_(volatile T &val, T rhs, Order o=Order::seqCst)
val &= rhs. Returns the initial value.
Definition: Atomic.h:83
T operator+=(T rhs) volatile
Add and return new value.
Definition: Atomic.h:188
bool cas(T newVal, T cmp, Order o=Order::seqCst) volatile
Compare and swap. If atomic is equal to comparand cmp then atomic is assigned to newVal and true is r...
Definition: Atomic.h:210
Methods to perform thread-safe atomic read/write operations.
Definition: Atomic.h:43
T * operator=(T *val) volatile
Definition: Atomic.h:229
T load(Order o=Order::seqCst) const volatile
Definition: Atomic.h:153
T * operator+=(sdt rhs) volatile
Definition: Atomic.h:236
Must be a store op. Synchronize with a later acquire in another thread.
Order
Atomic memory order for concurrent synchronization between threads.
Definition: Atomic.h:23
T operator++() volatile
Pre-increment, returns new value.
Definition: Atomic.h:180
T operator--(int) volatile
Post-decrement, returns initial value.
Definition: Atomic.h:186
ostream & dec(ostream &os)
Use decimal encoding (big-endian integer) when writing bytes to a string stream.
Definition: Encode.h:66
T operator=(T val) volatile
Assign value.
Definition: Atomic.h:146
T * load(Order o=Order::seqCst) const volatile
Definition: Atomic.h:244
T add(T rhs, Order o=Order::seqCst) volatile
Definition: Atomic.h:203
T * add(sdt rhs, Order o=Order::seqCst) volatile
Definition: Atomic.h:245
T operator=(const Atomic &val) volatile
Definition: Atomic.h:177
Must be a load op. Synchronize with a prior release in another thread.
T operator|=(T rhs) volatile
Or and return new value.
Definition: Atomic.h:194
static T inc(volatile T &val, Order o=Order::seqCst)
Increments val. Returns the initial value.
Definition: Atomic.h:69
T xor_(T rhs, Order o=Order::seqCst) volatile
Definition: Atomic.h:207
Get the smallest atomically-swappable type that is large enough to hold T.
Definition: Atomic.h:108
void store(T val, Order o=Order::seqCst) volatile
Definition: Atomic.h:152
T sub(T rhs, Order o=Order::seqCst) volatile
Definition: Atomic.h:204
Atomic(const Atomic &val)
Definition: Atomic.h:173
No order constraint, same as plain load/store. Unsafe but best performance.
int int32
Definition: Core.h:15
static void fence(Order o=Order::seqCst)
Create a memory barrier that synchronizes operations.
Definition: Atomic.h:101
Atomic(T val)
Definition: Atomic.h:172
Atomic(const Atomic &val)
Definition: Atomic.h:143
T operator-=(T rhs) volatile
Sub and return new value.
Definition: Atomic.h:190
static T load(volatile const T &val, Order o=Order::seqCst)
Returns val.
Definition: Atomic.h:50
T load(Order o=Order::seqCst) const volatile
Definition: Atomic.h:202
T * operator++(int) volatile
Definition: Atomic.h:233
T * operator->() const volatile
Definition: Atomic.h:239
T and_(T rhs, Order o=Order::seqCst) volatile
Definition: Atomic.h:205
static T or_(volatile T &val, T rhs, Order o=Order::seqCst)
val |= rhs. Returns the initial value.
Definition: Atomic.h:87
T * sub(sdt rhs, Order o=Order::seqCst) volatile
Definition: Atomic.h:246
Atomic(T *val)
Definition: Atomic.h:226
bool cas(T *newVal, T *cmp, Order o=Order::seqCst) volatile
Definition: Atomic.h:248
void store(T val, Order o=Order::seqCst) volatile
Definition: Atomic.h:201
bool cas(T newVal, T cmp, Order o=Order::seqCst) volatile
Compare and swap. If atomic is equal to comparand cmp then atomic is assigned to newVal and true is r...
Definition: Atomic.h:156
static T swap(volatile T &dst, T newVal, Order o=Order::seqCst)
Assigns dst to newVal and returns initial value of dst.
Definition: Atomic.h:64
T * operator=(const Atomic &val) volatile
Definition: Atomic.h:230
Op
Definition: Unique.h:16
Sequential consistency, safe total order but least performance.
Atomic(T val)
Initialize the underlying value to val
Definition: Atomic.h:142
static void store(volatile T &dst, T newVal, Order o=Order::seqCst)
Assigns dst to newVal.
Definition: Atomic.h:55
Must be a load op. Synchronize with a prior release in another thread, but only synchronize ops depen...
T & operator*() const volatile
Definition: Atomic.h:240
Must be a load-modify-store op. Performs both acquire and release.
T operator^=(T rhs) volatile
Xor and return new value.
Definition: Atomic.h:196
T operator=(const Atomic &val) volatile
Definition: Atomic.h:147
T * operator++() volatile
Definition: Atomic.h:232
T * operator--(int) volatile
Definition: Atomic.h:235
T * operator-=(sdt rhs) volatile
Definition: Atomic.h:237
T * operator--() volatile
Definition: Atomic.h:234
platform::SwapMaxType SwapMaxType
Largest atomically-swappable type.
Definition: Atomic.h:105
Global Honeycomb namespace.
static T dec(volatile T &val, Order o=Order::seqCst)
Decrements val. Returns the initial value.
Definition: Atomic.h:74
T operator--() volatile
Pre-decrement, returns new value.
Definition: Atomic.h:184
T or_(T rhs, Order o=Order::seqCst) volatile
Definition: Atomic.h:206