ITK  4.8.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 // Assume 64-bit atomic operations are not available on 32 bit platforms
43 #if 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 
60 namespace itk
61 {
62 
63 namespace Detail
64 {
65 
66 template <size_t VSize> class AtomicOps;
67 
68 #if defined ITK_HAVE_SYNC_BUILTINS
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  static ValueType AddAndFetch(ValueType *ref, ValueType val)
79  {
80  return __sync_add_and_fetch(ref, val);
81  }
82 
83  static ValueType SubAndFetch(ValueType *ref, ValueType val)
84  {
85  return __sync_sub_and_fetch(ref, val);
86  }
87 
88  static ValueType PreIncrement(ValueType *ref)
89  {
90  return __sync_add_and_fetch(ref, 1);
91  }
92 
93  static ValueType PreDecrement(ValueType *ref)
94  {
95  return __sync_sub_and_fetch(ref, 1);
96  }
97 
98  static ValueType PostIncrement(ValueType *ref)
99  {
100  return __sync_fetch_and_add(ref, 1);
101  }
102 
103  static ValueType PostDecrement(ValueType *ref)
104  {
105  return __sync_fetch_and_sub(ref, 1);
106  }
107 
108  static ValueType Load(const ValueType *ref)
109  {
110  __sync_synchronize();
111  return *static_cast<const volatile ValueType *>(ref);
112  }
113 
114  static void Store(ValueType *ref, ValueType val)
115  {
116  *static_cast<volatile ValueType*>(ref) = val;
117  __sync_synchronize();
118  }
119 };
120 
121 #endif // defined ITK_HAVE_SYNC_BUILTINS
122 
123 #if defined(ITK_GCC_ATOMICS_64)
124 template<> struct BaseType<8>
125 {
126  itkAlignedTypedef( 8, int64_t, Type );
127 };
128 
129 #elif defined(ITK_APPLE_ATOMICS_64)
130 template <> class AtomicOps<8>
131 {
132 public:
133  itkAlignedTypedef( 8, int64_t, AtomicType );
134  typedef int64_t ValueType;
135 
136  static int64_t AddAndFetch(int64_t *ref, int64_t val)
137  {
138  return OSAtomicAdd64Barrier(val, ref);
139  }
140 
141  static int64_t SubAndFetch(int64_t *ref, int64_t val)
142  {
143  return OSAtomicAdd64Barrier(-val, ref);
144  }
145 
146  static int64_t PreIncrement(int64_t *ref)
147  {
148  return OSAtomicIncrement64Barrier(ref);
149  }
150 
151  static int64_t PreDecrement(int64_t *ref)
152  {
153  return OSAtomicDecrement64Barrier(ref);
154  }
155 
156  static int64_t PostIncrement(int64_t *ref)
157  {
158  int64_t val = OSAtomicIncrement64Barrier(ref);
159  return --val;
160  }
161 
162  static int64_t PostDecrement(int64_t *ref)
163  {
164  int64_t val = OSAtomicDecrement64Barrier(ref);
165  return ++val;
166  }
167 
168  static int64_t Load(const int64_t *ref);
169  {
170  OSMemoryBarrier();
171  return *static_cast<const volatile int64_t*>(ref);
172  }
173 
174  static void Store(int64_t *ref, int64_t val);
175  {
176  *static_cast<volatile int64_t*>(ref) = val;
177  OSMemoryBarrier();
178  }
179 };
180 
181 #else
182 
183 template <> class ITKCommon_EXPORT AtomicOps<8>
184 {
185 public:
186 #if defined(ITK_WINDOWS_ATOMICS_64)
187  itkAlignedTypedef( 8, int64_t, AtomicType );
188 
189 #else
190  struct ITKCommon_EXPORT AtomicType
191  {
194 
195  AtomicType(int64_t init);
196  ~AtomicType();
197  };
198 #endif
200 
201  static int64_t AddAndFetch(AtomicType *ref, int64_t val);
202  static int64_t SubAndFetch(AtomicType *ref, int64_t val);
203  static int64_t PreIncrement(AtomicType *ref);
204  static int64_t PreDecrement(AtomicType *ref);
205  static int64_t PostIncrement(AtomicType *ref);
206  static int64_t PostDecrement(AtomicType *ref);
207  static int64_t Load(const AtomicType *ref);
208  static void Store(AtomicType *ref, int64_t val);
209 };
210 
211 #endif
212 
213 #if defined(ITK_GCC_ATOMICS_32)
214 template<> struct BaseType<4>
215 {
216  itkAlignedTypedef( 4, int32_t, Type );
217 };
218 
219 #elif defined(ITK_APPLE_ATOMICS_32)
220 template <> class AtomicOps<4>
221 {
222 public:
223  itkAlignedTypedef( 4, int32_t, AtomicType );
224  typedef int32_t ValueType;
225 
226  static int32_t AddAndFetch(int32_t *ref, int32_t val)
227  {
228  return OSAtomicAdd32Barrier(val, ref);
229  }
230 
231  static int32_t SubAndFetch(int32_t *ref, int32_t val)
232  {
233  return OSAtomicAdd32Barrier(-val, ref);
234  }
235 
236  static int32_t PreIncrement(int32_t *ref)
237  {
238  return OSAtomicIncrement32Barrier(ref);
239  }
240 
241  static int32_t PreDecrement(int32_t *ref)
242  {
243  return OSAtomicDecrement32Barrier(ref);
244  }
245 
246  static int32_t PostIncrement(int32_t *ref)
247  {
248  int32_t val = OSAtomicIncrement32Barrier(ref);
249  return --val;
250  }
251 
252  static int32_t PostDecrement(int32_t *ref)
253  {
254  int32_t val = OSAtomicDecrement32Barrier(ref);
255  return ++val;
256  }
257 
258  static int32_t Load(const int32_t *ref);
259  {
260  OSMemoryBarrier();
261  return *static_cast<const volatile int32_t*>(ref);
262  }
263 
264  static void Store(int32_t *ref, int32_t val);
265  {
266  *static_cast<volatile int32_t*>(ref) = val;
267  OSMemoryBarrier();
268  }
269 };
270 
271 #else
272 
273 template <> class ITKCommon_EXPORT AtomicOps<4>
274 {
275 public:
276 #if defined(ITK_WINDOWS_ATOMICS_32)
277  itkAlignedTypedef( 4, int32_t, AtomicType );
278 #else
279  struct ITKCommon_EXPORT AtomicType
280  {
283 
284  AtomicType(int32_t init);
285  ~AtomicType();
286  };
287 #endif
289 
290  static int32_t AddAndFetch(AtomicType *ref, int32_t val);
291  static int32_t SubAndFetch(AtomicType *ref, int32_t val);
292  static int32_t PreIncrement(AtomicType *ref);
293  static int32_t PreDecrement(AtomicType *ref);
294  static int32_t PostIncrement(AtomicType *ref);
295  static int32_t PostDecrement(AtomicType *ref);
296  static int32_t Load(const AtomicType *ref);
297  static void Store(AtomicType *ref, int32_t val);
298 };
299 
300 #endif
301 
302 template <typename T>
304 {
306  struct Constraints {
311  void constraints()
312  {
313  IntegralT a = TrueT();
314  IntegralT b = TrueT();
315  IntegralT c = TrueT();
316 
320  }
321  };
322 
323 
325 };
326 
327 } // end namespace Detail
328 } // end namespace itk
329 
330 #endif
Critical section locking class that can be allocated on the stack.
typedef::itksysFundamentalType_Int64 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
typedef::itksysFundamentalType_Int32 int32_t
Definition: itkIntTypes.h:86
Concept::Detail::UniqueType_bool< true > TrueT
Concept::Detail::UniqueType_bool< NumericTraits< T >::is_integer > IntegralT