Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / Atomic_Op.h
blob0c50566697669427cc8e631f205dfa8334568d60
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file Atomic_Op.h
7 * @author Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
8 */
9 //=============================================================================
11 #ifndef ACE_ATOMIC_OP_H
12 #define ACE_ATOMIC_OP_H
13 #include /**/ "ace/pre.h"
15 #include /**/ "ace/config-all.h"
17 #if !defined (ACE_LACKS_PRAGMA_ONCE)
18 # pragma once
19 #endif /* ACE_LACKS_PRAGMA_ONCE */
21 #include "ace/Thread_Mutex.h"
23 // Include the templates here.
24 #include "ace/Atomic_Op_T.h"
26 // Determine whether builtin atomic op support is
27 // available on this platform.
28 #if defined (ACE_HAS_THREADS)
29 # if defined (WIN32)
30 # if defined (ACE_HAS_INTRINSIC_INTERLOCKED)
31 # define ACE_HAS_BUILTIN_ATOMIC_OP
32 # endif /* ACE_HAS_INTRINSIC_INTERLOCKED */
33 # if defined (ACE_HAS_INTERLOCKED_EXCHANGEADD)
34 # define ACE_HAS_BUILTIN_ATOMIC_OP
35 # else /* ACE_HAS_INTERLOCKED_EXCHANGEADD */
36 // Inline assembly emulation of InterlockedExchangeAdd
37 // is currently only implemented for MSVC (x86 only) and Borland.
38 # if (defined (_MSC_VER) && defined (_M_IX86)) || defined (__BORLANDC__)
39 # define ACE_HAS_BUILTIN_ATOMIC_OP
40 # endif /* _MSC_VER || __BORLANDC__ */
41 # endif /* ACE_HAS_INTERLOCKED_EXCHANGEADD */
42 # elif defined (ACE_HAS_INTEL_ASSEMBLY)
43 # define ACE_HAS_BUILTIN_ATOMIC_OP
44 # elif defined (ACE_HAS_VXATOMICLIB)
45 # define ACE_HAS_BUILTIN_ATOMIC_OP
46 # endif /* WIN32 */
47 #endif /* ACE_HAS_THREADS */
49 // If we have the GCC Atomic builtin support, use it
50 #if defined (ACE_HAS_GCC_ATOMIC_BUILTINS) && (ACE_HAS_GCC_ATOMIC_BUILTINS == 1)
51 # undef ACE_HAS_BUILTIN_ATOMIC_OP
52 #endif
54 // Include the templates here.
55 #include "ace/Atomic_Op_GCC_T.h"
57 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
59 #if defined (ACE_HAS_BUILTIN_ATOMIC_OP)
61 /**
62 * @brief Specialization of ACE_Atomic_Op for platforms that
63 * support atomic integer operations.
65 * Specialization of ACE_Atomic_Op for platforms that support atomic
66 * integer operations.
68 template<>
69 class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, long>
71 public:
72 /// Initialize @c value_ to 0.
73 ACE_Atomic_Op ();
75 /// Initialize @c value_ to c.
76 ACE_Atomic_Op (long c);
78 /// Manage copying...
79 ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, long> &c);
81 /// Atomically pre-increment @c value_.
82 long operator++ ();
84 /// Atomically post-increment @c value_.
85 long operator++ (int);
87 /// Atomically increment @c value_ by rhs.
88 long operator+= (long rhs);
90 /// Atomically pre-decrement @c value_.
91 long operator-- ();
93 /// Atomically post-decrement @c value_.
94 long operator-- (int);
96 /// Atomically decrement @c value_ by rhs.
97 long operator-= (long rhs);
99 /// Atomically compare @c value_ with rhs.
100 bool operator== (long rhs) const;
102 /// Atomically compare @c value_ with rhs.
103 bool operator!= (long rhs) const;
105 /// Atomically check if @c value_ greater than or equal to rhs.
106 bool operator>= (long rhs) const;
108 /// Atomically check if @c value_ greater than rhs.
109 bool operator> (long rhs) const;
111 /// Atomically check if @c value_ less than or equal to rhs.
112 bool operator<= (long rhs) const;
114 /// Atomically check if @c value_ less than rhs.
115 bool operator< (long rhs) const;
117 /// Atomically assign rhs to @c value_.
118 ACE_Atomic_Op<ACE_Thread_Mutex, long> &operator= (long rhs);
120 /// Atomically assign <rhs> to @c value_.
121 ACE_Atomic_Op<ACE_Thread_Mutex, long> &operator= (const ACE_Atomic_Op<ACE_Thread_Mutex, long> &rhs);
123 /// Exchange value with @a newval.
124 long exchange (long newval);
126 /// Explicitly return @c value_.
127 long value () const;
129 /// Dump the state of an object.
130 void dump () const;
132 /// Explicitly return @c value_ (by reference).
133 volatile long &value_i ();
135 // ACE_ALLOC_HOOK_DECLARE;
136 // Declare the dynamic allocation hooks.
138 /// Used during ACE object manager initialization to optimize the fast
139 /// atomic op implementation according to the number of CPUs.
140 static void init_functions ();
142 private:
143 /// This function cannot be supported by this template specialization.
144 /// If you need access to an underlying lock, use the ACE_Atomic_Op_Ex
145 /// template instead.
146 ACE_Thread_Mutex &mutex ();
148 private:
149 /// Current object decorated by the atomic op.
150 volatile long value_;
152 /// Pointers to selected atomic op implementations.
153 static long (*increment_fn_) (volatile long *);
154 static long (*decrement_fn_) (volatile long *);
155 static long (*exchange_fn_) (volatile long *, long);
156 static long (*exchange_add_fn_) (volatile long *, long);
160 * @brief Specialization of ACE_Atomic_Op for platforms that
161 * support atomic integer operations.
163 * Specialization of ACE_Atomic_Op for platforms that support atomic
164 * integer operations.
166 template<>
167 class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>
169 public:
170 /// Initialize @c value_ to 0.
171 ACE_Atomic_Op ();
173 /// Initialize @c value_ to c.
174 ACE_Atomic_Op (unsigned long c);
176 /// Manage copying...
177 ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &c);
179 /// Atomically pre-increment @c value_.
180 unsigned long operator++ ();
182 /// Atomically post-increment @c value_.
183 unsigned long operator++ (int);
185 /// Atomically increment @c value_ by rhs.
186 unsigned long operator+= (unsigned long rhs);
188 /// Atomically pre-decrement @c value_.
189 unsigned long operator-- ();
191 /// Atomically post-decrement @c value_.
192 unsigned long operator-- (int);
194 /// Atomically decrement @c value_ by rhs.
195 unsigned long operator-= (unsigned long rhs);
197 /// Atomically compare @c value_ with rhs.
198 bool operator== (unsigned long rhs) const;
200 /// Atomically compare @c value_ with rhs.
201 bool operator!= (unsigned long rhs) const;
203 /// Atomically check if @c value_ greater than or equal to rhs.
204 bool operator>= (unsigned long rhs) const;
206 /// Atomically check if @c value_ greater than rhs.
207 bool operator> (unsigned long rhs) const;
209 /// Atomically check if @c value_ less than or equal to rhs.
210 bool operator<= (unsigned long rhs) const;
212 /// Atomically check if @c value_ less than rhs.
213 bool operator< (unsigned long rhs) const;
215 /// Atomically assign rhs to @c value_.
216 ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &operator= (unsigned long rhs);
218 /// Atomically assign <rhs> to @c value_.
219 ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &operator= (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &rhs);
221 /// Exchange value with @a newval.
222 unsigned long exchange (unsigned long newval);
224 /// Explicitly return @c value_.
225 unsigned long value () const;
227 /// Dump the state of an object.
228 void dump () const;
230 /// Explicitly return @c value_ (by reference).
231 volatile unsigned long &value_i ();
233 // ACE_ALLOC_HOOK_DECLARE;
234 // Declare the dynamic allocation hooks.
236 /// Used during ACE object manager initialization to optimize the fast
237 /// atomic op implementation according to the number of CPUs.
238 static void init_functions ();
240 private:
241 /// This function cannot be supported by this template specialization.
242 /// If you need access to an underlying lock, use the ACE_Atomic_Op_Ex
243 /// template instead.
244 ACE_Thread_Mutex &mutex ();
246 private:
247 /// Current object decorated by the atomic op.
248 volatile unsigned long value_;
250 // Pointers to selected atomic op implementations.
251 static long (*increment_fn_) (volatile long *);
252 static long (*decrement_fn_) (volatile long *);
253 static long (*exchange_fn_) (volatile long *, long);
254 static long (*exchange_add_fn_) (volatile long *, long);
257 #endif /* !ACE_HAS_BUILTIN_ATOMIC_OP */
259 #if defined (ACE_HAS_GCC_ATOMIC_BUILTINS) && (ACE_HAS_GCC_ATOMIC_BUILTINS == 1)
261 template<>
262 class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, int>
263 : public ACE_Atomic_Op_GCC<int>
265 public:
266 ACE_Atomic_Op ();
267 ACE_Atomic_Op (int c);
268 ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, int> &c);
269 ACE_Atomic_Op<ACE_Thread_Mutex, int> &operator= (int rhs);
270 ACE_Atomic_Op<ACE_Thread_Mutex, int> &operator= (const ACE_Atomic_Op<ACE_Thread_Mutex, int> &rhs);
273 template<>
274 class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, unsigned int>
275 : public ACE_Atomic_Op_GCC<unsigned int>
277 public:
278 ACE_Atomic_Op ();
279 ACE_Atomic_Op (unsigned int c);
280 ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned> &c);
281 ACE_Atomic_Op<ACE_Thread_Mutex, unsigned int> &operator= (unsigned int rhs);
282 ACE_Atomic_Op<ACE_Thread_Mutex, unsigned int> &operator= (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned int> &rhs);
285 // If we have built in atomic op, use that, the assignment operator
286 // is faster for a long/unsinged long
287 template<>
288 class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, long>
289 : public ACE_Atomic_Op_GCC<long>
291 public:
292 ACE_Atomic_Op ();
293 ACE_Atomic_Op (long c);
294 ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, long> &c);
295 ACE_Atomic_Op<ACE_Thread_Mutex, long> &operator= (long rhs);
296 ACE_Atomic_Op<ACE_Thread_Mutex, long> &operator= (const ACE_Atomic_Op<ACE_Thread_Mutex, long> &rhs);
299 template<>
300 class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>
301 : public ACE_Atomic_Op_GCC<unsigned long>
303 public:
304 ACE_Atomic_Op ();
305 ACE_Atomic_Op (unsigned long c);
306 ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &c);
307 ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &operator= (unsigned long rhs);
308 ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &operator= (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &c);
311 // The long long intrinsics are not available on PPC
312 #if !defined (__powerpc__)
313 template<>
314 class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, long long>
315 : public ACE_Atomic_Op_GCC<long long>
317 public:
318 ACE_Atomic_Op ();
319 ACE_Atomic_Op (long long c);
320 ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, long long> &c);
321 ACE_Atomic_Op<ACE_Thread_Mutex, long long> &operator= (long long rhs);
322 ACE_Atomic_Op<ACE_Thread_Mutex, long long> &operator= (const ACE_Atomic_Op<ACE_Thread_Mutex, long long> &c);
325 template<>
326 class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long long>
327 : public ACE_Atomic_Op_GCC<unsigned long long>
329 public:
330 ACE_Atomic_Op ();
331 ACE_Atomic_Op (unsigned long long c);
332 ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long long> &c);
333 ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long long> &operator= (unsigned long long rhs);
334 ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long long> &operator= (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long long> &c);
336 #endif /* !__powerpc__ */
338 #if !defined (ACE_LACKS_GCC_ATOMIC_BUILTINS_2)
339 template<>
340 class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, short>
341 : public ACE_Atomic_Op_GCC<short>
343 public:
344 ACE_Atomic_Op ();
345 ACE_Atomic_Op (short c);
346 ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, short> &c);
347 ACE_Atomic_Op<ACE_Thread_Mutex, short> &operator= (short rhs);
348 ACE_Atomic_Op<ACE_Thread_Mutex, short> &operator= (const ACE_Atomic_Op<ACE_Thread_Mutex, short> &c);
351 template<>
352 class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, unsigned short>
353 : public ACE_Atomic_Op_GCC<unsigned short>
355 public:
356 ACE_Atomic_Op ();
357 ACE_Atomic_Op (unsigned short c);
358 ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned short> &c);
359 ACE_Atomic_Op<ACE_Thread_Mutex, unsigned short> &operator= (unsigned short rhs);
360 ACE_Atomic_Op<ACE_Thread_Mutex, unsigned short> &operator= (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned short> &c);
362 #endif
364 #if !defined (ACE_LACKS_GCC_ATOMIC_BUILTINS_1)
365 template<>
366 class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, bool>
367 : public ACE_Atomic_Op_GCC<bool>
369 public:
370 ACE_Atomic_Op ();
371 ACE_Atomic_Op (bool c);
372 ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, bool> &c);
373 ACE_Atomic_Op<ACE_Thread_Mutex, bool> &operator= (bool rhs);
374 ACE_Atomic_Op<ACE_Thread_Mutex, bool> &operator= (const ACE_Atomic_Op<ACE_Thread_Mutex, bool> &c);
376 #endif
378 #endif /* ACE_HAS_BUILTIN_ATOMIC_OP */
380 ACE_END_VERSIONED_NAMESPACE_DECL
382 #if defined (__ACE_INLINE__)
383 #include "ace/Atomic_Op.inl"
384 #endif /* __ACE_INLINE__ */
386 #include /**/ "ace/post.h"
387 #endif /*ACE_ATOMIC_OP_H*/