00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef PTLIB_CRITICALSECTION_H
00032 #define PTLIB_CRITICALSECTION_H
00033
00034 #include <ptlib/psync.h>
00035
00036 #if defined(SOLARIS) && !defined(__GNUC__)
00037 #include <atomic.h>
00038 #endif
00039
00040 #if P_HAS_ATOMIC_INT
00041
00042 #if defined(__GNUC__)
00043 # if __GNUC__ >= 4 && __GNUC_MINOR__ >= 2
00044 # include <ext/atomicity.h>
00045 # else
00046 # include <bits/atomicity.h>
00047 # endif
00048 #endif
00049
00050 #if P_NEEDS_GNU_CXX_NAMESPACE
00051 #define EXCHANGE_AND_ADD(v,i) __gnu_cxx::__exchange_and_add(v,i)
00052 #else
00053 #define EXCHANGE_AND_ADD(v,i) __exchange_and_add(v,i)
00054 #endif
00055
00056 #endif // P_HAS_ATOMIC_INT
00057
00058
00065 #ifdef _WIN32
00066
00067 class PCriticalSection : public PSync
00068 {
00069 PCLASSINFO(PCriticalSection, PSync);
00070
00071 public:
00076 PCriticalSection();
00077
00081 PCriticalSection(const PCriticalSection &);
00082
00085 ~PCriticalSection();
00086
00090 PCriticalSection & operator=(const PCriticalSection &) { return *this; }
00092
00097 PObject * Clone() const
00098 {
00099 return new PCriticalSection();
00100 }
00101
00104 void Wait();
00105 inline void Enter() { Wait(); }
00106
00109 void Signal();
00110 inline void Leave() { Signal(); }
00111
00115 bool Try();
00117
00118
00119 #include "msos/ptlib/critsec.h"
00120
00121 };
00122
00123 #endif
00124
00125 typedef PWaitAndSignal PEnterAndLeave;
00126
00135 class PAtomicInteger
00136 {
00137 public:
00138 #if defined(_WIN32)
00139 typedef long IntegerType;
00140 #elif defined(_STLP_INTERNAL_THREADS_H) && defined(_STLP_ATOMIC_INCREMENT) && defined(_STLP_ATOMIC_DECREMENT)
00141 typedef __stl_atomic_t IntegerType;
00142 #elif defined(SOLARIS) && !defined(__GNUC__)
00143 typedef uint32_t IntegerType;
00144 #elif defined(__GNUC__) && P_HAS_ATOMIC_INT
00145 typedef _Atomic_word IntegerType;
00146 #else
00147 typedef int IntegerType;
00148 protected:
00149 pthread_mutex_t m_mutex;
00150 #endif
00151
00152 protected:
00153 IntegerType m_value;
00154
00155 public:
00158 explicit PAtomicInteger(
00159 IntegerType value = 0
00160 );
00161
00163 ~PAtomicInteger();
00164
00166 __inline operator IntegerType() const { return m_value; }
00167
00169 __inline PAtomicInteger & operator=(const PAtomicInteger & ref) { SetValue(ref); return *this; }
00170
00172 void SetValue(
00173 IntegerType value
00174 );
00175
00183 __inline bool IsZero() const { return m_value == 0; }
00184
00186 __inline bool operator!() const { return m_value != 0; }
00187
00188
00194 IntegerType operator++();
00195
00201 IntegerType operator++(int);
00202
00208 IntegerType operator--();
00209
00215 IntegerType operator--(int);
00216 };
00217
00218
00219 #if defined(_WIN32) || defined(DOC_PLUS_PLUS)
00220 __inline PAtomicInteger::PAtomicInteger(IntegerType value) : m_value(value) { }
00221 __inline PAtomicInteger::~PAtomicInteger() { }
00222 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { return InterlockedIncrement(&m_value); }
00223 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { return InterlockedExchangeAdd(&m_value, 1); }
00224 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { return InterlockedDecrement(&m_value); }
00225 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { return InterlockedExchangeAdd(&m_value, -1); }
00226 __inline void PAtomicInteger::SetValue(IntegerType value) { m_value = value; }
00227 #elif defined(_STLP_INTERNAL_THREADS_H) && defined(_STLP_ATOMIC_INCREMENT) && defined(_STLP_ATOMIC_DECREMENT)
00228 __inline PAtomicInteger::PAtomicInteger(IntegerType value) : m_value(value) { }
00229 __inline PAtomicInteger::~PAtomicInteger() { }
00230 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { return _STLP_ATOMIC_INCREMENT(&m_value); }
00231 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { return _STLP_ATOMIC_INCREMENT(&m_value)-1; }
00232 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { return _STLP_ATOMIC_DECREMENT(&m_value); }
00233 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { return _STLP_ATOMIC_DECREMENT(&m_value)+1; }
00234 __inline void PAtomicInteger::SetValue(IntegerType value) { m_value = value; }
00235 #elif defined(SOLARIS) && !defined(__GNUC__)
00236 __inline PAtomicInteger::PAtomicInteger(IntegerType value) : m_value(value) { }
00237 __inline PAtomicInteger::~PAtomicInteger() { }
00238 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { return atomic_add_32_nv((&m_value), 1); }
00239 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { return atomic_add_32_nv((&m_value), 1)-1; }
00240 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { return atomic_add_32_nv((&m_value), -1); }
00241 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { return atomic_add_32_nv((&m_value), -1)+1; }
00242 __inline void PAtomicInteger::SetValue(IntegerType value) { m_value = value; }
00243 #elif defined(__GNUC__) && P_HAS_ATOMIC_INT
00244 __inline PAtomicInteger::PAtomicInteger(IntegerType value) : m_value(value) { }
00245 __inline PAtomicInteger::~PAtomicInteger() { }
00246 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { return EXCHANGE_AND_ADD(&m_value, 1)+1; }
00247 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { return EXCHANGE_AND_ADD(&m_value, 1); }
00248 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { return EXCHANGE_AND_ADD(&m_value, -1)-1; }
00249 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { return EXCHANGE_AND_ADD(&m_value, -1); }
00250 __inline void PAtomicInteger::SetValue(IntegerType value) { m_value = value; }
00251 #else
00252 __inline PAtomicInteger::PAtomicInteger(IntegerType value) : m_value(value) { pthread_mutex_init(&mutex, NULL); }
00253 __inline PAtomicInteger::~PAtomicInteger() { pthread_mutex_destroy(&mutex); }
00254 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { pthread_mutex_lock(&mutex); int retval = ++m_value; pthread_mutex_unlock(&mutex); return retval; }
00255 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { pthread_mutex_lock(&mutex); int retval = m_value++; pthread_mutex_unlock(&mutex); return retval; }
00256 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { pthread_mutex_lock(&mutex); int retval = --m_value; pthread_mutex_unlock(&mutex); return retval; }
00257 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { pthread_mutex_lock(&mutex); int retval = m_value--; pthread_mutex_unlock(&mutex); return retval; }
00258 __inline void PAtomicInteger::SetValue(IntegerType v) { pthread_mutex_lock(&mutex); m_value = v; pthread_mutex_unlock(&mutex); }
00259 #endif
00260
00261
00262 #endif // PTLIB_CRITICALSECTION_H
00263
00264
00265