OSG  3.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Atomic.h
Go to the documentation of this file.
1 /* -*-c++-*- OpenThreads library, Copyright (C) 2008 The Open Thread Group
2  *
3  * This library is open source and may be redistributed and/or modified under
4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5  * (at your option) any later version. The full license is in LICENSE file
6  * included with this distribution, and on the openscenegraph.org website.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * OpenSceneGraph Public License for more details.
12 */
13 
14 #ifndef _OPENTHREADS_ATOMIC_
15 #define _OPENTHREADS_ATOMIC_
16 
17 #include <OpenThreads/Config>
18 #include <OpenThreads/Exports>
19 
20 #if defined(_OPENTHREADS_ATOMIC_USE_BSD_ATOMIC)
21 # include <libkern/OSAtomic.h>
22 # define _OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES
23 #elif defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS) && defined(__i386__)
24 # define _OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES
25 #elif defined(_OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED)
26 # define _OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES
27 #elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
28 # include <atomic.h>
29 # include "Mutex"
30 # include "ScopedLock"
31 #elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
32 # include "Mutex"
33 # include "ScopedLock"
34 #endif
35 
36 #if defined(_OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES)
37 #define _OPENTHREADS_ATOMIC_INLINE
38 #else
39 #define _OPENTHREADS_ATOMIC_INLINE inline
40 #endif
41 
42 namespace OpenThreads {
43 
49  public:
50  Atomic(unsigned value = 0) : _value(value)
51  { }
52  _OPENTHREADS_ATOMIC_INLINE unsigned operator++();
53  _OPENTHREADS_ATOMIC_INLINE unsigned operator--();
54  _OPENTHREADS_ATOMIC_INLINE unsigned AND(unsigned value);
55  _OPENTHREADS_ATOMIC_INLINE unsigned OR(unsigned value);
56  _OPENTHREADS_ATOMIC_INLINE unsigned XOR(unsigned value);
57  _OPENTHREADS_ATOMIC_INLINE unsigned exchange(unsigned value = 0);
58  _OPENTHREADS_ATOMIC_INLINE operator unsigned() const;
59  private:
60 
61  Atomic(const Atomic&);
62  Atomic& operator=(const Atomic&);
63 
64 #if defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
65  mutable Mutex _mutex;
66 #endif
67 #if defined(_OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED)
68  volatile long _value;
69 #elif defined(_OPENTHREADS_ATOMIC_USE_BSD_ATOMIC)
70  volatile int32_t _value;
71 #elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
72  volatile uint_t _value;
73  mutable Mutex _mutex; // needed for xor
74 #else
75  volatile unsigned _value;
76 #endif
77 };
78 
84 public:
85  AtomicPtr(void* ptr = 0) : _ptr(ptr)
86  { }
88  { _ptr = 0; }
89 
90  // assigns a new pointer
91  _OPENTHREADS_ATOMIC_INLINE bool assign(void* ptrNew, const void* const ptrOld);
92  _OPENTHREADS_ATOMIC_INLINE void* get() const;
93 
94 private:
95  AtomicPtr(const AtomicPtr&);
96  AtomicPtr& operator=(const AtomicPtr&);
97 
98 #if defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
99  mutable Mutex _mutex;
100 #endif
101  void* volatile _ptr;
102 };
103 
104 #if !defined(_OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES)
105 
108 {
109 #if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
110  return __sync_add_and_fetch(&_value, 1);
111 #elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
112  return __add_and_fetch(&_value, 1);
113 #elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
114  return atomic_inc_uint_nv(&_value);
115 #elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
116  ScopedLock<Mutex> lock(_mutex);
117  return ++_value;
118 #else
119  return ++_value;
120 #endif
121 }
122 
125 {
126 #if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
127  return __sync_sub_and_fetch(&_value, 1);
128 #elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
129  return __sub_and_fetch(&_value, 1);
130 #elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
131  return atomic_dec_uint_nv(&_value);
132 #elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
133  ScopedLock<Mutex> lock(_mutex);
134  return --_value;
135 #else
136  return --_value;
137 #endif
138 }
139 
141 Atomic::AND(unsigned value)
142 {
143 #if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
144  return __sync_fetch_and_and(&_value, value);
145 #elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
146  return __and_and_fetch(&_value, value);
147 #elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
148  return atomic_and_uint_nv(&_value, value);
149 #elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
150  ScopedLock<Mutex> lock(_mutex);
151  _value &= value;
152  return _value;
153 #else
154  _value &= value;
155  return _value;
156 #endif
157 }
158 
160 Atomic::OR(unsigned value)
161 {
162 #if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
163  return __sync_fetch_and_or(&_value, value);
164 #elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
165  return __or_and_fetch(&_value, value);
166 #elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
167  return atomic_or_uint_nv(&_value, value);
168 #elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
169  ScopedLock<Mutex> lock(_mutex);
170  _value |= value;
171  return _value;
172 #else
173  _value |= value;
174  return _value;
175 #endif
176 }
177 
179 Atomic::XOR(unsigned value)
180 {
181 #if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
182  return __sync_fetch_and_xor(&_value, value);
183 #elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
184  return __xor_and_fetch(&_value, value);
185 #elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
186  ScopedLock<Mutex> lock(_mutex);
187  _value ^= value;
188  return _value;
189 #elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
190  ScopedLock<Mutex> lock(_mutex);
191  _value ^= value;
192  return _value;
193 #else
194  _value ^= value;
195  return _value;
196 #endif
197 }
198 
200 Atomic::exchange(unsigned value)
201 {
202 #if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
203  return __sync_lock_test_and_set(&_value, value);
204 #elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
205  return __compare_and_swap(&_value, _value, value);
206 #elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
207  return atomic_cas_uint(&_value, _value, value);
208 #elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
209  ScopedLock<Mutex> lock(_mutex);
210  unsigned oldval = _value;
211  _value = value;
212  return oldval;
213 #else
214  unsigned oldval = _value;
215  _value = value;
216  return oldval;
217 #endif
218 }
219 
221 Atomic::operator unsigned() const
222 {
223 #if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
224  __sync_synchronize();
225  return _value;
226 #elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
227  __synchronize();
228  return _value;
229 #elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
230  membar_consumer(); // Hmm, do we need???
231  return _value;
232 #elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
233  ScopedLock<Mutex> lock(_mutex);
234  return _value;
235 #else
236  return _value;
237 #endif
238 }
239 
241 AtomicPtr::assign(void* ptrNew, const void* const ptrOld)
242 {
243 #if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
244  return __sync_bool_compare_and_swap(&_ptr, (void *)ptrOld, ptrNew);
245 #elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
246  return __compare_and_swap((unsigned long*)&_ptr, (unsigned long)ptrOld, (unsigned long)ptrNew);
247 #elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
248  return ptrOld == atomic_cas_ptr(&_ptr, const_cast<void*>(ptrOld), ptrNew);
249 #elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
250  ScopedLock<Mutex> lock(_mutex);
251  if (_ptr != ptrOld)
252  return false;
253  _ptr = ptrNew;
254  return true;
255 #else
256  if (_ptr != ptrOld)
257  return false;
258  _ptr = ptrNew;
259  return true;
260 #endif
261 }
262 
265 {
266 #if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
267  __sync_synchronize();
268  return _ptr;
269 #elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
270  __synchronize();
271  return _ptr;
272 #elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
273  membar_consumer(); // Hmm, do we need???
274  return _ptr;
275 #elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
276  ScopedLock<Mutex> lock(_mutex);
277  return _ptr;
278 #else
279  return _ptr;
280 #endif
281 }
282 
283 #endif // !defined(_OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES)
284 
285 }
286 
287 #endif // _OPENTHREADS_ATOMIC_
This class provides an object-oriented thread mutex interface.
Definition: Mutex.h:31
_OPENTHREADS_ATOMIC_INLINE bool assign(void *ptrNew, const void *const ptrOld)
Definition: Atomic.h:241
_OPENTHREADS_ATOMIC_INLINE unsigned operator++()
Definition: Atomic.h:107
#define _OPENTHREADS_ATOMIC_INLINE
Definition: Atomic.h:39
Atomic(unsigned value=0)
Definition: Atomic.h:50
This class provides an atomic increment and decrement operation.
Definition: Atomic.h:48
_OPENTHREADS_ATOMIC_INLINE unsigned operator--()
Definition: Atomic.h:124
_OPENTHREADS_ATOMIC_INLINE void * get() const
Definition: Atomic.h:264
AtomicPtr(void *ptr=0)
Definition: Atomic.h:85
This class provides an atomic pointer assignment using cas operations.
Definition: Atomic.h:83
#define OPENTHREAD_EXPORT_DIRECTIVE
Definition: Exports.h:20
_OPENTHREADS_ATOMIC_INLINE unsigned OR(unsigned value)
Definition: Atomic.h:160
_OPENTHREADS_ATOMIC_INLINE unsigned exchange(unsigned value=0)
Definition: Atomic.h:200
_OPENTHREADS_ATOMIC_INLINE unsigned XOR(unsigned value)
Definition: Atomic.h:179
_OPENTHREADS_ATOMIC_INLINE unsigned AND(unsigned value)
Definition: Atomic.h:141