diff options
author | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2015-11-19 09:49:52 -0500 |
---|---|---|
committer | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2015-11-19 09:50:06 -0500 |
commit | 30458a9c6160b01925a8bdd768deb98ed8da8cb0 (patch) | |
tree | 7973db9fd1b442d71b8cbb7a97b45ec4c98a94ac /src/mongo/util/concurrency/spin_lock.cpp | |
parent | a0771ea5ec1b44537d3c409e3d712db24fd8e6bb (diff) | |
download | mongo-30458a9c6160b01925a8bdd768deb98ed8da8cb0.tar.gz |
Revert "SERVER-21542 Optimize spinlock on non-windows systems"
This reverts commit 18600ed909f739ab1bc3032c2a230aeac1abe1c2.
Diffstat (limited to 'src/mongo/util/concurrency/spin_lock.cpp')
-rw-r--r-- | src/mongo/util/concurrency/spin_lock.cpp | 72 |
1 files changed, 64 insertions, 8 deletions
diff --git a/src/mongo/util/concurrency/spin_lock.cpp b/src/mongo/util/concurrency/spin_lock.cpp index 7f01b9d491b..cb66ad2abc5 100644 --- a/src/mongo/util/concurrency/spin_lock.cpp +++ b/src/mongo/util/concurrency/spin_lock.cpp @@ -27,20 +27,45 @@ * then also delete it in the license file. */ -#if !defined(_WIN32) - #include "mongo/platform/basic.h" +#undef MONGO_PCH_WHITELISTED // todo eliminate this include #include "mongo/util/concurrency/spin_lock.h" #include <sched.h> #include <time.h> +#include "mongo/bson/inline_decls.h" namespace mongo { +SpinLock::~SpinLock() { +#if defined(_WIN32) + DeleteCriticalSection(&_cs); +#elif defined(__USE_XOPEN2K) + pthread_spin_destroy(&_lock); +#endif +} + +SpinLock::SpinLock() +#if defined(_WIN32) +{ + InitializeCriticalSectionAndSpinCount(&_cs, 4000); +} +#elif defined(__USE_XOPEN2K) +{ + pthread_spin_init(&_lock, 0); +} +#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) + : _locked(false) { +} +#else + : _mutex("SpinLock") { +} +#endif -void SpinLock::_lockSlowPath() { +#if defined(__USE_XOPEN2K) +NOINLINE_DECL void SpinLock::_lk() { /** * this is designed to perform close to the default spin lock * the reason for the mild insanity is to prevent horrible performance @@ -50,15 +75,15 @@ void SpinLock::_lockSlowPath() { */ for (int i = 0; i < 1000; i++) { - if (_tryLock()) + if (pthread_spin_trylock(&_lock) == 0) return; #if defined(__i386__) || defined(__x86_64__) - asm volatile("pause"); + asm volatile("pause"); // maybe trylock does this; just in case. #endif } for (int i = 0; i < 1000; i++) { - if (_tryLock()) + if (pthread_spin_trylock(&_lock) == 0) return; sched_yield(); } @@ -67,11 +92,42 @@ void SpinLock::_lockSlowPath() { t.tv_sec = 0; t.tv_nsec = 5000000; - while (!_tryLock()) { + while (pthread_spin_trylock(&_lock) != 0) { nanosleep(&t, NULL); } } +#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) +void SpinLock::lock() { + // fast path + if (!_locked && !__sync_lock_test_and_set(&_locked, true)) { + return; + } -} // namespace mongo + // wait for lock + int wait = 1000; + while ((wait-- > 0) && (_locked)) { +#if defined(__i386__) || defined(__x86_64__) + asm volatile("pause"); +#endif + } + + // if failed to grab lock, sleep + struct timespec t; + t.tv_sec = 0; + t.tv_nsec = 5000000; + while (__sync_lock_test_and_set(&_locked, true)) { + nanosleep(&t, NULL); + } +} +#endif +bool SpinLock::isfast() { +#if defined(_WIN32) || defined(__USE_XOPEN2K) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) + return true; +#else + return false; #endif +} + + +} // namespace mongo |