OpendTect  6.6
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 "gendefs.h"
14 #include "odversion.h"
15 
16 #ifdef __win__
17 # include "windows.h"
18 #endif
19 
20 # include <atomic>
21 
22 namespace Threads
23 {
24 
25 template <class T>
26 mClass(Basic) Atomic : public std::atomic<T>
27 {
28 public:
29  Atomic(T val=0);
30  Atomic(const Atomic<T>&);
32 
35 
36  mDeprecated("Use load") inline T get() const
37  { 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 mGlobal(Basic) bool atomicSetIfValueIs(volatile int& val,int curval,int newval,
60  int* actualvalptr);
61 
62 
68 template <class T>
69 mClass(Basic) AtomicPointer : public std::atomic<T*>
70 {
71 public:
72  inline AtomicPointer(T* newptr = 0);
73 
74  inline bool setIfEqual(const T* curptr, T* newptr);
83  bool operator!() const { return !std::atomic<T*>::load(); }
84  operator bool() const { return std::atomic<T*>::load();}
85 
86  T* operator->() { return std::atomic<T*>::load(); }
87  const T* operator->() const { return std::atomic<T*>::load(); }
88 
91 
92  inline T* setToNull();
95  inline AtomicPointer(const AtomicPointer<T>&) = delete;
96 };
97 
98 
108 {
109 public:
110  SpinLock(bool recursive = false);
111  /*\If recursive, mutex can be locked
112  multiple times from the same thread without deadlock.
113  It will be unlock when unLock has been called the same
114  number of times as lock(). */
117 
119  { recursive_ = b.recursive_; return *this; }
120 
121  void lock();
122  void unLock();
123  bool tryLock();
124 
125 protected:
131 
132 public:
133  int count() const { return count_; }
135 };
136 
137 
147 {
148 public:
150  /*\If recursive, mutex can be locked
151  multiple times from the same thread without deadlock.
152  It will be unlock when unLock has been called the same
153  number of times as lock(). */
156 
157 
158  void readLock();
159  void readUnlock();
160  void writeLock();
161  void writeUnlock();
162 
163 protected:
165 
166 public:
167  int count() const { return count_; }
169 };
170 
171 
172 //Implementations
173 
174 
175 template <class T>
176 void Atomic<T>::setIfLarger( T newval )
177 {
178  T oldval = *this;
179  do
180  {
181  if ( oldval>=newval )
182  return;
183  }
184  while ( !setIfValueIs( oldval, newval, &oldval ) );
185 }
186 
187 template <class T>
188 void Atomic<T>::setIfSmaller( T newval )
189 {
190  T oldval = *this;
191  do
192  {
193  if ( oldval<=newval )
194  return;
195  }
196  while ( !setIfValueIs( oldval, newval, &oldval ) );
197 }
198 
199 
200 template <class T> inline
202  : std::atomic<T>( val )
203 {}
204 
205 
206 template <class T> inline
208  : std::atomic<T>( sCast(T,val) )
209 {}
210 
211 
212 template <class T> inline
214 {}
215 
216 
217 template <class T> inline
219 { std::atomic<T>::store(nv); return *this; }
220 
221 
222 template <class T> inline
224 { std::atomic<T>::store(nv); return *this; }
225 
226 
227 template <class T> inline
228 bool Atomic<T>::setIfValueIs( T curval, T newval, T* actualvalptr )
229 {
230  T presumedval = curval;
231  if ( !this->compare_exchange_strong(presumedval,newval) )
232  {
233  if ( actualvalptr )
234  *actualvalptr = presumedval;
235  return false;
236  }
237 
238  return true;
239 }
240 
241 
242 
243 /* AtomicPointer implementations. */
244 template <class T> inline
246  : std::atomic<T*>( newptr )
247 {}
248 
249 
250 template <class T> inline
251 bool AtomicPointer<T>::setIfEqual( const T* oldptr, T* newptr )
252 {
253  T* curval = const_cast<T*>( oldptr );
254  return this->compare_exchange_strong( curval, newptr );
255 }
256 
257 
258 template <class T> inline
260 {
261  return std::atomic<T*>::exchange( 0 );
262 }
263 
264 
265 template <class T> inline
267 {
268  std::atomic<T*>::store( ptr );
269  return *this;
270 }
271 
272 
273 template <class T> inline
275 {
276  return operator=( sCast(T*,ptr) );
277 }
278 
279 } //namespace Threads
280 
281 
Threads::Atomic::setIfLarger
void setIfLarger(T newval)
Definition: atomic.h:176
Threads::AtomicPointer
Atomic instantiated with a pointer. The class really only handles the casting from a void* to a T*.
Definition: atomic.h:70
Threads::AtomicPointer::AtomicPointer
AtomicPointer(T *newptr=0)
Definition: atomic.h:245
DirtyCounter
Threads::Atomic< DirtyCountType > DirtyCounter
Definition: atomic.h:282
Threads::Atomic::Atomic
Atomic(T val=0)
Definition: atomic.h:201
Threads::SpinLock::unLock
void unLock()
mGlobal
#define mGlobal(module)
Definition: commondefs.h:180
Threads::SpinLock::count_
Atomic< int > count_
Definition: atomic.h:129
Threads::SpinLock::recursive_
bool recursive_
Definition: atomic.h:130
mExpClass
#define mExpClass(module)
Definition: commondefs.h:177
sCast
#define sCast(tp, v)
Definition: commondefs.h:141
Threads::AtomicPointer::operator=
AtomicPointer< T > & operator=(const AtomicPointer< T > &)
Definition: atomic.h:274
Threads::Atomic::Atomic
Atomic(const Atomic< T > &)
Definition: atomic.h:207
Threads::AtomicPointer::operator->
T * operator->()
Definition: atomic.h:86
Threads::SpinRWLock::writeUnlock
void writeUnlock()
Threads::SpinLock
Is an alternative to Mutex. It is a lock which causes a thread trying to acquire it to simply wait in...
Definition: atomic.h:108
Threads::Atomic::operator=
Atomic< T > & operator=(const Atomic< T > &)
Definition: atomic.h:223
Threads::SpinLock::lockingthread_
Atomic< void * > lockingthread_
Definition: atomic.h:126
Threads::SpinLock::~SpinLock
~SpinLock()
Threads::SpinLock::count
int count() const
Definition: atomic.h:133
Threads::SpinLock::lock
void lock()
Threads::SpinRWLock::readLock
void readLock()
Threads::SpinRWLock::count_
Atomic< int > count_
Definition: atomic.h:164
mClass
#define mClass(module)
Definition: commondefs.h:181
mDeprecated
#define mDeprecated(msg)
Definition: plfdefs.h:215
Threads::Atomic::operator=
Atomic< T > & operator=(T nv)
Definition: atomic.h:218
gendefs.h
Threads::SpinRWLock::SpinRWLock
SpinRWLock()
Threads::atomicSetIfValueIs
bool atomicSetIfValueIs(volatile int &val, int curval, int newval, int *actualvalptr)
Threads::AtomicPointer::setIfEqual
bool setIfEqual(const T *curptr, T *newptr)
Definition: atomic.h:251
Threads::AtomicPointer::operator=
AtomicPointer< T > & operator=(T *ptr)
Definition: atomic.h:266
Threads::SpinRWLock::~SpinRWLock
~SpinRWLock()
Threads::Atomic::~Atomic
~Atomic()
Definition: atomic.h:213
Threads::SpinRWLock::count
int count() const
Definition: atomic.h:167
std
Definition: fixedstreambuf.h:20
Threads::SpinLock::SpinLock
SpinLock(const SpinLock &)
Threads::SpinLock::operator=
SpinLock & operator=(const SpinLock &b)
Definition: atomic.h:118
Threads::AtomicPointer::operator!
bool operator!() const
Definition: atomic.h:83
Threads::AtomicPointer::operator->
const T * operator->() const
Definition: atomic.h:87
Threads::Atomic::setIfValueIs
bool setIfValueIs(T curval, T newval, T *actualvalptr=0)
Definition: atomic.h:228
Threads::SpinRWLock::writeLock
void writeLock()
Threads::SpinRWLock
Is an alternative to ReadWriteLock. It is a lock which causes a thread trying to acquire it to simply...
Definition: atomic.h:147
Threads::AtomicPointer::AtomicPointer
AtomicPointer(const AtomicPointer< T > &)=delete
Threads::SpinRWLock::readUnlock
void readUnlock()
Threads::AtomicPointer::setToNull
T * setToNull()
Definition: atomic.h:259
Threads::SpinRWLock::SpinRWLock
SpinRWLock(const SpinRWLock &)
Threads::Atomic::setIfSmaller
void setIfSmaller(T newval)
Definition: atomic.h:188
Threads::SpinLock::tryLock
bool tryLock()
Threads
interface to threads that should be portable.
Definition: atomic.h:23
Threads::Atomic
Definition: atomic.h:27
Threads::SpinLock::SpinLock
SpinLock(bool recursive=false)

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