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: 19137 $ 00027 * $Author: rjongbloed $ 00028 * $Date: 2007-12-20 10:33:48 +0000 (Thu, 20 Dec 2007) $ 00029 */ 00030 00031 #ifndef _PCRITICALSECTION 00032 #define _PCRITICALSECTION 00033 00034 #include <ptlib/psync.h> 00035 00036 #if defined(__GNUC__) 00037 # if __GNUC__ >= 4 && __GNUC_MINOR__ >= 2 00038 # include <ext/atomicity.h> 00039 # else 00040 # include <bits/atomicity.h> 00041 # endif 00042 #endif 00043 00044 #if P_HAS_ATOMIC_INT 00045 #if P_NEEDS_GNU_CXX_NAMESPACE 00046 #define EXCHANGE_AND_ADD(v,i) __gnu_cxx::__exchange_and_add(v,i) 00047 #else 00048 #define EXCHANGE_AND_ADD(v,i) __exchange_and_add(v,i) 00049 #endif 00050 #endif 00051 00058 #ifdef _WIN32 00059 00060 class PCriticalSection : public PSync 00061 { 00062 PCLASSINFO(PCriticalSection, PSync); 00063 00064 public: 00069 PCriticalSection(); 00070 00074 PCriticalSection(const PCriticalSection &); 00075 00078 ~PCriticalSection(); 00079 00083 PCriticalSection & operator=(const PCriticalSection &) { return *this; } 00085 00090 PObject * Clone() const 00091 { 00092 return new PCriticalSection(); 00093 } 00094 00097 void Wait(); 00098 inline void Enter() { Wait(); } 00099 00102 void Signal(); 00103 inline void Leave() { Signal(); } 00104 00108 bool Try(); 00110 00111 00112 #include "msos/ptlib/critsec.h" 00113 00114 }; 00115 00116 #endif 00117 00118 typedef PWaitAndSignal PEnterAndLeave; 00119 00128 class PAtomicInteger 00129 { 00130 #if defined(_WIN32) || defined(DOC_PLUS_PLUS) 00131 public: 00134 inline PAtomicInteger( 00135 long v = 0 00136 ) 00137 : value(v) { } 00138 00146 PBoolean IsZero() const { return value == 0; } 00147 00153 inline long operator++() { return InterlockedIncrement(&value); } 00154 00160 inline long operator--() { return InterlockedDecrement(&value); } 00161 00165 inline operator long () const { return value; } 00166 00170 inline void SetValue( 00171 long v 00172 ) 00173 { value = v; } 00174 protected: 00175 long value; 00176 #elif defined(_STLP_INTERNAL_THREADS_H) && defined(_STLP_ATOMIC_INCREMENT) && defined(_STLP_ATOMIC_DECREMENT) 00177 public: 00178 inline PAtomicInteger(__stl_atomic_t v = 0) 00179 : value(v) { } 00180 PBoolean IsZero() const { return value == 0; } 00181 inline int operator++() { return _STLP_ATOMIC_INCREMENT(&value); } 00182 inline int unsigned operator--() { return _STLP_ATOMIC_DECREMENT(&value); } 00183 inline operator int () const { return value; } 00184 inline void SetValue(int v) { value = v; } 00185 protected: 00186 __stl_atomic_t value; 00187 #elif defined(__GNUC__) && P_HAS_ATOMIC_INT 00188 public: 00189 inline PAtomicInteger(int v = 0) 00190 : value(v) { } 00191 PBoolean IsZero() const { return value == 0; } 00192 inline int operator++() { return EXCHANGE_AND_ADD(&value, 1) + 1; } 00193 inline int unsigned operator--() { return EXCHANGE_AND_ADD(&value, -1) - 1; } 00194 inline operator int () const { return value; } 00195 inline void SetValue(int v) { value = v; } 00196 protected: 00197 _Atomic_word value; 00198 #else 00199 protected: 00200 PCriticalSection critSec; 00201 public: 00202 inline PAtomicInteger(int v = 0) 00203 : value(v) { } 00204 PBoolean IsZero() const { return value == 0; } 00205 inline int operator++() { PWaitAndSignal m(critSec); value++; return value;} 00206 inline int operator--() { PWaitAndSignal m(critSec); value--; return value;} 00207 inline operator int () const { return value; } 00208 inline void SetValue(int v) { value = v; } 00209 protected: 00210 int value; 00211 #endif 00212 private: 00213 PAtomicInteger & operator=(const PAtomicInteger & ref) { value = (int)ref; return *this; } 00214 }; 00215 00216 #endif 00217 00218 // End Of File ///////////////////////////////////////////////////////////////