diff --git a/src/common/classes/alloc.cpp b/src/common/classes/alloc.cpp index 17719f471e..f7b8014818 100644 --- a/src/common/classes/alloc.cpp +++ b/src/common/classes/alloc.cpp @@ -1176,7 +1176,7 @@ void MemoryPool::deletePool(MemoryPool* pool) pool->decrement_mapping(pool->mapped_memory); // Free mutex - pool->lock.~Mutex(); + pool->lock.~Spinlock(); // Order of deallocation is of significance because // we delete our pool in process diff --git a/src/common/classes/alloc.h b/src/common/classes/alloc.h index 439124f44c..5b9e50998d 100644 --- a/src/common/classes/alloc.h +++ b/src/common/classes/alloc.h @@ -225,7 +225,7 @@ private: // accounted locally, i.e. redirect_amount and parent_redirected linked list // are synchronized with parent pool mutex only. All other pool members are // synchronized with this mutex. - Mutex lock; + Spinlock lock; // Current usage counters for pool. Used to move pool to different statistics group AtomicCounter used_memory; diff --git a/src/common/classes/locks.cpp b/src/common/classes/locks.cpp index ed15201b0e..b790a26066 100644 --- a/src/common/classes/locks.cpp +++ b/src/common/classes/locks.cpp @@ -36,10 +36,9 @@ namespace Firebird { #define INIT_SPIN_COUNT ((tSetCriticalSectionSpinCount *)(0)) tSetCriticalSectionSpinCount* - Mutex::SetCriticalSectionSpinCount = INIT_SPIN_COUNT; + Spinlock::SetCriticalSectionSpinCount = INIT_SPIN_COUNT; -Mutex::Mutex() { - InitializeCriticalSection(&spinlock); +Spinlock::Spinlock() { if (SetCriticalSectionSpinCount == MISS_SPIN_COUNT) return; if (SetCriticalSectionSpinCount == INIT_SPIN_COUNT) { diff --git a/src/common/classes/locks.h b/src/common/classes/locks.h index 213af10958..69841b2218 100644 --- a/src/common/classes/locks.h +++ b/src/common/classes/locks.h @@ -51,29 +51,39 @@ namespace Firebird { #ifdef MULTI_THREAD #ifdef WIN_NT -// Process-local spinlock. Used to manage memory heaps in threaded environment. +// Generic process-local mutex and spinlock. The latter +// is used to manage memory heaps in a threaded environment. + // Windows version of the class +class Mutex { +protected: + CRITICAL_SECTION spinlock; +public: + Mutex() { + InitializeCriticalSection(&spinlock); + } + virtual ~Mutex() { + DeleteCriticalSection(&spinlock); + } + virtual void enter() { + EnterCriticalSection(&spinlock); + } + virtual void leave() { + LeaveCriticalSection(&spinlock); + } +}; + typedef WINBASEAPI DWORD WINAPI tSetCriticalSectionSpinCount ( LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount ); -class Mutex { +class Spinlock : public Mutex { private: - CRITICAL_SECTION spinlock; static tSetCriticalSectionSpinCount* SetCriticalSectionSpinCount; public: - Mutex(); - ~Mutex() { - DeleteCriticalSection(&spinlock); - } - void enter() { - EnterCriticalSection(&spinlock); - } - void leave() { - LeaveCriticalSection(&spinlock); - } + Spinlock(); }; #else //WIN_NT @@ -102,6 +112,8 @@ public: } }; +typedef Mutex Spinlock; + #else //SOLARIS_MT // Pthreads version of the class @@ -127,6 +139,28 @@ public: } }; +class Spinlock { +private: + pthread_spinlock_t spinlock; +public: + Spinlock() { + if (pthread_spin_init(&spinlock, false)) + system_call_failed::raise("pthread_spin_init"); + } + ~Spinlock() { + if (pthread_spin_destroy(&spinlock)) + system_call_failed::raise("pthread_spin_destroy"); + } + void enter() { + if (pthread_spin_lock(&spinlock)) + system_call_failed::raise("pthread_spin_lock"); + } + void leave() { + if (pthread_spin_unlock(&spinlock)) + system_call_failed::raise("pthread_spin_unlock"); + } +}; + #endif //SOLARIS_MT #endif //WIN_NT @@ -146,6 +180,8 @@ public: } }; +typedef Mutex Spinlock; + #endif //MULTI_THREAD // RAII holder of mutex lock