diff options
author | Antonin Kral <a.kral@bobek.cz> | 2011-12-15 10:02:19 +0100 |
---|---|---|
committer | Antonin Kral <a.kral@bobek.cz> | 2011-12-15 10:02:46 +0100 |
commit | 0b48f8ada2acb0de830b23f8cefc8e3fea28d915 (patch) | |
tree | f7c2811269b6b53199412be2dd5ec02eea15d55d /util/concurrency/spin_lock.cpp | |
parent | 85f1cd56145b90a32b7ccdc750000deeed54fe22 (diff) | |
parent | f0d9a01bccdaeb466c12c92057914bbfef59526c (diff) | |
download | mongodb-0b48f8ada2acb0de830b23f8cefc8e3fea28d915.tar.gz |
Merge branch 'upstream/2.0.2'
Diffstat (limited to 'util/concurrency/spin_lock.cpp')
-rw-r--r-- | util/concurrency/spin_lock.cpp | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/util/concurrency/spin_lock.cpp b/util/concurrency/spin_lock.cpp index 1811f15..52bd218 100644 --- a/util/concurrency/spin_lock.cpp +++ b/util/concurrency/spin_lock.cpp @@ -45,7 +45,36 @@ namespace mongo { #if defined(_WIN32) EnterCriticalSection(&_cs); #elif defined(__USE_XOPEN2K) - pthread_spin_lock( &_lock ); + + /** + * this is designed to perform close to the default spin lock + * the reason for the mild insanity is to prevent horrible performance + * when contention spikes + * it allows spinlocks to be used in many more places + * which is good because even with this change they are about 8x faster on linux + */ + + if ( pthread_spin_trylock( &_lock ) == 0 ) + return; + + for ( int i=0; i<1000; i++ ) + if ( pthread_spin_trylock( &_lock ) == 0 ) + return; + + for ( int i=0; i<1000; i++ ) { + if ( pthread_spin_trylock( &_lock ) == 0 ) + return; + pthread_yield(); + } + + struct timespec t; + t.tv_sec = 0; + t.tv_nsec = 5000000; + + while ( pthread_spin_trylock( &_lock ) != 0 ) { + nanosleep(&t, NULL); + } + #elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) // fast path if (!_locked && !__sync_lock_test_and_set(&_locked, true)) { |