summaryrefslogtreecommitdiff
path: root/src/mongo/util/concurrency/spin_lock.h
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2015-11-19 09:54:14 -0500
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2015-11-19 09:54:14 -0500
commit3f598f1edc57ca0b863b58009e7cca9a986d4da7 (patch)
tree62517780ad0982ec80b8a6d968a72cf0474df617 /src/mongo/util/concurrency/spin_lock.h
parent30458a9c6160b01925a8bdd768deb98ed8da8cb0 (diff)
downloadmongo-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.h86
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