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: 19008 $ 00027 * $Author: rjongbloed $ 00028 * $Date: 2007-11-29 09:17:41 +0000 (Thu, 29 Nov 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 void Wait(); 00091 inline void Enter() 00092 { Wait(); } 00093 00096 void Signal(); 00097 inline void Leave() 00098 { Signal(); } 00099 00102 PObject * Clone() const 00103 { return new PCriticalSection(); } 00104 00106 00107 00108 #include "msos/ptlib/critsec.h" 00109 00110 }; 00111 00112 #endif 00113 00114 typedef PWaitAndSignal PEnterAndLeave; 00115 00124 class PAtomicInteger 00125 { 00126 #if defined(_WIN32) || defined(DOC_PLUS_PLUS) 00127 public: 00130 inline PAtomicInteger( 00131 long v = 0 00132 ) 00133 : value(v) { } 00134 00142 PBoolean IsZero() const { return value == 0; } 00143 00149 inline long operator++() { return InterlockedIncrement(&value); } 00150 00156 inline long operator--() { return InterlockedDecrement(&value); } 00157 00161 inline operator long () const { return value; } 00162 00166 inline void SetValue( 00167 long v 00168 ) 00169 { value = v; } 00170 protected: 00171 long value; 00172 #elif defined(_STLP_INTERNAL_THREADS_H) && defined(_STLP_ATOMIC_INCREMENT) && defined(_STLP_ATOMIC_DECREMENT) 00173 public: 00174 inline PAtomicInteger(__stl_atomic_t v = 0) 00175 : value(v) { } 00176 PBoolean IsZero() const { return value == 0; } 00177 inline int operator++() { return _STLP_ATOMIC_INCREMENT(&value); } 00178 inline int unsigned operator--() { return _STLP_ATOMIC_DECREMENT(&value); } 00179 inline operator int () const { return value; } 00180 inline void SetValue(int v) { value = v; } 00181 protected: 00182 __stl_atomic_t value; 00183 #elif defined(__GNUC__) && P_HAS_ATOMIC_INT 00184 public: 00185 inline PAtomicInteger(int v = 0) 00186 : value(v) { } 00187 PBoolean IsZero() const { return value == 0; } 00188 inline int operator++() { return EXCHANGE_AND_ADD(&value, 1) + 1; } 00189 inline int unsigned operator--() { return EXCHANGE_AND_ADD(&value, -1) - 1; } 00190 inline operator int () const { return value; } 00191 inline void SetValue(int v) { value = v; } 00192 protected: 00193 _Atomic_word value; 00194 #else 00195 protected: 00196 PCriticalSection critSec; 00197 public: 00198 inline PAtomicInteger(int v = 0) 00199 : value(v) { } 00200 PBoolean IsZero() const { return value == 0; } 00201 inline int operator++() { PWaitAndSignal m(critSec); value++; return value;} 00202 inline int operator--() { PWaitAndSignal m(critSec); value--; return value;} 00203 inline operator int () const { return value; } 00204 inline void SetValue(int v) { value = v; } 00205 protected: 00206 int value; 00207 #endif 00208 private: 00209 PAtomicInteger & operator=(const PAtomicInteger & ref) { value = (int)ref; return *this; } 00210 }; 00211 00212 #endif 00213 00214 // End Of File ///////////////////////////////////////////////////////////////