VTK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
vtkAtomicInt.h
Go to the documentation of this file.
1  /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkAtomicInt.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
39 #ifndef __vtkAtomicInt_h
40 #define __vtkAtomicInt_h
41 
42 #include "vtkCommonCoreModule.h" // For export macro
43 #include "vtkSystemIncludes.h"
44 #include "vtkConfigure.h"
45 
46 #if defined(__APPLE__)
47 # include <libkern/OSAtomic.h>
48 #endif
49 
50 #if (defined(_WIN32) && !defined(__MINGW32__))
51 # define VTK_WINDOWS_ATOMIC
52 # if defined(_MSC_VER)
53 # pragma warning(disable:4324) // disable warning about the padding due to alignment
54 # endif
55 #endif
56 
57 #if defined(VTK_WINDOWS_ATOMIC) || defined(__APPLE__) || defined(VTK_HAVE_SYNC_BUILTINS)
58 # define VTK_HAS_ATOMIC32
59 #endif
60 
61 // Overall, we assume that 64 bit atomic operations are not available on 32
62 // bit systems.
63 #if VTK_SIZEOF_VOID_P == 8
64 # if defined(VTK_WINDOWS_ATOMIC) || defined(__APPLE__) || defined(VTK_HAVE_SYNC_BUILTINS)
65 # define VTK_HAS_ATOMIC64
66 # endif
67 #endif
68 
69 #if !defined(VTK_HAS_ATOMIC64) || !defined(VTK_HAS_ATOMIC32)
71 #endif
72 
73 // Below are the actual implementations of 32 and 64 bit atomic operations.
74 namespace detail
75 {
76 #if defined (VTK_WINDOWS_ATOMIC)
77 # define VTK__ALIGN32 __declspec(align(32))
78 #else
79 # define VTK__ALIGN32
80 #endif
81 
82 template <typename T> class vtkAtomicIntImpl;
83 
84 template <>
85 #if defined(VTK_HAS_ATOMIC32) && !defined(VTK_WINDOWS_ATOMIC)
86 class vtkAtomicIntImpl<vtkTypeInt32>
87 #else
88 class VTKCOMMONCORE_EXPORT vtkAtomicIntImpl<vtkTypeInt32>
89 #endif
90 {
91 public:
92 
94 
95 #if defined(VTK_HAS_ATOMIC32) && !defined(VTK_WINDOWS_ATOMIC)
96  vtkTypeInt32 operator++()
97  {
98 # if defined(__APPLE__)
99  return OSAtomicIncrement32Barrier(&this->Value);
101 
102 // GCC, CLANG, etc
103 # elif defined(VTK_HAVE_SYNC_BUILTINS)
104  return __sync_add_and_fetch(&this->Value, 1);
105 
106 # endif
107  }
108 
110 
111  vtkTypeInt32 operator--()
112  {
113 # if defined(__APPLE__)
114  return OSAtomicDecrement32Barrier(&this->Value);
116 
117 // GCC, CLANG, etc
118 # elif defined(VTK_HAVE_SYNC_BUILTINS)
119  return __sync_sub_and_fetch(&this->Value, 1);
120 
121 # endif
122  }
123 
125 
126  vtkTypeInt32 operator+=(vtkTypeInt32 val)
127  {
128 # if defined(__APPLE__)
129  return OSAtomicAdd32Barrier(val, &this->Value);
131 
132 // GCC, CLANG, etc
133 # elif defined(VTK_HAVE_SYNC_BUILTINS)
134  return __sync_add_and_fetch(&this->Value, val);
135 
136 # endif
137  }
138 
140 
141  vtkTypeInt32 load() const
142  {
143 # if defined(__APPLE__)
144  vtkTypeInt32 retval = 0;
145  OSAtomicCompareAndSwap32Barrier(retval, this->Value, &retval);
146  return retval;
148 
149 // GCC, CLANG, etc
150 # elif defined(VTK_HAVE_SYNC_BUILTINS)
151  vtkTypeInt32 retval = 0;
152  __sync_val_compare_and_swap(&retval, retval, this->Value);
153  return retval;
154 
155 # endif
156  }
157 
159 
160  void store(vtkTypeInt32 val)
161  {
162 # if defined(__APPLE__)
163  OSAtomicCompareAndSwap32Barrier(this->Value, val, &this->Value);
165 
166 // GCC, CLANG, etc
167 # elif defined(VTK_HAVE_SYNC_BUILTINS)
168  __sync_val_compare_and_swap(&this->Value, this->Value, val);
169 
170 #endif
171  }
172 
173 #else // defined(VTK_HAS_ATOMIC32) && !defined(VTK_WINDOWS_ATOMIC)
174 
175  // These methods are for when using a mutex. Same as above.
176  // A virtual descructor is used becase the mutex is constructed
177  // with new to avoid including windows header in the .h file.
180  vtkTypeInt32 operator++();
181  vtkTypeInt32 operator--();
182  vtkTypeInt32 operator+=(vtkTypeInt32 val);
183  vtkTypeInt32 load() const;
184  void store(vtkTypeInt32 val);
185 
186 #endif // defined(VTK_HAS_ATOMIC32) && !defined(VTK_WINDOWS_ATOMIC)
187 
188 protected:
189  // Explicitely aligning Value on Windows is probably not necessary
190  // since the compiler should automatically do it. Just being extra
191  // cautious since the InterlockedXXX() functions require alignment.
192  VTK__ALIGN32 vtkTypeInt32 Value;
193 
194 #if !defined(VTK_HAS_ATOMIC32)
195  vtkSimpleCriticalSection* AtomicInt32CritSec;
196 #endif
197 };
198 
199 #if defined (VTK_WINDOWS_ATOMIC)
200 # define VTK__ALIGN64 __declspec(align(64))
201 #else
202 # define VTK__ALIGN64
203 #endif
204 
205 template <>
206 #if defined(VTK_HAS_ATOMIC64) && !defined(VTK_WINDOWS_ATOMIC)
207 class vtkAtomicIntImpl<vtkTypeInt64>
208 #else
209 class VTKCOMMONCORE_EXPORT vtkAtomicIntImpl<vtkTypeInt64>
210 #endif
211 {
212 public:
213 
215 
216 #if defined(VTK_HAS_ATOMIC64) && !defined(VTK_WINDOWS_ATOMIC)
217  vtkTypeInt64 operator++()
218  {
219 # if defined(__APPLE__)
220  return OSAtomicIncrement64Barrier(&this->Value);
222 
223 // GCC, CLANG, etc
224 # elif defined(VTK_HAVE_SYNC_BUILTINS)
225  return __sync_add_and_fetch(&this->Value, 1);
226 
227 # endif
228  }
229 
231 
232  vtkTypeInt64 operator--()
233  {
234 # if defined(__APPLE__)
235  return OSAtomicDecrement64Barrier(&this->Value);
237 
238 // GCC, CLANG, etc
239 # elif defined(VTK_HAVE_SYNC_BUILTINS)
240  return __sync_sub_and_fetch(&this->Value, 1);
241 
242 # endif
243  }
244 
246 
247  vtkTypeInt64 operator+=(vtkTypeInt64 val)
248  {
249 # if defined(__APPLE__)
250  return OSAtomicAdd64Barrier(val, &this->Value);
252 
253 // GCC, CLANG, etc
254 # elif defined(VTK_HAVE_SYNC_BUILTINS)
255  return __sync_add_and_fetch(&this->Value, val);
256 
257 # endif
258  }
259 
261 
262  vtkTypeInt64 load() const
263  {
264 # if defined(__APPLE__)
265  vtkTypeInt64 retval = 0;
266  OSAtomicCompareAndSwap64Barrier(retval, this->Value, &retval);
267  return retval;
269 
270 // GCC, CLANG, etc
271 # elif defined(VTK_HAVE_SYNC_BUILTINS)
272  vtkTypeInt64 retval = 0;
273  __sync_val_compare_and_swap(&retval, retval, this->Value);
274  return retval;
275 
276 # endif
277  }
278 
280 
281  void store(vtkTypeInt64 val)
282  {
283 # if defined(__APPLE__)
284  OSAtomicCompareAndSwap64Barrier(this->Value, val, &this->Value);
286 
287 // GCC, CLANG, etc
288 # elif defined(VTK_HAVE_SYNC_BUILTINS)
289  __sync_val_compare_and_swap(&this->Value, this->Value, val);
290 
291 # endif
292  }
293 
294 #else // defined(VTK_HAS_ATOMIC64) && !defined(VTK_WINDOWS_ATOMIC)
295 
296  // These methods are for when using a mutex. Same as above.
297  // A virtual descructor is used becase the mutex is constructed
298  // with new to avoid including windows header in the .h file.
301  vtkTypeInt64 operator++();
302  vtkTypeInt64 operator--();
303  vtkTypeInt64 operator+=(vtkTypeInt64 val);
304  vtkTypeInt64 load() const;
305  void store(vtkTypeInt64 val);
306 
307 #endif // defined(VTK_HAS_ATOMIC64) && !defined(VTK_WINDOWS_ATOMIC)
308 
309 protected:
310  // Explicitely aligning Value on Windows is probably not necessary
311  // since the compiler should automatically do it. Just being extra
312  // cautious since the InterlockedXXX() functions require alignment.
313  VTK__ALIGN64 vtkTypeInt64 Value;
314 
315 #if !defined(VTK_HAS_ATOMIC64)
316  vtkSimpleCriticalSection* AtomicInt64CritSec;
317 #endif
318 };
319 }
320 
321 template <typename T>
323 {
325 
326 public:
328 
330  {
331  this->Value = 0;
332  }
334 
336 
338  {
339  this->Value = val;
340  }
342 
344 
346  {
347  return this->Superclass::operator++();
348  }
350 
352 
353  T operator++(int)
354  {
355  return this->operator++() - 1;
356  }
358 
360 
362  {
363  return this->Superclass::operator--();
364  }
366 
368 
369  T operator--(int)
370  {
371  return this->operator--() + 1;
372  }
374 
376 
378  {
379  return this->operator+=(-val);
380  }
382 
384 
385  operator T() const
386  {
387  return this->load();
388  }
390 
392 
394  {
395  this->store(val);
396  return val;
397  }
398 };
400 
401 
402 #endif
403 // VTK-HeaderTest-Exclude: vtkAtomicInt.h
T operator=(T val)
Definition: vtkAtomicInt.h:393
T operator-=(T val)
Definition: vtkAtomicInt.h:377
#define VTKCOMMONCORE_EXPORT
vtkTypeInt64 operator+=(vtkTypeInt64 val)
Definition: vtkAtomicInt.h:247
#define VTK__ALIGN32
Definition: vtkAtomicInt.h:79
T operator++(int)
Definition: vtkAtomicInt.h:353
vtkTypeInt32 operator+=(vtkTypeInt32 val)
Definition: vtkAtomicInt.h:126
vtkAtomicInt(T val)
Definition: vtkAtomicInt.h:337
#define VTK__ALIGN64
Definition: vtkAtomicInt.h:202
T operator--(int)
Definition: vtkAtomicInt.h:369
Critical section locking class.
Provides support for atomic integers.
Definition: vtkAtomicInt.h:322
GLuint GLfloat * val
Definition: vtkgl.h:13789