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 _PCRITICALSECTION
00032 #define _PCRITICALSECTION
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 #if defined(_WIN32) || defined(DOC_PLUS_PLUS)
00138 public:
00141 inline PAtomicInteger(
00142 long v = 0
00143 )
00144 : value(v) { }
00145
00153 bool IsZero() const { return value == 0; }
00154
00160 inline long operator++() { return InterlockedIncrement(&value); }
00161
00167 inline long operator++(int) { return InterlockedExchangeAdd(&value, 1); }
00168
00174 inline long operator--() { return InterlockedDecrement(&value); }
00175
00181 inline long operator--(int) { return InterlockedExchangeAdd(&value, -1); }
00182
00186 inline operator long () const { return value; }
00187
00191 inline void SetValue(
00192 long v
00193 )
00194 { value = v; }
00195 protected:
00196 long value;
00197 #elif defined(_STLP_INTERNAL_THREADS_H) && defined(_STLP_ATOMIC_INCREMENT) && defined(_STLP_ATOMIC_DECREMENT)
00198 public:
00199 inline PAtomicInteger(__stl_atomic_t v = 0)
00200 : value(v) { }
00201 inline bool IsZero() const { return value == 0; }
00202 inline int operator++() { return _STLP_ATOMIC_INCREMENT(&value); }
00203 inline int operator++(int) { return _STLP_ATOMIC_INCREMENT(&value)-1; }
00204 inline int operator--() { return _STLP_ATOMIC_DECREMENT(&value); }
00205 inline int operator--(int) { return _STLP_ATOMIC_DECREMENT(&value)+1; }
00206 inline operator int () const { return value; }
00207 inline void SetValue(int v) { value = v; }
00208 protected:
00209 __stl_atomic_t value;
00210 #elif defined(SOLARIS) && !defined(__GNUC__)
00211 public:
00212 inline PAtomicInteger(uint32_t v = 0)
00213 : value(v) { }
00214 inline bool IsZero() const { return value == 0; }
00215 inline int operator++() { return atomic_add_32_nv((&value), 1); }
00216 inline int operator++(int) { return atomic_add_32_nv((&value), 1)-1; }
00217 inline int operator--() { return atomic_add_32_nv((&value), -1); }
00218 inline int operator--(int) { return atomic_add_32_nv((&value), -1)+1; }
00219 inline operator int () const { return value; }
00220 inline void SetValue(int v) { value = v; }
00221 protected:
00222 uint32_t value;
00223 #elif defined(__GNUC__) && P_HAS_ATOMIC_INT
00224 public:
00225 inline PAtomicInteger(int v = 0)
00226 : value(v) { }
00227 inline bool IsZero() const { return value == 0; }
00228 inline int operator++() { return EXCHANGE_AND_ADD(&value, 1)+1; }
00229 inline int operator++(int) { return EXCHANGE_AND_ADD(&value, 1); }
00230 inline int operator--() { return EXCHANGE_AND_ADD(&value, -1)-1; }
00231 inline int operator--(int) { return EXCHANGE_AND_ADD(&value, -1); }
00232 inline operator int () const { return value; }
00233 inline void SetValue(int v) { value = v; }
00234 protected:
00235 _Atomic_word value;
00236 #else
00237 public:
00238 inline PAtomicInteger(int v = 0)
00239 : value(v) { pthread_mutex_init(&mutex, NULL); }
00240 inline ~PAtomicInteger() { pthread_mutex_destroy(&mutex); }
00241 inline bool IsZero() const { return value == 0; }
00242 inline int operator++() { pthread_mutex_lock(&mutex); int retval = ++value; pthread_mutex_unlock(&mutex); return retval; }
00243 inline int operator++(int) { pthread_mutex_lock(&mutex); int retval = value++; pthread_mutex_unlock(&mutex); return retval; }
00244 inline int operator--() { pthread_mutex_lock(&mutex); int retval = --value; pthread_mutex_unlock(&mutex); return retval; }
00245 inline int operator--(int) { pthread_mutex_lock(&mutex); int retval = value--; pthread_mutex_unlock(&mutex); return retval; }
00246 inline operator int () const { return value; }
00247 inline void SetValue(int v) { pthread_mutex_lock(&mutex); value = v; pthread_mutex_unlock(&mutex); }
00248 protected:
00249 pthread_mutex_t mutex;
00250 int value;
00251 #endif
00252 private:
00253 PAtomicInteger & operator=(const PAtomicInteger & ref) { value = (int)ref; return *this; }
00254 };
00255
00256 #endif
00257
00258