VTK
/Users/kitware/Dashboards/MyTests/VTK_BLD_Release_docs/Utilities/Doxygen/dox/Volumes/BIGMAC1/Dashboards/MyTests/VTK_BLD_Release_docs/Common/Core/vtkAtomicInt.h
Go to the documentation of this file.
00001  /*=========================================================================
00002 
00003   Program:   Visualization Toolkit
00004   Module:    vtkAtomicInt.h
00005 
00006   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
00007   All rights reserved.
00008   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
00009 
00010      This software is distributed WITHOUT ANY WARRANTY; without even
00011      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00012      PURPOSE.  See the above copyright notice for more information.
00013 
00014 =========================================================================*/
00039 #ifndef vtkAtomicInt_h
00040 #define vtkAtomicInt_h
00041 
00042 #include "vtkCommonCoreModule.h" // For export macro
00043 #include "vtkSystemIncludes.h"
00044 #include "vtkConfigure.h"
00045 
00046 #if defined(__APPLE__)
00047 # include <libkern/OSAtomic.h>
00048 #endif
00049 
00050 #if (defined(_WIN32)  && !defined(__MINGW32__))
00051 # define VTK_WINDOWS_ATOMIC
00052 # if defined(_MSC_VER)
00053 #  pragma warning(disable:4324) // disable warning about the padding due to alignment
00054 # endif
00055 #endif
00056 
00057 #if defined(VTK_WINDOWS_ATOMIC) || defined(__APPLE__) || defined(VTK_HAVE_SYNC_BUILTINS)
00058 # define VTK_HAS_ATOMIC32
00059 #endif
00060 
00061 // Overall, we assume that 64 bit atomic operations are not available on 32
00062 // bit systems.
00063 #if VTK_SIZEOF_VOID_P == 8
00064 # if defined(VTK_WINDOWS_ATOMIC) || defined(__APPLE__) || defined(VTK_HAVE_SYNC_BUILTINS)
00065 #  define VTK_HAS_ATOMIC64
00066 # endif
00067 #endif
00068 
00069 #if !defined(VTK_HAS_ATOMIC64) || !defined(VTK_HAS_ATOMIC32)
00070 class vtkSimpleCriticalSection;
00071 #endif
00072 
00073 // Below are the actual implementations of 32 and 64 bit atomic operations.
00074 namespace detail
00075 {
00076 #if defined (VTK_WINDOWS_ATOMIC)
00077 # define VTK__ALIGN32 __declspec(align(32))
00078 #else
00079 # define VTK__ALIGN32
00080 #endif
00081 
00082 template <typename T> class vtkAtomicIntImpl;
00083 
00084 template <>
00085 #if defined(VTK_HAS_ATOMIC32) && !defined(VTK_WINDOWS_ATOMIC)
00086 class vtkAtomicIntImpl<vtkTypeInt32>
00087 #else
00088 class VTKCOMMONCORE_EXPORT vtkAtomicIntImpl<vtkTypeInt32>
00089 #endif
00090 {
00091 public:
00092 
00094 
00095 #if defined(VTK_HAS_ATOMIC32) && !defined(VTK_WINDOWS_ATOMIC)
00096   vtkTypeInt32 operator++()
00097     {
00098 # if defined(__APPLE__)
00099     return OSAtomicIncrement32Barrier(&this->Value);
00101 
00102 // GCC, CLANG, etc
00103 # elif defined(VTK_HAVE_SYNC_BUILTINS)
00104     return __sync_add_and_fetch(&this->Value, 1);
00105 
00106 # endif
00107     }
00108 
00110 
00111   vtkTypeInt32 operator--()
00112     {
00113 # if defined(__APPLE__)
00114     return OSAtomicDecrement32Barrier(&this->Value);
00116 
00117 // GCC, CLANG, etc
00118 # elif defined(VTK_HAVE_SYNC_BUILTINS)
00119     return __sync_sub_and_fetch(&this->Value, 1);
00120 
00121 # endif
00122     }
00123 
00125 
00126   vtkTypeInt32 operator+=(vtkTypeInt32 val)
00127     {
00128 # if defined(__APPLE__)
00129     return OSAtomicAdd32Barrier(val, &this->Value);
00131 
00132 // GCC, CLANG, etc
00133 # elif defined(VTK_HAVE_SYNC_BUILTINS)
00134     return __sync_add_and_fetch(&this->Value, val);
00135 
00136 # endif
00137     }
00138 
00140 
00141   vtkTypeInt32 load() const
00142     {
00143 # if defined(__APPLE__)
00144     vtkTypeInt32 retval = 0;
00145     OSAtomicCompareAndSwap32Barrier(retval, this->Value, &retval);
00146     return retval;
00148 
00149 // GCC, CLANG, etc
00150 # elif defined(VTK_HAVE_SYNC_BUILTINS)
00151     vtkTypeInt32 retval = 0;
00152     __sync_val_compare_and_swap(&retval, retval, this->Value);
00153     return retval;
00154 
00155 # endif
00156     }
00157 
00159 
00160   void store(vtkTypeInt32 val)
00161     {
00162 # if defined(__APPLE__)
00163     OSAtomicCompareAndSwap32Barrier(this->Value, val, &this->Value);
00165 
00166 // GCC, CLANG, etc
00167 # elif defined(VTK_HAVE_SYNC_BUILTINS)
00168   __sync_val_compare_and_swap(&this->Value, this->Value, val);
00169 
00170 #endif
00171     }
00172 
00173 #else // defined(VTK_HAS_ATOMIC32) && !defined(VTK_WINDOWS_ATOMIC)
00174 
00175   // These methods are for when using a mutex. Same as above.
00176   // A virtual descructor is used becase the mutex is constructed
00177   // with new to avoid including windows header in the .h file.
00178   vtkAtomicIntImpl<vtkTypeInt32>();
00179   virtual ~vtkAtomicIntImpl<vtkTypeInt32>();
00180   vtkTypeInt32 operator++();
00181   vtkTypeInt32 operator--();
00182   vtkTypeInt32 operator+=(vtkTypeInt32 val);
00183   vtkTypeInt32 load() const;
00184   void store(vtkTypeInt32 val);
00185 
00186 #endif // defined(VTK_HAS_ATOMIC32) && !defined(VTK_WINDOWS_ATOMIC)
00187 
00188 protected:
00189   // Explicitely aligning Value on Windows is probably not necessary
00190   // since the compiler should automatically do it. Just being extra
00191   // cautious since the InterlockedXXX() functions require alignment.
00192   VTK__ALIGN32 vtkTypeInt32 Value;
00193 
00194 #if !defined(VTK_HAS_ATOMIC32)
00195   vtkSimpleCriticalSection* AtomicInt32CritSec;
00196 #endif
00197 };
00198 
00199 #if defined (VTK_WINDOWS_ATOMIC)
00200 # define VTK__ALIGN64 __declspec(align(64))
00201 #else
00202 # define VTK__ALIGN64
00203 #endif
00204 
00205 template <>
00206 #if defined(VTK_HAS_ATOMIC64) && !defined(VTK_WINDOWS_ATOMIC)
00207 class vtkAtomicIntImpl<vtkTypeInt64>
00208 #else
00209 class VTKCOMMONCORE_EXPORT vtkAtomicIntImpl<vtkTypeInt64>
00210 #endif
00211 {
00212 public:
00213 
00215 
00216 #if defined(VTK_HAS_ATOMIC64) && !defined(VTK_WINDOWS_ATOMIC)
00217   vtkTypeInt64 operator++()
00218     {
00219 # if defined(__APPLE__)
00220     return OSAtomicIncrement64Barrier(&this->Value);
00222 
00223 // GCC, CLANG, etc
00224 # elif defined(VTK_HAVE_SYNC_BUILTINS)
00225     return __sync_add_and_fetch(&this->Value, 1);
00226 
00227 # endif
00228    }
00229 
00231 
00232   vtkTypeInt64 operator--()
00233     {
00234 # if defined(__APPLE__)
00235     return OSAtomicDecrement64Barrier(&this->Value);
00237 
00238 // GCC, CLANG, etc
00239 # elif defined(VTK_HAVE_SYNC_BUILTINS)
00240     return __sync_sub_and_fetch(&this->Value, 1);
00241 
00242 # endif
00243     }
00244 
00246 
00247   vtkTypeInt64 operator+=(vtkTypeInt64 val)
00248     {
00249 # if defined(__APPLE__)
00250     return OSAtomicAdd64Barrier(val, &this->Value);
00252 
00253 // GCC, CLANG, etc
00254 # elif defined(VTK_HAVE_SYNC_BUILTINS)
00255     return __sync_add_and_fetch(&this->Value, val);
00256 
00257 # endif
00258     }
00259 
00261 
00262   vtkTypeInt64 load() const
00263     {
00264 # if defined(__APPLE__)
00265   vtkTypeInt64 retval = 0;
00266   OSAtomicCompareAndSwap64Barrier(retval, this->Value, &retval);
00267   return retval;
00269 
00270 // GCC, CLANG, etc
00271 # elif defined(VTK_HAVE_SYNC_BUILTINS)
00272   vtkTypeInt64 retval = 0;
00273   __sync_val_compare_and_swap(&retval, retval, this->Value);
00274   return retval;
00275 
00276 # endif
00277     }
00278 
00280 
00281   void store(vtkTypeInt64 val)
00282     {
00283 # if defined(__APPLE__)
00284   OSAtomicCompareAndSwap64Barrier(this->Value, val, &this->Value);
00286 
00287 // GCC, CLANG, etc
00288 # elif defined(VTK_HAVE_SYNC_BUILTINS)
00289   __sync_val_compare_and_swap(&this->Value, this->Value, val);
00290 
00291 # endif
00292     }
00293 
00294 #else // defined(VTK_HAS_ATOMIC64) && !defined(VTK_WINDOWS_ATOMIC)
00295 
00296   // These methods are for when using a mutex. Same as above.
00297   // A virtual descructor is used becase the mutex is constructed
00298   // with new to avoid including windows header in the .h file.
00299   vtkAtomicIntImpl<vtkTypeInt64>();
00300   virtual ~vtkAtomicIntImpl<vtkTypeInt64>();
00301   vtkTypeInt64 operator++();
00302   vtkTypeInt64 operator--();
00303   vtkTypeInt64 operator+=(vtkTypeInt64 val);
00304   vtkTypeInt64 load() const;
00305   void store(vtkTypeInt64 val);
00306 
00307 #endif // defined(VTK_HAS_ATOMIC64) && !defined(VTK_WINDOWS_ATOMIC)
00308 
00309 protected:
00310  // Explicitely aligning Value on Windows is probably not necessary
00311   // since the compiler should automatically do it. Just being extra
00312   // cautious since the InterlockedXXX() functions require alignment.
00313   VTK__ALIGN64 vtkTypeInt64 Value;
00314 
00315 #if !defined(VTK_HAS_ATOMIC64)
00316   vtkSimpleCriticalSection* AtomicInt64CritSec;
00317 #endif
00318 };
00319 }
00320 
00321 template <typename T>
00322 class vtkAtomicInt: public detail::vtkAtomicIntImpl<T>
00323 {
00324   typedef detail::vtkAtomicIntImpl<T> Superclass;
00325 
00326 public:
00328 
00329   vtkAtomicInt()
00330     {
00331     this->Value = 0;
00332     }
00334 
00336 
00337   vtkAtomicInt(T val)
00338     {
00339     this->Value = val;
00340     }
00342 
00344 
00345   T operator++()
00346     {
00347     return this->Superclass::operator++();
00348     }
00350 
00352 
00353   T operator++(int)
00354     {
00355     return this->operator++() - 1;
00356     }
00358 
00360 
00361   T operator--()
00362     {
00363     return this->Superclass::operator--();
00364     }
00366 
00368 
00369   T operator--(int)
00370     {
00371     return this->operator--() + 1;
00372     }
00374 
00376 
00377   T operator-=(T val)
00378     {
00379     return this->operator+=(-val);
00380     }
00382 
00384 
00385   operator T() const
00386     {
00387     return this->load();
00388     }
00390 
00392 
00393   T operator=(T val)
00394     {
00395     this->store(val);
00396     return val;
00397     }
00398 };
00400 
00401 
00402 #endif
00403 // VTK-HeaderTest-Exclude: vtkAtomicInt.h