27 #ifndef PTLIB_CRITICALSECTION_H
28 #define PTLIB_CRITICALSECTION_H
35 #define PAtomicEnum std::atomic
39 #ifdef P_ATOMICITY_HEADER
40 #include P_ATOMICITY_HEADER
43 template <
typename Type>
struct atomic
45 __inline
atomic() { this->ConstructMutex(); }
46 __inline
atomic(Type value) : m_storage(value) { this->ConstructMutex(); }
47 __inline
atomic(
const atomic & other) : m_storage(other.m_storage) { this->ConstructMutex(); }
48 __inline
~atomic() { this->DestroyMutex(); }
49 __inline
atomic &
operator=(
const atomic & other) { this->Lock(); other.Lock(); this->m_storage = other.m_storage; other.Unlock(); this->Unlock();
return *
this; }
50 __inline
operator Type()
const { this->Lock(); Type value = this->m_storage; this->Unlock();
return value; }
51 __inline Type
load()
const { this->Lock(); Type value = this->m_storage; this->Unlock();
return value; } \
52 __inline
void store(Type value) { this->Lock(); this->m_storage = value; this->Unlock(); } \
53 __inline Type
exchange(Type value) { this->Lock(); Type previous = this->m_storage; this->m_storage = value; this->Unlock();
return previous; }
57 if (this->m_storage == comp) {
58 this->m_storage = value;
63 comp = this->m_storage;
70 volatile Type m_storage;
74 mutable CRITICAL_SECTION m_mutex;
75 __inline
void ConstructMutex() { InitializeCriticalSection(&this->m_mutex); }
76 __inline
void DestroyMutex() { DeleteCriticalSection(&this->m_mutex); }
77 __inline
void Lock()
const { EnterCriticalSection(&this->m_mutex); }
78 __inline
void Unlock()
const { LeaveCriticalSection(&this->m_mutex); }
80 mutable pthread_mutex_t m_mutex;
81 __inline
void ConstructMutex() { pthread_mutex_init(&this->m_mutex, NULL); }
82 __inline
void DestroyMutex() { pthread_mutex_destroy(&this->m_mutex); }
83 __inline
void Lock()
const { pthread_mutex_lock(&this->m_mutex); }
84 __inline
void Unlock()
const { pthread_mutex_unlock(&this->m_mutex); }
88 #define P_DEFINE_ATOMIC_FUNCTIONS(Type,Exch,FetchAdd,AddFetch,CompExch) \
89 __inline atomic() : m_storage() { } \
90 __inline atomic(Type value) : m_storage(value) { } \
91 __inline atomic(const atomic & other) : m_storage((Type)AddFetch(const_cast<Type *>(&other.m_storage), 0)) { } \
92 __inline atomic & operator=(const atomic & other) { store(other.load()); return *this; } \
93 __inline atomic & operator=(Type other) { store(other); return *this; } \
94 __inline operator Type() const { return (Type)AddFetch(const_cast<Type *>(&m_storage), 0); } \
95 __inline bool compare_exchange_strong(Type & comp, Type value) { return CompExch(&m_storage, comp, value); } \
96 __inline void store(Type value) { exchange(value); } \
97 __inline Type load() const { return (Type)AddFetch(const_cast<Type *>(&m_storage), 0); } \
98 __inline Type exchange(Type value) { return (Type)Exch(&m_storage, value); } \
99 __inline Type operator++() { return (Type)AddFetch(&m_storage, 1); } \
100 __inline Type operator++(int) { return (Type)FetchAdd(&m_storage, 1); } \
101 __inline Type operator+=(Type i) { return (Type)AddFetch(&m_storage, i); } \
102 __inline Type operator--() { return (Type)AddFetch(&m_storage, -1); } \
103 __inline Type operator--(int) { return (Type)FetchAdd(&m_storage, -1); } \
104 __inline Type operator-=(Type i) { return (Type)AddFetch(&m_storage, -i); } \
106 #define P_DEFINE_ATOMIC_INT_CLASS(Type,Exch,FetchAdd,AddFetch,CompExch) \
107 template <> struct atomic<Type> { \
108 P_DEFINE_ATOMIC_FUNCTIONS(Type,Exch,FetchAdd,AddFetch,CompExch) \
109 private: volatile Type m_storage; \
112 #define P_DEFINE_ATOMIC_PTR_CLASS(Exch,FetchAdd,AddFetch,CompExch) \
113 template <typename Type> struct atomic<Type *> { \
114 P_DEFINE_ATOMIC_FUNCTIONS(Type*,Exch,FetchAdd,AddFetch,CompExch) \
115 private: volatile Type * m_storage; \
120 #define P_Exchange8(storage, value) _InterlockedExchange8 ((CHAR *)(storage), value)
121 #define P_CompExch8(storage,comp,value) (_InterlockedCompareExchange8 ((CHAR *)(storage), value, comp) == (CHAR)comp)
122 #define P_FetchAdd8(storage, value) _InterlockedExchangeAdd8 ((char *)(storage), value)
123 #define P_AddFetch8(storage, value) (_InterlockedExchangeAdd8 ((char *)(storage), value)+value)
124 #define P_Exchange16(storage, value) _InterlockedExchange16 ((SHORT *)(storage), value)
125 #define P_CompExch16(storage,comp,value) (_InterlockedCompareExchange16 ((SHORT *)(storage), value, comp) == (SHORT)comp)
126 #define P_FetchAdd16(storage, value) _InterlockedExchangeAdd16 ((SHORT *)(storage), value)
127 #define P_AddFetch16(storage, value) (_InterlockedExchangeAdd16 ((SHORT *)(storage), value)+value)
128 #define P_Exchange32(storage, value) _InterlockedExchange ((LONG *)(storage), value)
129 #define P_CompExch32(storage,comp,value) (_InterlockedCompareExchange ((LONG *)(storage), value, comp) == (LONG)comp)
130 #define P_FetchAdd32(storage, value) _InterlockedExchangeAdd ((LONG *)(storage), value)
131 #define P_AddFetch32(storage, value) _InterlockedAdd ((LONG *)(storage), value)
132 #define P_Exchange64(storage, value) _InterlockedExchange64 ((LONG64*)(storage), value)
133 #define P_CompExch64(storage,comp,value) (_InterlockedCompareExchange64 ((LONG64*)(storage), value, comp) == (LONG64)comp)
134 #define P_FetchAdd64(storage, value) _InterlockedExchangeAdd64 ((LONG64*)(storage), value)
135 #define P_AddFetch64(storage, value) _InterlockedAdd64 ((LONG64*)(storage), value)
136 #define P_ExchangePtr(storage, value) _InterlockedExchangePointer ((PVOID *)(storage), value)
138 #define P_CompExchPtr(storage,comp,value) (_InterlockedCompareExchange64((LONG *)(storage), value, comp) == comp)
139 #define P_FetchAddPtr(storage, value) _InterlockedExchangeAdd64 ((LONG64*)(storage), value)
140 #define P_AddFetchPtr(storage, value) _InterlockedAdd64 ((LONG64*)(storage), value)
142 #define P_CompExchPtr(storage,comp,value) (_InterlockedCompareExchange ((LONG *)(storage), value, comp) == comp)
143 #define P_FetchAddPtr(storage, value) _InterlockedExchangeAdd ((LONG *)(storage), value)
144 #define P_AddFetchPtr(storage, value) _InterlockedAdd ((LONG *)(storage), value)
147 #define P_DEFINE_ATOMIC_INT_CLASS_WIN32(Type, Size) \
148 P_DEFINE_ATOMIC_INT_CLASS(Type, P_Exchange##Size, P_FetchAdd##Size, P_AddFetch##Size, P_CompExch##Size)
150 P_DEFINE_ATOMIC_INT_CLASS_WIN32(
bool, 8 );
151 P_DEFINE_ATOMIC_INT_CLASS_WIN32(
signed char, 8 );
152 P_DEFINE_ATOMIC_INT_CLASS_WIN32(
unsigned char, 8 );
153 P_DEFINE_ATOMIC_INT_CLASS_WIN32(
signed short, 16);
154 P_DEFINE_ATOMIC_INT_CLASS_WIN32(
unsigned short, 16);
155 P_DEFINE_ATOMIC_INT_CLASS_WIN32(
signed int, 32);
156 P_DEFINE_ATOMIC_INT_CLASS_WIN32(
unsigned int, 32);
157 P_DEFINE_ATOMIC_INT_CLASS_WIN32(
signed long, 32);
158 P_DEFINE_ATOMIC_INT_CLASS_WIN32(
unsigned long, 32);
159 P_DEFINE_ATOMIC_INT_CLASS_WIN32(
signed long long, 64);
160 P_DEFINE_ATOMIC_INT_CLASS_WIN32(
unsigned long long, 64);
164 #elif defined(P_ATOMICITY_BUILTIN)
166 template <
typename Type>
static __inline
bool p_compare_exchange_strong(
volatile Type *ptr, Type & comp, Type newval)
168 Type oldval = __sync_val_compare_and_swap(ptr, comp, newval);
175 #define P_DEFINE_ATOMIC_INT_CLASS_BUILTIN(Type) \
176 P_DEFINE_ATOMIC_INT_CLASS(Type, __sync_lock_test_and_set, __sync_fetch_and_add, __sync_add_and_fetch, p_compare_exchange_strong)
178 template <>
struct atomic<bool>
180 __inline
atomic() : m_storage() { }
181 __inline
atomic(
bool value) : m_storage(value) { }
182 __inline
atomic(
const atomic & other) : m_storage(__sync_add_and_fetch(reinterpret_cast<char *>(const_cast<bool *>(&other.m_storage)), 0)) { }
185 __inline
operator bool()
const {
return __sync_add_and_fetch(reinterpret_cast<char *>(const_cast<bool *>(&m_storage)), 0) != 0; }
186 __inline
bool compare_exchange_strong(
bool & comp,
bool value) {
return p_compare_exchange_strong(&m_storage, comp, value); }
188 __inline
bool load()
const {
return __sync_add_and_fetch(reinterpret_cast<char *>(const_cast<bool *>(&m_storage)), 0) != 0; }
189 __inline
bool exchange(
bool value) {
return __sync_lock_test_and_set(&m_storage, value) != 0; }
190 private:
volatile bool m_storage;
193 P_DEFINE_ATOMIC_INT_CLASS_BUILTIN(
signed char);
194 P_DEFINE_ATOMIC_INT_CLASS_BUILTIN(
unsigned char);
195 P_DEFINE_ATOMIC_INT_CLASS_BUILTIN(
signed short);
196 P_DEFINE_ATOMIC_INT_CLASS_BUILTIN(
unsigned short);
197 P_DEFINE_ATOMIC_INT_CLASS_BUILTIN(
signed int);
198 P_DEFINE_ATOMIC_INT_CLASS_BUILTIN(
unsigned int);
199 P_DEFINE_ATOMIC_INT_CLASS_BUILTIN(
signed long);
200 P_DEFINE_ATOMIC_INT_CLASS_BUILTIN(
unsigned long);
201 #if HAVE_LONG_LONG_INT
202 P_DEFINE_ATOMIC_INT_CLASS_BUILTIN(
signed long long);
204 #if HAVE_UNSIGNED_LONG_LONG_INT
205 P_DEFINE_ATOMIC_INT_CLASS_BUILTIN(
unsigned long long);
207 P_DEFINE_ATOMIC_PTR_CLASS(__sync_lock_test_and_set, __sync_fetch_and_add, __sync_add_and_fetch, __sync_bool_compare_and_swap);
209 #elif defined(SOLARIS) && !defined(__GNUC__)
220 #if HAVE_LONG_LONG_INT
223 #if HAVE_UNSIGNED_LONG_LONG_INT
232 #elif defined(P_ATOMICITY_HEADER)
244 __inline
operator Enum()
const {
return this->
load(); }
245 __inline Enum
load()
const {
return (Enum)this->m_enum.
load(); }
246 __inline
void store(Enum value) { this->m_enum.
store(value); }
253 #endif // P_STD_ATOMIC
277 #endif // PTLIB_CRITICALSECTION_H
__inline PAtomicEnum()
Definition: atomic.h:240
__inline PAtomicEnum(const PAtomicEnum &other)
Definition: atomic.h:242
long IntegerType
Definition: atomic.h:270
#define P_DEFINE_ATOMIC_INT_CLASS(Type, Exch, FetchAdd, AddFetch, CompExch)
Definition: atomic.h:106
__inline Enum operator=(const PAtomicEnum &other)
Definition: atomic.h:243
__inline PAtomicBoolean & operator=(bool value)
Definition: atomic.h:272
#define P_DEFINE_ATOMIC_PTR_CLASS(Exch, FetchAdd, AddFetch, CompExch)
Definition: atomic.h:112
void SetValue(IntegerType value)
Definition: atomic.h:262
__inline atomic(Type value)
Definition: atomic.h:46
__inline void store(Enum value)
Definition: atomic.h:246
__inline PAtomicInteger & operator=(IntegerType value)
Definition: atomic.h:261
__inline bool compare_exchange_strong(Enum &comp, Enum value)
Definition: atomic.h:248
__inline atomic & operator=(const atomic &other)
Definition: atomic.h:49
__inline bool IsZero() const
Definition: atomic.h:263
__inline void store(Type value)
Definition: atomic.h:52
long IntegerType
Definition: atomic.h:259
__inline PAtomicEnum(Enum value)
Definition: atomic.h:241
__inline Type exchange(Type value)
Definition: atomic.h:53
__inline atomic()
Definition: atomic.h:45
__inline Enum load() const
Definition: atomic.h:245
__inline Type load() const
Definition: atomic.h:51
PAtomicInteger(IntegerType value=0)
Definition: atomic.h:260
PAtomicBoolean(bool value=false)
Definition: atomic.h:271
__inline Enum exchange(Enum value)
Definition: atomic.h:247
__inline atomic(const atomic &other)
Definition: atomic.h:47
__inline ~atomic()
Definition: atomic.h:48
bool TestAndSet(bool value)
Definition: atomic.h:273
bool compare_exchange_strong(Type &comp, Type value)
Definition: atomic.h:54