50 #if defined(VTK_HAVE_SYNC_BUILTINS)
51 # define VTK_GCC_ATOMICS_32
52 # if VTK_SIZEOF_VOID_P == 8
53 # define VTK_GCC_ATOMICS_64
55 #elif defined(__APPLE__)
56 # include <libkern/OSAtomic.h>
57 # define VTK_APPLE_ATOMICS_32
58 # if VTK_SIZEOF_VOID_P == 8
59 # define VTK_APPLE_ATOMICS_64
61 #elif defined(_WIN32) && defined(_MSC_VER)
62 # define VTK_WINDOWS_ATOMICS_32
63 # if VTK_SIZEOF_VOID_P == 8
64 # define VTK_WINDOWS_ATOMICS_64
69 #if defined(_WIN32) && defined(_MSC_VER)
71 # pragma warning(disable:4324)
72 # define VTK_ALIGN(X) __declspec(align(X))
73 #elif defined(__GNUC__) // gcc compatible compiler
74 # define VTK_ALIGN(X) __attribute__ ((aligned (X)))
89 #if defined(VTK_GCC_ATOMICS_64)
96 static value_type AddAndFetch(value_type *ref, value_type val)
98 return __sync_add_and_fetch(ref, val);
103 return __sync_sub_and_fetch(ref, val);
108 return __sync_add_and_fetch(ref, 1);
113 return __sync_sub_and_fetch(ref, 1);
118 return __sync_fetch_and_add(ref, 1);
123 return __sync_fetch_and_sub(ref, 1);
128 __sync_synchronize();
129 return *
static_cast<const volatile value_type *
>(ref);
134 *
static_cast<volatile value_type*
>(ref) = val;
135 __sync_synchronize();
139 #elif defined(VTK_APPLE_ATOMICS_64)
140 template <>
class AtomicOps<8>
143 typedef vtkTypeInt64
VTK_ALIGN(8) atomic_type;
144 typedef vtkTypeInt64 value_type;
146 static vtkTypeInt64 AddAndFetch(vtkTypeInt64 *ref, vtkTypeInt64 val)
148 return OSAtomicAdd64Barrier(val, ref);
151 static vtkTypeInt64 SubAndFetch(vtkTypeInt64 *ref, vtkTypeInt64 val)
153 return OSAtomicAdd64Barrier(-val, ref);
156 static vtkTypeInt64 PreIncrement(vtkTypeInt64 *ref)
158 return OSAtomicIncrement64Barrier(ref);
161 static vtkTypeInt64 PreDecrement(vtkTypeInt64 *ref)
163 return OSAtomicDecrement64Barrier(ref);
166 static vtkTypeInt64 PostIncrement(vtkTypeInt64 *ref)
168 vtkTypeInt64 val = OSAtomicIncrement64Barrier(ref);
172 static vtkTypeInt64 PostDecrement(vtkTypeInt64 *ref)
174 vtkTypeInt64 val = OSAtomicDecrement64Barrier(ref);
178 static vtkTypeInt64 Load(
const vtkTypeInt64 *ref);
181 return *
static_cast<const volatile vtkTypeInt64*
>(ref);
184 static void Store(vtkTypeInt64 *ref, vtkTypeInt64 val);
186 *
static_cast<volatile vtkTypeInt64*
>(ref) = val;
196 #if defined(VTK_WINDOWS_ATOMICS_64)
197 typedef vtkTypeInt64
VTK_ALIGN(8) atomic_type;
204 atomic_type(vtkTypeInt64 init);
208 typedef vtkTypeInt64 value_type;
210 static vtkTypeInt64 AddAndFetch(atomic_type *ref, vtkTypeInt64 val);
211 static vtkTypeInt64 SubAndFetch(atomic_type *ref, vtkTypeInt64 val);
212 static vtkTypeInt64 PreIncrement(atomic_type *ref);
213 static vtkTypeInt64 PreDecrement(atomic_type *ref);
214 static vtkTypeInt64 PostIncrement(atomic_type *ref);
215 static vtkTypeInt64 PostDecrement(atomic_type *ref);
216 static vtkTypeInt64 Load(
const atomic_type *ref);
217 static void Store(atomic_type *ref, vtkTypeInt64 val);
222 #if defined(VTK_GCC_ATOMICS_32)
229 static value_type AddAndFetch(value_type *ref, value_type val)
231 return __sync_add_and_fetch(ref, val);
236 return __sync_sub_and_fetch(ref, val);
241 return __sync_add_and_fetch(ref, 1);
246 return __sync_sub_and_fetch(ref, 1);
251 return __sync_fetch_and_add(ref, 1);
256 return __sync_fetch_and_sub(ref, 1);
261 __sync_synchronize();
262 return *
static_cast<const volatile value_type *
>(ref);
267 *
static_cast<volatile value_type*
>(ref) = val;
268 __sync_synchronize();
272 #elif defined(VTK_APPLE_ATOMICS_32)
273 template <>
class AtomicOps<4>
276 typedef vtkTypeInt32
VTK_ALIGN(4) atomic_type;
277 typedef vtkTypeInt32 value_type;
279 static vtkTypeInt32 AddAndFetch(vtkTypeInt32 *ref, vtkTypeInt32 val)
281 return OSAtomicAdd32Barrier(val, ref);
284 static vtkTypeInt32 SubAndFetch(vtkTypeInt32 *ref, vtkTypeInt32 val)
286 return OSAtomicAdd32Barrier(-val, ref);
289 static vtkTypeInt32 PreIncrement(vtkTypeInt32 *ref)
291 return OSAtomicIncrement32Barrier(ref);
294 static vtkTypeInt32 PreDecrement(vtkTypeInt32 *ref)
296 return OSAtomicDecrement32Barrier(ref);
299 static vtkTypeInt32 PostIncrement(vtkTypeInt32 *ref)
301 vtkTypeInt32 val = OSAtomicIncrement32Barrier(ref);
305 static vtkTypeInt32 PostDecrement(vtkTypeInt32 *ref)
307 vtkTypeInt32 val = OSAtomicDecrement32Barrier(ref);
311 static vtkTypeInt32 Load(
const vtkTypeInt32 *ref);
314 return *
static_cast<const volatile vtkTypeInt32*
>(ref);
317 static void Store(vtkTypeInt32 *ref, vtkTypeInt32 val);
319 *
static_cast<volatile vtkTypeInt32*
>(ref) = val;
329 #if defined(VTK_WINDOWS_ATOMICS_32)
330 typedef vtkTypeInt32
VTK_ALIGN(4) atomic_type;
337 atomic_type(vtkTypeInt32 init);
341 typedef vtkTypeInt32 value_type;
343 static vtkTypeInt32 AddAndFetch(atomic_type *ref, vtkTypeInt32 val);
344 static vtkTypeInt32 SubAndFetch(atomic_type *ref, vtkTypeInt32 val);
345 static vtkTypeInt32 PreIncrement(atomic_type *ref);
346 static vtkTypeInt32 PreDecrement(atomic_type *ref);
347 static vtkTypeInt32 PostIncrement(atomic_type *ref);
348 static vtkTypeInt32 PostDecrement(atomic_type *ref);
349 static vtkTypeInt32 Load(
const atomic_type *ref);
350 static void Store(atomic_type *ref, vtkTypeInt32 val);
367 vtkAtomic(T val) : Atomic(static_cast<typename Impl::value_type>(val))
372 : Atomic(static_cast<typename Impl::value_type>(atomic.
load()))
378 return static_cast<T
>(Impl::PreIncrement(&this->Atomic));
383 return static_cast<T
>(Impl::PostIncrement(&this->Atomic));
388 return static_cast<T
>(Impl::PreDecrement(&this->Atomic));
393 return static_cast<T
>(Impl::PostDecrement(&this->Atomic));
398 return static_cast<T
>(Impl::AddAndFetch(&this->Atomic,
399 static_cast<typename Impl::value_type>(val)));
404 return static_cast<T
>(Impl::SubAndFetch(&this->Atomic,
405 static_cast<typename Impl::value_type>(val)));
410 return static_cast<T
>(Impl::Load(&this->Atomic));
415 Impl::Store(&this->Atomic, static_cast<typename Impl::value_type>(val));
427 return static_cast<T
>(Impl::Load(&this->Atomic));
432 Impl::Store(&this->Atomic, static_cast<typename Impl::value_type>(val));
436 typename Impl::atomic_type Atomic;
451 : Atomic(reinterpret_cast<typename Impl::value_type>(val))
456 : Atomic(reinterpret_cast<typename Impl::value_type>(atomic.
load()))
462 return reinterpret_cast<T*
>(Impl::AddAndFetch(&this->Atomic,
sizeof(T)));
467 T* val =
reinterpret_cast<T*
>(Impl::AddAndFetch(&this->Atomic,
sizeof(T)));
473 return reinterpret_cast<T*
>(Impl::SubAndFetch(&this->Atomic,
sizeof(T)));
478 T* val =
reinterpret_cast<T*
>(Impl::AddAndFetch(&this->Atomic,
sizeof(T)));
484 return reinterpret_cast<T*
>(Impl::AddAndFetch(&this->Atomic,
490 return reinterpret_cast<T*
>(Impl::SubAndFetch(&this->Atomic,
496 return reinterpret_cast<T*
>(Impl::Load(&this->Atomic));
501 Impl::Store(&this->Atomic,
502 reinterpret_cast<typename Impl::value_type>(val));
514 return reinterpret_cast<T*
>(Impl::Load(&this->Atomic));
519 Impl::Store(&this->Atomic,
520 reinterpret_cast<typename Impl::value_type>(val));
524 typename Impl::atomic_type Atomic;
539 : Atomic(reinterpret_cast<Impl::value_type>(val))
544 : Atomic(reinterpret_cast<Impl::value_type>(atomic.
load()))
548 operator void*()
const
550 return reinterpret_cast<void*
>(Impl::Load(&this->Atomic));
555 Impl::Store(&this->Atomic,
556 reinterpret_cast<Impl::value_type>(val));
568 return reinterpret_cast<void*
>(Impl::Load(&this->Atomic));
573 Impl::Store(&this->Atomic,
574 reinterpret_cast<Impl::value_type>(val));
578 Impl::atomic_type Atomic;
vtkAtomic< T > & operator=(const vtkAtomic< T > &atomic)
static value_type Load(const value_type *ref)
static value_type Load(const value_type *ref)
T * operator+=(std::ptrdiff_t val)
#define VTKCOMMONCORE_EXPORT
static value_type PostIncrement(value_type *ref)
static value_type PostDecrement(value_type *ref)
static void Store(value_type *ref, value_type val)
Provides support for atomic integers.
vtkAtomic(const vtkAtomic< T > &atomic)
static value_type PostDecrement(value_type *ref)
static value_type PreDecrement(value_type *ref)
vtkAtomic< T * > & operator=(const vtkAtomic< T * > &atomic)
static value_type PostIncrement(value_type *ref)
static value_type SubAndFetch(value_type *ref, value_type val)
static value_type PreIncrement(value_type *ref)
T * operator-=(std::ptrdiff_t val)
static value_type PreDecrement(value_type *ref)
static void Store(value_type *ref, value_type val)
vtkTypeInt32 VTK_ALIGN(4) atomic_type
vtkAtomic< void * > & operator=(const vtkAtomic< void * > &atomic)
static value_type SubAndFetch(value_type *ref, value_type val)
Critical section locking class.
vtkAtomic(const vtkAtomic< void * > &atomic)
static value_type PreIncrement(value_type *ref)
void * operator=(void *val)
vtkTypeInt64 VTK_ALIGN(8) atomic_type
vtkAtomic(const vtkAtomic< T * > &atomic)