ITK  4.13.0
Insight Segmentation and Registration Toolkit
itkAtomicIntDetail.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 /*=========================================================================
19  *
20  * Program: Visualization Toolkit
21  * Module: vtkAtomicInt.h
22  *
23  * Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
24  * All rights reserved.
25  * See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
26  *
27  * This software is distributed WITHOUT ANY WARRANTY; without even
28  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
29  * PURPOSE. See the above copyright notice for more information.
30  *
31  *=========================================================================*/
32 
33 #ifndef itkAtomicIntDetail_h
34 #define itkAtomicIntDetail_h
35 
36 #include "itkMacro.h"
37 #include "itkIntTypes.h"
38 #include "itkSimpleFastMutexLock.h"
39 #include "itkConceptChecking.h"
40 
41 #if ITK_COMPILER_CXX_ATOMIC
42 # include <atomic>
43 #elif defined(ITK_HAVE_SYNC_BUILTINS)
44 # define ITK_GCC_ATOMICS_32
45 # define ITK_GCC_ATOMICS_64
46 #elif defined(__APPLE__)
47 # include <libkern/OSAtomic.h>
48 # define ITK_APPLE_ATOMICS_32
49 # if ITK_SIZEOF_VOID_P == 8 || defined(__i386__)
50 # define ITK_APPLE_ATOMICS_64
51 # endif
52 #elif defined(_WIN32) && defined(_MSC_VER)
53 # define ITK_WINDOWS_ATOMICS_32
54 # if ITK_SIZEOF_VOID_P == 8
55 # define ITK_WINDOWS_ATOMICS_64
56 # endif
57 #endif
58 
59 namespace itk
60 {
61 
62 namespace Detail
63 {
64 
65 template <size_t VSize> class AtomicOps;
66 
67 
68 #if ITK_COMPILER_CXX_ATOMIC
69 
70 template <size_t VSize> struct BaseType;
71 
72 template <size_t VSize> class AtomicOps
73 {
74 public:
75  typedef typename BaseType<VSize>::Type AtomicType;
76  typedef typename BaseType<VSize>::Type ValueType;
77 };
78 
79 #elif defined ITK_HAVE_SYNC_BUILTINS
80 
81 template <size_t VSize> struct BaseType;
82 
83 template <size_t VSize> class AtomicOps
84 {
85 public:
86  typedef typename BaseType<VSize>::Type AtomicType;
87  typedef typename BaseType<VSize>::Type ValueType;
88 
89  static ValueType AddAndFetch(ValueType *ref, ValueType val)
90  {
91  return __sync_add_and_fetch(ref, val);
92  }
93 
94  static ValueType SubAndFetch(ValueType *ref, ValueType val)
95  {
96  return __sync_sub_and_fetch(ref, val);
97  }
98 
99  static ValueType PreIncrement(ValueType *ref)
100  {
101  return __sync_add_and_fetch(ref, 1);
102  }
103 
104  static ValueType PreDecrement(ValueType *ref)
105  {
106  return __sync_sub_and_fetch(ref, 1);
107  }
108 
109  static ValueType PostIncrement(ValueType *ref)
110  {
111  return __sync_fetch_and_add(ref, 1);
112  }
113 
114  static ValueType PostDecrement(ValueType *ref)
115  {
116  return __sync_fetch_and_sub(ref, 1);
117  }
118 
119  static ValueType Load(const ValueType *ref)
120  {
121  __sync_synchronize();
122  return *static_cast<const volatile ValueType *>(ref);
123  }
124 
125  static void Store(ValueType *ref, ValueType val)
126  {
127  *static_cast<volatile ValueType*>(ref) = val;
128  __sync_synchronize();
129  }
130 };
131 
132 #endif // defined ITK_HAVE_SYNC_BUILTINS
133 
134 #if defined(ITK_GCC_ATOMICS_64) || ITK_COMPILER_CXX_ATOMIC
135 template<> struct BaseType<8>
136 {
137  itkAlignedTypedef( 8, int64_t, Type );
138 };
139 
140 #elif defined(ITK_APPLE_ATOMICS_64)
141 template <> class AtomicOps<8>
142 {
143 public:
144  itkAlignedTypedef( 8, int64_t, AtomicType );
145  typedef int64_t ValueType;
146 
147  static int64_t AddAndFetch(int64_t *ref, int64_t val)
148  {
149  return OSAtomicAdd64Barrier(val, ref);
150  }
151 
152  static int64_t SubAndFetch(int64_t *ref, int64_t val)
153  {
154  return OSAtomicAdd64Barrier(-val, ref);
155  }
156 
157  static int64_t PreIncrement(int64_t *ref)
158  {
159  return OSAtomicIncrement64Barrier(ref);
160  }
161 
162  static int64_t PreDecrement(int64_t *ref)
163  {
164  return OSAtomicDecrement64Barrier(ref);
165  }
166 
167  static int64_t PostIncrement(int64_t *ref)
168  {
169  int64_t val = OSAtomicIncrement64Barrier(ref);
170  return --val;
171  }
172 
173  static int64_t PostDecrement(int64_t *ref)
174  {
175  int64_t val = OSAtomicDecrement64Barrier(ref);
176  return ++val;
177  }
178 
179  static int64_t Load(const int64_t *ref)
180  {
181  OSMemoryBarrier();
182  return *static_cast<const volatile int64_t*>(ref);
183  }
184 
185  static void Store(int64_t *ref, int64_t val)
186  {
187  *static_cast<volatile int64_t*>(ref) = val;
188  OSMemoryBarrier();
189  }
190 };
191 
192 #else
193 
194 template <> class ITKCommon_EXPORT AtomicOps<8>
195 {
196 public:
197 #if defined(ITK_WINDOWS_ATOMICS_64)
198  itkAlignedTypedef( 8, int64_t, AtomicType );
199 
200 #else
201  struct ITKCommon_EXPORT AtomicType
202  {
205 
206  AtomicType(int64_t init);
207  ~AtomicType();
208  };
209 #endif
211 
212  static int64_t AddAndFetch(AtomicType *ref, int64_t val);
213  static int64_t SubAndFetch(AtomicType *ref, int64_t val);
214  static int64_t PreIncrement(AtomicType *ref);
215  static int64_t PreDecrement(AtomicType *ref);
216  static int64_t PostIncrement(AtomicType *ref);
217  static int64_t PostDecrement(AtomicType *ref);
218  static int64_t Load(const AtomicType *ref);
219  static void Store(AtomicType *ref, int64_t val);
220 };
221 
222 #endif
223 
224 #if defined(ITK_GCC_ATOMICS_32) || ITK_COMPILER_CXX_ATOMIC
225 template<> struct BaseType<4>
226 {
227  itkAlignedTypedef( 4, int32_t, Type );
228 };
229 
230 #elif defined(ITK_APPLE_ATOMICS_32)
231 template <> class AtomicOps<4>
232 {
233 public:
234  itkAlignedTypedef( 4, int32_t, AtomicType );
235  typedef int32_t ValueType;
236 
237  static int32_t AddAndFetch(int32_t *ref, int32_t val)
238  {
239  return OSAtomicAdd32Barrier(val, ref);
240  }
241 
242  static int32_t SubAndFetch(int32_t *ref, int32_t val)
243  {
244  return OSAtomicAdd32Barrier(-val, ref);
245  }
246 
247  static int32_t PreIncrement(int32_t *ref)
248  {
249  return OSAtomicIncrement32Barrier(ref);
250  }
251 
252  static int32_t PreDecrement(int32_t *ref)
253  {
254  return OSAtomicDecrement32Barrier(ref);
255  }
256 
257  static int32_t PostIncrement(int32_t *ref)
258  {
259  int32_t val = OSAtomicIncrement32Barrier(ref);
260  return --val;
261  }
262 
263  static int32_t PostDecrement(int32_t *ref)
264  {
265  int32_t val = OSAtomicDecrement32Barrier(ref);
266  return ++val;
267  }
268 
269  static int32_t Load(const int32_t *ref)
270  {
271  OSMemoryBarrier();
272  return *static_cast<const volatile int32_t*>(ref);
273  }
274 
275  static void Store(int32_t *ref, int32_t val)
276  {
277  *static_cast<volatile int32_t*>(ref) = val;
278  OSMemoryBarrier();
279  }
280 };
281 
282 #else
283 
284 template <> class ITKCommon_EXPORT AtomicOps<4>
285 {
286 public:
287 #if defined(ITK_WINDOWS_ATOMICS_32)
288  itkAlignedTypedef( 4, int32_t, AtomicType );
289 #else
290  struct ITKCommon_EXPORT AtomicType
291  {
294 
295  AtomicType(int32_t init);
296  ~AtomicType();
297  };
298 #endif
300 
301  static int32_t AddAndFetch(AtomicType *ref, int32_t val);
302  static int32_t SubAndFetch(AtomicType *ref, int32_t val);
303  static int32_t PreIncrement(AtomicType *ref);
304  static int32_t PreDecrement(AtomicType *ref);
305  static int32_t PostIncrement(AtomicType *ref);
306  static int32_t PostDecrement(AtomicType *ref);
307  static int32_t Load(const AtomicType *ref);
308  static void Store(AtomicType *ref, int32_t val);
309 };
310 
311 #endif
312 
313 template <typename T>
315 {
317  struct Constraints {
322  void constraints()
323  {
324  IntegralT a = TrueT();
325  IntegralT b = TrueT();
326  IntegralT c = TrueT();
327 
331  }
332  };
333 
334 
336 };
337 
338 } // end namespace Detail
339 } // end namespace itk
340 
341 #endif
Critical section locking class that can be allocated on the stack.
KWIML_INT_int64_t int64_t
Definition: itkIntTypes.h:88
Concept::Detail::UniqueType_bool< sizeof(T)==4||sizeof(T)==8 > SizeT
Concept::Detail::UniqueType_bool< NumericTraits< T >::is_specialized > SpecializedT
Concept::Detail::UniqueType_bool< true > TrueT
KWIML_INT_int32_t int32_t
Definition: itkIntTypes.h:86
Concept::Detail::UniqueType_bool< NumericTraits< T >::is_integer > IntegralT