diff options
author | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2015-11-19 09:54:14 -0500 |
---|---|---|
committer | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2015-11-19 09:54:14 -0500 |
commit | 3f598f1edc57ca0b863b58009e7cca9a986d4da7 (patch) | |
tree | 62517780ad0982ec80b8a6d968a72cf0474df617 /src/mongo/util/concurrency/spin_lock.h | |
parent | 30458a9c6160b01925a8bdd768deb98ed8da8cb0 (diff) | |
download | mongo-3f598f1edc57ca0b863b58009e7cca9a986d4da7.tar.gz |
SERVER-21542 Optimize spinlock on non-windows systems
This reverts commit 30458a9c6160b01925a8bdd768deb98ed8da8cb0.
Diffstat (limited to 'src/mongo/util/concurrency/spin_lock.h')
-rw-r--r-- | src/mongo/util/concurrency/spin_lock.h | 86 |
1 files changed, 37 insertions, 49 deletions
diff --git a/src/mongo/util/concurrency/spin_lock.h b/src/mongo/util/concurrency/spin_lock.h index e56458d6cf8..9e4b707f160 100644 --- a/src/mongo/util/concurrency/spin_lock.h +++ b/src/mongo/util/concurrency/spin_lock.h @@ -32,84 +32,72 @@ #ifdef _WIN32 #include "mongo/platform/windows_basic.h" +#else +#include <atomic> #endif -#include "mutex.h" +#include "mongo/base/disallow_copying.h" +#include "mongo/platform/compiler.h" +#include "mongo/stdx/mutex.h" namespace mongo { -/** - * The spinlock currently requires late GCC support routines to be efficient. - * Other platforms default to a mutex implemenation. - */ +#if defined(_WIN32) class SpinLock { MONGO_DISALLOW_COPYING(SpinLock); public: - SpinLock(); - ~SpinLock(); - - static bool isfast(); // true if a real spinlock on this platform + SpinLock() { + InitializeCriticalSectionAndSpinCount(&_cs, 4000); + } -private: -#if defined(_WIN32) - CRITICAL_SECTION _cs; + ~SpinLock() { + DeleteCriticalSection(&_cs); + } -public: void lock() { EnterCriticalSection(&_cs); } + void unlock() { LeaveCriticalSection(&_cs); } -#elif defined(__USE_XOPEN2K) - pthread_spinlock_t _lock; - void _lk(); -public: - void unlock() { - pthread_spin_unlock(&_lock); - } - void lock() { - if (MONGO_likely(pthread_spin_trylock(&_lock) == 0)) - return; - _lk(); - } -#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) - volatile bool _locked; +private: + CRITICAL_SECTION _cs; +}; -public: - void unlock() { - __sync_lock_release(&_locked); - } - void lock(); #else - // default to a mutex if not implemented - SimpleMutex _mutex; + +class SpinLock { + MONGO_DISALLOW_COPYING(SpinLock); public: + SpinLock() = default; + void unlock() { - _mutex.unlock(); + _locked.clear(std::memory_order_release); } + void lock() { - _mutex.lock(); + if (MONGO_likely(_tryLock())) + return; + _lockSlowPath(); } -#endif -}; - -class scoped_spinlock { - MONGO_DISALLOW_COPYING(scoped_spinlock); -public: - scoped_spinlock(SpinLock& l) : _l(l) { - _l.lock(); - } - ~scoped_spinlock() { - _l.unlock(); +private: + bool _tryLock() { + bool wasLocked = _locked.test_and_set(std::memory_order_acquire); + return !wasLocked; } -private: - SpinLock& _l; + void _lockSlowPath(); + + // Initializes to the cleared state. + std::atomic_flag _locked = ATOMIC_FLAG_INIT; // NOLINT }; +#endif + +using scoped_spinlock = stdx::lock_guard<SpinLock>; } // namespace mongo |