summaryrefslogtreecommitdiff
path: root/src/mongo/util/concurrency/spin_lock.cpp
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2015-11-19 09:49:52 -0500
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2015-11-19 09:50:06 -0500
commit30458a9c6160b01925a8bdd768deb98ed8da8cb0 (patch)
tree7973db9fd1b442d71b8cbb7a97b45ec4c98a94ac /src/mongo/util/concurrency/spin_lock.cpp
parenta0771ea5ec1b44537d3c409e3d712db24fd8e6bb (diff)
downloadmongo-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.cpp72
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