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)
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();
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)
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();
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);
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;