PTLib
Version 2.10.4
|
00001 /* 00002 * critsec.h 00003 * 00004 * Critical section mutex class. 00005 * 00006 * Portable Windows Library 00007 * 00008 * Copyright (C) 2004 Post Increment 00009 * 00010 * The contents of this file are subject to the Mozilla Public License 00011 * Version 1.0 (the "License"); you may not use this file except in 00012 * compliance with the License. You may obtain a copy of the License at 00013 * http://www.mozilla.org/MPL/ 00014 * 00015 * Software distributed under the License is distributed on an "AS IS" 00016 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 00017 * the License for the specific language governing rights and limitations 00018 * under the License. 00019 * 00020 * The Original Code is Portable Windows Library. 00021 * 00022 * The Initial Developer of the Original Code is Post Increment 00023 * 00024 * Contributor(s): ______________________________________. 00025 * 00026 * $Revision: 25356 $ 00027 * $Author: rjongbloed $ 00028 * $Date: 2011-03-17 17:37:13 -0500 (Thu, 17 Mar 2011) $ 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=(IntegerType i) { SetValue(i); return *this; } 00170 00172 __inline PAtomicInteger & operator=(const PAtomicInteger & ref) { SetValue(ref); return *this; } 00173 00175 void SetValue( 00176 IntegerType value 00177 ); 00178 00186 __inline bool IsZero() const { return m_value == 0; } 00187 00189 __inline bool operator!() const { return m_value != 0; } 00190 00191 friend __inline ostream & operator<<(ostream & strm, const PAtomicInteger & i) 00192 { 00193 return strm << i.m_value; 00194 } 00195 00201 IntegerType operator++(); 00202 00208 IntegerType operator++(int); 00209 00215 IntegerType operator--(); 00216 00222 IntegerType operator--(int); 00223 }; 00224 00225 00226 #if defined(_WIN32) || defined(DOC_PLUS_PLUS) 00227 __inline PAtomicInteger::PAtomicInteger(IntegerType value) : m_value(value) { } 00228 __inline PAtomicInteger::~PAtomicInteger() { } 00229 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { return InterlockedIncrement(&m_value); } 00230 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { return InterlockedExchangeAdd(&m_value, 1); } 00231 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { return InterlockedDecrement(&m_value); } 00232 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { return InterlockedExchangeAdd(&m_value, -1); } 00233 __inline void PAtomicInteger::SetValue(IntegerType value) { m_value = value; } 00234 #elif defined(_STLP_INTERNAL_THREADS_H) && defined(_STLP_ATOMIC_INCREMENT) && defined(_STLP_ATOMIC_DECREMENT) 00235 __inline PAtomicInteger::PAtomicInteger(IntegerType value) : m_value(value) { } 00236 __inline PAtomicInteger::~PAtomicInteger() { } 00237 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { return _STLP_ATOMIC_INCREMENT(&m_value); } 00238 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { return _STLP_ATOMIC_INCREMENT(&m_value)-1; } 00239 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { return _STLP_ATOMIC_DECREMENT(&m_value); } 00240 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { return _STLP_ATOMIC_DECREMENT(&m_value)+1; } 00241 __inline void PAtomicInteger::SetValue(IntegerType value) { m_value = value; } 00242 #elif defined(SOLARIS) && !defined(__GNUC__) 00243 __inline PAtomicInteger::PAtomicInteger(IntegerType value) : m_value(value) { } 00244 __inline PAtomicInteger::~PAtomicInteger() { } 00245 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { return atomic_add_32_nv((&m_value), 1); } 00246 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { return atomic_add_32_nv((&m_value), 1)-1; } 00247 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { return atomic_add_32_nv((&m_value), -1); } 00248 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { return atomic_add_32_nv((&m_value), -1)+1; } 00249 __inline void PAtomicInteger::SetValue(IntegerType value) { m_value = value; } 00250 #elif defined(__GNUC__) && P_HAS_ATOMIC_INT 00251 __inline PAtomicInteger::PAtomicInteger(IntegerType value) : m_value(value) { } 00252 __inline PAtomicInteger::~PAtomicInteger() { } 00253 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { return EXCHANGE_AND_ADD(&m_value, 1)+1; } 00254 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { return EXCHANGE_AND_ADD(&m_value, 1); } 00255 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { return EXCHANGE_AND_ADD(&m_value, -1)-1; } 00256 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { return EXCHANGE_AND_ADD(&m_value, -1); } 00257 __inline void PAtomicInteger::SetValue(IntegerType value) { m_value = value; } 00258 #else 00259 __inline PAtomicInteger::PAtomicInteger(IntegerType value) : m_value(value) { pthread_mutex_init(&m_mutex, NULL); } 00260 __inline PAtomicInteger::~PAtomicInteger() { pthread_mutex_destroy(&m_mutex); } 00261 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { pthread_mutex_lock(&m_mutex); int retval = ++m_value; pthread_mutex_unlock(&m_mutex); return retval; } 00262 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { pthread_mutex_lock(&m_mutex); int retval = m_value++; pthread_mutex_unlock(&m_mutex); return retval; } 00263 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { pthread_mutex_lock(&m_mutex); int retval = --m_value; pthread_mutex_unlock(&m_mutex); return retval; } 00264 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { pthread_mutex_lock(&m_mutex); int retval = m_value--; pthread_mutex_unlock(&m_mutex); return retval; } 00265 __inline void PAtomicInteger::SetValue(IntegerType v) { pthread_mutex_lock(&m_mutex); m_value = v; pthread_mutex_unlock(&m_mutex); } 00266 #endif 00267 00268 00269 #endif // PTLIB_CRITICALSECTION_H 00270 00271 00272 // End Of File ///////////////////////////////////////////////////////////////