20 #ifndef GALOIS_ATOMIC_H
21 #define GALOIS_ATOMIC_H
25 #include "galois/config.h"
34 template <
typename T,
template <
typename _>
class W,
bool CONCURRENT>
41 explicit GAtomicImpl(
const T& i) : val(i) {}
46 T operator+=(
const T& rhs) {
return __sync_add_and_fetch(&val.data, rhs); }
48 T operator-=(
const T& rhs) {
return __sync_sub_and_fetch(&(val.data), rhs); }
50 T operator++() {
return __sync_add_and_fetch(&(val.data), 1); }
52 T operator++(
int) {
return __sync_fetch_and_add(&(val.data), 1); }
54 T operator--() {
return __sync_sub_and_fetch(&(val.data), 1); }
56 T operator--(
int) {
return __sync_fetch_and_sub(&(val.data), 1); }
58 operator T()
const {
return val.data; }
60 T& operator=(
const T& i) {
return val.data = i; }
62 T& operator=(
const GAtomicImpl& i) {
return val.data = i.val.data; }
64 bool cas(
const T& expected,
const T& updated) {
65 if (val.data != expected) {
68 #if defined(__INTEL_COMPILER)
69 return __sync_bool_compare_and_swap(
70 &val.data, *reinterpret_cast<const ptrdiff_t*>(&expected),
71 *reinterpret_cast<const ptrdiff_t*>(&updated));
73 return __sync_bool_compare_and_swap(&val.data, expected, updated);
79 template <
typename T,
template <
typename _>
class W>
80 class GAtomicImpl<T, W, false> {
86 explicit GAtomicImpl(
const T& i) : val(i) {}
91 T operator+=(
const T& rhs) {
return (val.data += rhs); }
93 T operator-=(
const T& rhs) {
return (val.data -= rhs); }
95 T operator++() {
return ++(val.data); }
97 T operator++(
int) {
return (val.data)++; }
99 T operator--() {
return --(val.data); }
101 T operator--(
int) {
return (val.data)--; }
103 operator T()
const {
return val.data; }
105 T& operator=(
const T& i) {
return val.data = i; }
107 T& operator=(
const GAtomicImpl& i) {
return val.data = i.val.data; }
109 bool cas(
const T& expected,
const T& updated) {
110 if (val.data != expected) {
120 template <
typename T,
template <
typename _>
class W,
bool CONCURRENT>
121 class GAtomicBase :
public GAtomicImpl<T, W, CONCURRENT> {
122 typedef GAtomicImpl<T, W, CONCURRENT> Super_ty;
126 explicit GAtomicBase(
const T& i) : Super_ty(i) {}
129 GAtomicBase() : Super_ty() {}
131 T& operator=(
const GAtomicBase& that) {
return Super_ty::operator=(that); }
133 T& operator=(
const T& that) {
return Super_ty::operator=(that); }
137 template <
typename T,
template <
typename _>
class W,
bool CONCURRENT>
138 class GAtomicBase<T*, W, CONCURRENT> :
public GAtomicImpl<T*, W, CONCURRENT> {
139 typedef GAtomicImpl<T*, W, CONCURRENT> Super_ty;
142 typedef typename std::iterator_traits<T*>::difference_type difference_type;
144 GAtomicBase() : Super_ty() {}
146 GAtomicBase(T* i) : Super_ty(i) {}
148 T*& operator=(
const GAtomicBase& that) {
return Super_ty::operator=(that); }
150 T*& operator=(T* that) {
return Super_ty::operator=(that); }
152 T* operator+=(
const difference_type& rhs) {
154 return __sync_add_and_fetch(&Super_ty::val.data, rhs);
156 return (Super_ty::val.data += rhs);
160 T* operator-=(
const difference_type& rhs) {
162 return __sync_sub_and_fetch(&Super_ty::val.data, rhs);
164 return (Super_ty::val.data -= rhs);
170 template <
typename T,
template <
typename _>
class W,
bool CONCURRENT>
171 class GAtomicBase<const T*, W, CONCURRENT>
172 :
public GAtomicImpl<const T*, W, CONCURRENT> {
173 typedef GAtomicImpl<const T*, W, CONCURRENT> Super_ty;
177 typename std::iterator_traits<const T*>::difference_type difference_type;
179 GAtomicBase() : Super_ty() {}
181 GAtomicBase(
const T* i) : Super_ty(i) {}
183 const T*& operator=(
const GAtomicBase& that) {
184 return Super_ty::operator=(that);
187 const T*& operator=(
const T* that) {
return Super_ty::operator=(that); }
189 const T* operator+=(
const difference_type& rhs) {
191 return __sync_add_and_fetch(&Super_ty::val.data, rhs);
193 return (Super_ty::val.data += rhs);
197 const T* operator-=(
const difference_type& rhs) {
199 return __sync_sub_and_fetch(&Super_ty::val.data, rhs);
201 return (Super_ty::val.data -= rhs);
207 template <
template <
typename _>
class W,
bool CONCURRENT>
208 class GAtomicBase<bool, W, CONCURRENT>
209 :
private GAtomicImpl<bool, W, CONCURRENT> {
210 typedef GAtomicImpl<bool, W, CONCURRENT> Super_ty;
214 explicit GAtomicBase(
bool i) : Super_ty(i) {}
216 GAtomicBase() : Super_ty() {}
219 operator bool()
const {
return Super_ty::operator bool(); }
222 bool& operator=(
const GAtomicBase& i) {
return Super_ty::operator=(i); }
225 bool& operator=(
bool i) {
return Super_ty::operator=(i); }
227 bool cas(
bool expected,
bool updated) {
228 return Super_ty::cas(expected, updated);
232 template <
typename T>
233 struct DummyWrapper {
236 explicit DummyWrapper(
const T& d) : data(d) {}
247 template <
typename T,
bool CONCURRENT = true>
249 :
public internal::GAtomicBase<T, internal::DummyWrapper, CONCURRENT> {
250 typedef internal::GAtomicBase<T, internal::DummyWrapper, CONCURRENT> Super_ty;
258 T&
operator=(
const T& that) {
return Super_ty::operator=(that); }
264 template <
typename T,
bool CONCURRENT = true>
266 :
public internal::GAtomicBase<T, galois::substrate::CacheLineStorage,
279 T&
operator=(
const T& that) {
return Super_ty::operator=(that); }
T & operator=(const GAtomic &that)
Definition: Atomic.h:256
Definition: CacheLineStorage.h:32
Cache-line padded version of GAtomic.
Definition: Atomic.h:265
GAtomic()
Definition: Atomic.h:253
T & operator=(const T &that)
Definition: Atomic.h:258
T & operator=(const T &that)
Definition: Atomic.h:279
T & operator=(const GAtomicPadded &that)
Definition: Atomic.h:277
GAtomicPadded()
Definition: Atomic.h:274
GAtomic(const T &v)
Definition: Atomic.h:254
GAtomicPadded(const T &v)
Definition: Atomic.h:275
An atomic wrapper that provides sensible atomic behavior for most primative data types.
Definition: Atomic.h:248