15 #ifndef LUNCHBOX_ATOMIC_H
16 #define LUNCHBOX_ATOMIC_H
19 #include <lunchbox/compiler.h>
23 # pragma warning (push)
24 # pragma warning (disable: 4985) // inconsistent decl of ceil
27 # pragma warning (pop)
28 # pragma intrinsic(_ReadWriteBarrier)
29 #elif defined(__xlC__)
30 # include <builtins.h>
40 #ifdef LB_GCC_4_1_OR_LATER
42 #elif defined(_MSC_VER)
44 #elif defined(__xlC__)
49 # error "no memory barrier implemented for this platform"
88 LUNCHBOX_API
static T
getAndAdd( T& value,
const T increment );
91 LUNCHBOX_API
static T
getAndSub( T& value,
const T increment );
94 static T
addAndGet( T& value,
const T increment );
97 static T
subAndGet( T& value,
const T increment );
100 LUNCHBOX_API
static T
incAndGet( T& value );
103 LUNCHBOX_API
static T
decAndGet( T& value );
106 LUNCHBOX_API
static bool compareAndSwap( T* value,
const T expected,
110 explicit Atomic(
const T v = 0 );
116 operator T(
void)
const;
163 LB_ALIGN8(
mutable T _value );
168 #ifdef LB_GCC_4_1_OR_LATER
171 return __sync_fetch_and_add( &value, increment );
176 return __sync_fetch_and_sub( &value, increment );
181 return __sync_add_and_fetch( &value, increment );
186 return __sync_sub_and_fetch( &value, increment );
191 return addAndGet( value, 1 );
196 return subAndGet( value, 1 );
202 return __sync_bool_compare_and_swap( value, expected, newValue );
205 #elif defined (_MSC_VER)
210 return getAndAdd( value, increment ) + increment;
215 return getAndSub( value, increment ) - increment;
223 return __compare_and_swap( value, const_cast< T* >( &expected ), newValue );
228 const int64_t newValue )
230 return __compare_and_swaplp( value, const_cast< int64_t* >( &expected ),
235 # error No compare-and-swap implementated for this platform
243 const T oldv = value;
244 const T newv = oldv + increment;
245 if( !compareAndSwap( &value, oldv, newv ))
258 const T oldv = value;
259 const T newv = oldv - increment;
260 if( !compareAndSwap( &value, oldv, newv ))
273 const T oldv = value;
274 const T newv = oldv + increment;
288 const T oldv = value;
289 const T newv = oldv - increment;
300 return addAndGet( value, 1 );
305 return subAndGet( value, 1 );
335 return addAndGet( _value, v );
340 return subAndGet( _value, v );
345 return incAndGet( _value );
350 return decAndGet( _value );
355 return getAndAdd( _value, 1 );
360 return getAndSub( _value, 1 );
366 return _value == rhs._value;
372 return _value != rhs._value;
378 return compareAndSwap( &_value, expected, newValue );
382 #endif // LUNCHBOX_ATOMIC_H