OpendTect  6.3
atomic.h
Go to the documentation of this file.
1 #pragma once
2 
3 /*
4 ________________________________________________________________________
5 
6  (C) dGB Beheer B.V.; (LICENSE) http://opendtect.org/OpendTect_license.txt
7  Author: K. Tingdahl
8  Date: 9-3-1999
9 ________________________________________________________________________
10 
11 */
12 
13 #include "basicmod.h"
14 #include "commondefs.h"
15 #include "plftypes.h"
16 #include "odversion.h"
17 
18 #ifdef __win__
19 # include "windows.h"
20 #endif
21 
22 # include <atomic>
23 
24 namespace Threads {
25 
26 template <class T>
27 mClass(Basic) Atomic : public std::atomic<T>
28 {
29 public:
30  Atomic(T val=0);
31  Atomic(const Atomic<T>&);
32  ~Atomic();
33 
34  Atomic<T>& operator=(T nv);
35  Atomic<T>& operator=(const Atomic<T>&);
36 
37  inline mDeprecated T get() const { return std::atomic<T>::load(); }
38 
39  inline void setIfLarger(T newval);
42  inline void setIfSmaller(T newval);
46  inline bool setIfValueIs(T curval,T newval,
47  T* actualvalptr = 0);
48 };
49 
50 
59 inline bool atomicSetIfValueIs( volatile int& val, int curval, int newval,
60  int* actualvalptr = 0 )
61 {
62 # ifdef __win__
63  const int oldval =InterlockedCompareExchange( (volatile long*) &val, newval,
64  curval );
65  if ( oldval!=curval )
66  {
67  if ( actualvalptr ) *actualvalptr = oldval;
68  return false;
69  }
70 
71  return true;
72 
73 # else
74  const int old = __sync_val_compare_and_swap( &val, curval, newval );
75  if ( old!=curval )
76  {
77  if ( actualvalptr ) *actualvalptr = old;
78  return false;
79  }
80 
81  return true;
82 #endif
83 }
84 
85 
91 template <class T>
92 mClass(Basic) AtomicPointer : public std::atomic<T*>
93 {
94 public:
95  inline AtomicPointer(T* newptr = 0);
96 
97  inline bool setIfEqual(const T* curptr, T* newptr);
106  bool operator!() const { return !std::atomic<T*>::load(); }
107  operator bool() const { return std::atomic<T*>::load();}
108 
109  T* operator->() { return std::atomic<T*>::load(); }
110  const T* operator->() const { return std::atomic<T*>::load(); }
111 
112  AtomicPointer<T>& operator=(T* ptr);
113  AtomicPointer<T>& operator=(const AtomicPointer<T>&);
114 
115  inline T* setToNull();
118  inline AtomicPointer(const AtomicPointer<T>&) = delete;
119 };
120 
121 
131 {
132 public:
133  SpinLock(bool recursive = false);
134  /*\If recursive, mutex can be locked
135  multiple times from the same thread without deadlock.
136  It will be unlock when unLock has been called the same
137  number of times as lock(). */
138  SpinLock(const SpinLock&);
139  ~SpinLock();
140 
141  SpinLock& operator=(const SpinLock& b)
142  { recursive_ = b.recursive_; return *this; }
143 
144  void lock();
145  void unLock();
146  bool tryLock();
147 
148 protected:
154 
155 public:
156  int count() const { return count_; }
158 };
159 
160 
170 {
171 public:
172  SpinRWLock();
173  /*\If recursive, mutex can be locked
174  multiple times from the same thread without deadlock.
175  It will be unlock when unLock has been called the same
176  number of times as lock(). */
177  SpinRWLock(const SpinRWLock&);
178  ~SpinRWLock();
179 
180 
181  void readLock();
182  void readUnlock();
183  void writeLock();
184  void writeUnlock();
185 
186 protected:
188 
189 public:
190  int count() const { return count_; }
192 };
193 
194 
195 //Implementations
196 
197 
198 template <class T>
199 void Atomic<T>::setIfLarger( T newval )
200 {
201  T oldval = *this;
202  do
203  {
204  if ( oldval>=newval )
205  return;
206  }
207  while ( !setIfValueIs( oldval, newval, &oldval ) );
208 }
209 
210 template <class T>
211 void Atomic<T>::setIfSmaller( T newval )
212 {
213  T oldval = *this;
214  do
215  {
216  if ( oldval<=newval )
217  return;
218  }
219  while ( !setIfValueIs( oldval, newval, &oldval ) );
220 }
221 
222 
223 template <class T> inline
225  : std::atomic<T>( val )
226 {}
227 
228 
229 template <class T> inline
231  : std::atomic<T>( (T) val )
232 {}
233 
234 
235 template <class T> inline
237 {}
238 
239 
240 template <class T> inline
242 { std::atomic<T>::store(nv); return *this; }
243 
244 
245 template <class T> inline
247 { std::atomic<T>::store(nv); return *this; }
248 
249 
250 template <class T> inline
251 bool Atomic<T>::setIfValueIs( T curval, T newval, T* actualvalptr )
252 {
253  T presumedval = curval;
254  if ( !this->compare_exchange_strong(presumedval,newval) )
255  {
256  if ( actualvalptr )
257  *actualvalptr = presumedval;
258  return false;
259  }
260 
261  return true;
262 }
263 
264 
265 
266 /* AtomicPointer implementations. */
267 template <class T> inline
269  : std::atomic<T*>( newptr )
270 {}
271 
272 
273 template <class T> inline
274 bool AtomicPointer<T>::setIfEqual( const T* oldptr, T* newptr )
275 {
276  T* curval = const_cast<T*>( oldptr );
277  return this->compare_exchange_strong( curval, newptr );
278 }
279 
280 
281 template <class T> inline
283 {
284  return std::atomic<T*>::exchange( 0 );
285 }
286 
287 
288 template <class T> inline
290 {
291  std::atomic<T*>::store( ptr );
292  return *this;
293 }
294 
295 
296 template <class T> inline
298 {
299  return operator=((T*)ptr);
300 }
301 
302 } //namespace
#define mExpClass(module)
Definition: commondefs.h:157
void setIfLarger(T newval)
Definition: atomic.h:199
bool operator!() const
Definition: atomic.h:106
Atomic(T val=0)
Definition: atomic.h:224
Atomic< int > count_
Definition: atomic.h:152
SpinLock & operator=(const SpinLock &b)
Definition: atomic.h:141
bool setIfEqual(const T *curptr, T *newptr)
Definition: atomic.h:274
T * setToNull()
Definition: atomic.h:282
Atomic< int > count_
Definition: atomic.h:187
Definition: fixedstreambuf.h:18
T * operator->()
Definition: atomic.h:109
AtomicPointer(T *newptr=0)
Definition: atomic.h:268
Atomic< void * > lockingthread_
Definition: atomic.h:149
interface to threads that should be portable.
Definition: atomic.h:24
int count() const
Definition: atomic.h:156
Is an alternative to Mutex. It is a lock which causes a thread trying to acquire it to simply wait in...
Definition: atomic.h:130
Atomic< T > & operator=(T nv)
Definition: atomic.h:241
bool recursive_
Definition: atomic.h:153
Atomic instantiated with a pointer. The class really only handles the casting from a void* to a T*...
Definition: atomic.h:92
#define mDeprecated
Definition: plfdefs.h:213
int count() const
Definition: atomic.h:190
~Atomic()
Definition: atomic.h:236
bool atomicSetIfValueIs(volatile int &val, int curval, int newval, int *actualvalptr=0)
Definition: atomic.h:59
Definition: atomic.h:27
#define mClass(module)
Definition: commondefs.h:161
bool setIfValueIs(T curval, T newval, T *actualvalptr=0)
Definition: atomic.h:251
Is an alternative to ReadWriteLock. It is a lock which causes a thread trying to acquire it to simply...
Definition: atomic.h:169
const T * operator->() const
Definition: atomic.h:110
void setIfSmaller(T newval)
Definition: atomic.h:211
AtomicPointer< T > & operator=(T *ptr)
Definition: atomic.h:289

Generated at for the OpendTect seismic interpretation project. Copyright (C): dGB Beheer B. V. 2017