9 #ifndef _QI_ATOMIC_HPP_
10 #define _QI_ATOMIC_HPP_
16 extern "C" long __cdecl _InterlockedIncrement(
long volatile *);
17 extern "C" long __cdecl _InterlockedDecrement(
long volatile *);
19 # pragma intrinsic(_InterlockedIncrement)
20 # pragma intrinsic(_InterlockedDecrement)
24 #include <boost/static_assert.hpp>
26 #include <qi/config.hpp>
34 return __sync_bool_compare_and_swap(cond, 0, 1);
35 #elif defined _MSC_VER
36 return 1 - InterlockedCompareExchange(cond, 1, 0);
38 #error "Unknown platform, testAndSet not implemented"
68 inline T
swap(T value);
102 template <
typename T>
105 return __sync_add_and_fetch(&_value, 1);
108 template <
typename T>
111 return __sync_sub_and_fetch(&_value, 1);
114 template <
typename T>
117 __sync_lock_test_and_set(&_value, value);
121 template <
typename T>
124 return __sync_lock_test_and_set(&_value, value);
126 template <
typename T>
129 return __sync_bool_compare_and_swap(&_value, testValue, setValue);
138 return _InterlockedIncrement(&_value);
144 return _InterlockedDecrement(&_value);
150 InterlockedExchange(&_value, value);
157 return InterlockedExchange(&_value, value);
163 return _InterlockedCompareExchange(&_value, setValue, testValue) == testValue;
167 inline unsigned int AtomicBase<unsigned int>::operator++()
169 return _InterlockedIncrement(&_value);
173 inline unsigned int AtomicBase<unsigned int>::operator--()
175 return _InterlockedDecrement(&_value);
179 inline AtomicBase<unsigned int>& AtomicBase<unsigned int>::operator=(
unsigned int value)
181 InterlockedExchange(&_value, value);
186 inline unsigned int AtomicBase<unsigned int>::swap(
unsigned int value)
188 return InterlockedExchange(&_value, value);
192 inline bool AtomicBase<unsigned int>::setIfEquals(
unsigned int testValue,
unsigned int setValue)
194 return _InterlockedCompareExchange(&_value, setValue, testValue) == testValue;
200 #define _QI_INSTANCIATE(_, a, elem) ::qi::details::newAndAssign(&elem);
210 #define QI_THREADSAFE_NEW(...) \
211 QI_ONCE(QI_VAARGS_APPLY(_QI_INSTANCIATE, _, __VA_ARGS__);)
214 #define QI_ONCE(code) \
215 static qi::AtomicBase<int> QI_UNIQ_DEF(atomic_guard_a) = {0}; \
216 static qi::AtomicBase<int> QI_UNIQ_DEF(atomic_guard_b) = {0}; \
217 while (!QI_UNIQ_DEF(atomic_guard_a).setIfEquals(1, 1)) \
219 bool tok = QI_UNIQ_DEF(atomic_guard_b).setIfEquals(0,1); \
223 ++QI_UNIQ_DEF(atomic_guard_a); \
228 #endif // _QI_ATOMIC_HPP_
Atomic()
Default atomic constructor, setting value to 0.
Various macros for qi. (deprecated, export API, disallow copy, ..)
Atomic(T value)
Atomic constructor setting value to its parameter.
Atomic operations on integers.
long testAndSet(long *cond)
AtomicBase< T > & operator=(T value)
bool setIfEquals(T testValue, T setValue)
BOOST_STATIC_ASSERT_MSG(sizeof(T)==sizeof(int),"qi::Atomic is only supprted for int-like types")