ITK  4.9.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 
42 #if defined(__APPLE__)
43 # include <libkern/OSAtomic.h>
44 # define ITK_APPLE_ATOMICS_32
45 # if ITK_SIZEOF_VOID_P == 8 || defined(__i386__)
46 # define ITK_APPLE_ATOMICS_64
47 # endif
48 #elif defined(_WIN32) && defined(_MSC_VER)
49 # define ITK_WINDOWS_ATOMICS_32
50 # if ITK_SIZEOF_VOID_P == 8
51 # define ITK_WINDOWS_ATOMICS_64
52 # endif
53 #elif defined(ITK_HAVE_SYNC_BUILTINS)
54 # define ITK_GCC_ATOMICS_32
55 # define ITK_GCC_ATOMICS_64
56 #endif
57 
58 
59 namespace itk
60 {
61 
62 namespace Detail
63 {
64 
65 template <size_t VSize> class AtomicOps;
66 
67 #if defined ITK_HAVE_SYNC_BUILTINS
68 
69 template <size_t VSize> struct BaseType;
70 
71 template <size_t VSize> class AtomicOps
72 {
73 public:
74  typedef typename BaseType<VSize>::Type AtomicType;
75  typedef typename BaseType<VSize>::Type ValueType;
76 
77  static ValueType AddAndFetch(ValueType *ref, ValueType val)
78  {
79  return __sync_add_and_fetch(ref, val);
80  }
81 
82  static ValueType SubAndFetch(ValueType *ref, ValueType val)
83  {
84  return __sync_sub_and_fetch(ref, val);
85  }
86 
87  static ValueType PreIncrement(ValueType *ref)
88  {
89  return __sync_add_and_fetch(ref, 1);
90  }
91 
92  static ValueType PreDecrement(ValueType *ref)
93  {
94  return __sync_sub_and_fetch(ref, 1);
95  }
96 
97  static ValueType PostIncrement(ValueType *ref)
98  {
99  return __sync_fetch_and_add(ref, 1);
100  }
101 
102  static ValueType PostDecrement(ValueType *ref)
103  {
104  return __sync_fetch_and_sub(ref, 1);
105  }
106 
107  static ValueType Load(const ValueType *ref)
108  {
109  __sync_synchronize();
110  return *static_cast<const volatile ValueType *>(ref);
111  }
112 
113  static void Store(ValueType *ref, ValueType val)
114  {
115  *static_cast<volatile ValueType*>(ref) = val;
116  __sync_synchronize();
117  }
118 };
119 
120 #endif // defined ITK_HAVE_SYNC_BUILTINS
121 
122 #if defined(ITK_GCC_ATOMICS_64)
123 template<> struct BaseType<8>
124 {
125  itkAlignedTypedef( 8, int64_t, Type );
126 };
127 
128 #elif defined(ITK_APPLE_ATOMICS_64)
129 template <> class AtomicOps<8>
130 {
131 public:
132  itkAlignedTypedef( 8, int64_t, AtomicType );
133  typedef int64_t ValueType;
134 
135  static int64_t AddAndFetch(int64_t *ref, int64_t val)
136  {
137  return OSAtomicAdd64Barrier(val, ref);
138  }
139 
140  static int64_t SubAndFetch(int64_t *ref, int64_t val)
141  {
142  return OSAtomicAdd64Barrier(-val, ref);
143  }
144 
145  static int64_t PreIncrement(int64_t *ref)
146  {
147  return OSAtomicIncrement64Barrier(ref);
148  }
149 
150  static int64_t PreDecrement(int64_t *ref)
151  {
152  return OSAtomicDecrement64Barrier(ref);
153  }
154 
155  static int64_t PostIncrement(int64_t *ref)
156  {
157  int64_t val = OSAtomicIncrement64Barrier(ref);
158  return --val;
159  }
160 
161  static int64_t PostDecrement(int64_t *ref)
162  {
163  int64_t val = OSAtomicDecrement64Barrier(ref);
164  return ++val;
165  }
166 
167  static int64_t Load(const int64_t *ref)
168  {
169  OSMemoryBarrier();
170  return *static_cast<const volatile int64_t*>(ref);
171  }
172 
173  static void Store(int64_t *ref, int64_t val)
174  {
175  *static_cast<volatile int64_t*>(ref) = val;
176  OSMemoryBarrier();
177  }
178 };
179 
180 #else
181 
182 template <> class ITKCommon_EXPORT AtomicOps<8>
183 {
184 public:
185 #if defined(ITK_WINDOWS_ATOMICS_64)
186  itkAlignedTypedef( 8, int64_t, AtomicType );
187 
188 #else
189  struct ITKCommon_EXPORT AtomicType
190  {
193 
194  AtomicType(int64_t init);
195  ~AtomicType();
196  };
197 #endif
199 
200  static int64_t AddAndFetch(AtomicType *ref, int64_t val);
201  static int64_t SubAndFetch(AtomicType *ref, int64_t val);
202  static int64_t PreIncrement(AtomicType *ref);
203  static int64_t PreDecrement(AtomicType *ref);
204  static int64_t PostIncrement(AtomicType *ref);
205  static int64_t PostDecrement(AtomicType *ref);
206  static int64_t Load(const AtomicType *ref);
207  static void Store(AtomicType *ref, int64_t val);
208 };
209 
210 #endif
211 
212 #if defined(ITK_GCC_ATOMICS_32)
213 template<> struct BaseType<4>
214 {
215  itkAlignedTypedef( 4, int32_t, Type );
216 };
217 
218 #elif defined(ITK_APPLE_ATOMICS_32)
219 template <> class AtomicOps<4>
220 {
221 public:
222  itkAlignedTypedef( 4, int32_t, AtomicType );
223  typedef int32_t ValueType;
224 
225  static int32_t AddAndFetch(int32_t *ref, int32_t val)
226  {
227  return OSAtomicAdd32Barrier(val, ref);
228  }
229 
230  static int32_t SubAndFetch(int32_t *ref, int32_t val)
231  {
232  return OSAtomicAdd32Barrier(-val, ref);
233  }
234 
235  static int32_t PreIncrement(int32_t *ref)
236  {
237  return OSAtomicIncrement32Barrier(ref);
238  }
239 
240  static int32_t PreDecrement(int32_t *ref)
241  {
242  return OSAtomicDecrement32Barrier(ref);
243  }
244 
245  static int32_t PostIncrement(int32_t *ref)
246  {
247  int32_t val = OSAtomicIncrement32Barrier(ref);
248  return --val;
249  }
250 
251  static int32_t PostDecrement(int32_t *ref)
252  {
253  int32_t val = OSAtomicDecrement32Barrier(ref);
254  return ++val;
255  }
256 
257  static int32_t Load(const int32_t *ref)
258  {
259  OSMemoryBarrier();
260  return *static_cast<const volatile int32_t*>(ref);
261  }
262 
263  static void Store(int32_t *ref, int32_t val)
264  {
265  *static_cast<volatile int32_t*>(ref) = val;
266  OSMemoryBarrier();
267  }
268 };
269 
270 #else
271 
272 template <> class ITKCommon_EXPORT AtomicOps<4>
273 {
274 public:
275 #if defined(ITK_WINDOWS_ATOMICS_32)
276  itkAlignedTypedef( 4, int32_t, AtomicType );
277 #else
278  struct ITKCommon_EXPORT AtomicType
279  {
282 
283  AtomicType(int32_t init);
284  ~AtomicType();
285  };
286 #endif
288 
289  static int32_t AddAndFetch(AtomicType *ref, int32_t val);
290  static int32_t SubAndFetch(AtomicType *ref, int32_t val);
291  static int32_t PreIncrement(AtomicType *ref);
292  static int32_t PreDecrement(AtomicType *ref);
293  static int32_t PostIncrement(AtomicType *ref);
294  static int32_t PostDecrement(AtomicType *ref);
295  static int32_t Load(const AtomicType *ref);
296  static void Store(AtomicType *ref, int32_t val);
297 };
298 
299 #endif
300 
301 template <typename T>
303 {
305  struct Constraints {
310  void constraints()
311  {
312  IntegralT a = TrueT();
313  IntegralT b = TrueT();
314  IntegralT c = TrueT();
315 
319  }
320  };
321 
322 
324 };
325 
326 } // end namespace Detail
327 } // end namespace itk
328 
329 #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