Skip to content

Commit

Permalink
Merge branch 'master' of github.com:mongodb/mongo
Browse files Browse the repository at this point in the history
  • Loading branch information
dwight committed Oct 14, 2011
2 parents 44115bd + 92624b2 commit 127251f
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 36 deletions.
43 changes: 10 additions & 33 deletions util/concurrency/spin_lock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "pch.h"
#include "pch.h" // todo eliminate this include
#include <time.h>
#include "spin_lock.h"

Expand All @@ -41,11 +41,8 @@ namespace mongo {
: _mutex( "SpinLock" ) { }
#endif

void SpinLock::lock() {
#if defined(_WIN32)
EnterCriticalSection(&_cs);
#elif defined(__USE_XOPEN2K)

#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
Expand All @@ -54,12 +51,11 @@ namespace mongo {
* 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++ )
for ( int i=0; i<1000; i++ ) {
if ( pthread_spin_trylock( &_lock ) == 0 )
return;
asm volatile ( "pause" ) ; // maybe trylock does this; just in case.
}

for ( int i=0; i<1000; i++ ) {
if ( pthread_spin_trylock( &_lock ) == 0 )
Expand All @@ -74,8 +70,10 @@ namespace mongo {
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;
Expand All @@ -94,32 +92,11 @@ namespace mongo {
while (__sync_lock_test_and_set(&_locked, true)) {
nanosleep(&t, NULL);
}
#else
// WARNING Missing spin lock in this platform. This can potentially
// be slow.
_mutex.lock();

#endif
}

void SpinLock::unlock() {
#if defined(_WIN32)
LeaveCriticalSection(&_cs);
#elif defined(__USE_XOPEN2K)
pthread_spin_unlock(&_lock);
#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
__sync_lock_release(&_locked);
#else
_mutex.unlock();
#endif
}

bool SpinLock::isfast() {
#if defined(_WIN32)
return true;
#elif defined(__USE_XOPEN2K)
return true;
#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
#if defined(_WIN32) || defined(__USE_XOPEN2K) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
return true;
#else
return false;
Expand Down
20 changes: 17 additions & 3 deletions util/concurrency/spin_lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,35 @@ namespace mongo {
SpinLock();
~SpinLock();

void lock();
void unlock();

static bool isfast(); // true if a real spinlock on this platform

private:
#if defined(_WIN32)
CRITICAL_SECTION _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 ( pthread_spin_trylock( &_lock ) == 0 )
return;
_lk();
}
#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
volatile bool _locked;
public:
void unlock() {__sync_lock_release(&_locked); }
void lock();
#else
// default to a mutex if not implemented
SimpleMutex _mutex;
public:
void unlock() { _mutex.unlock(); }
void lock() { _mutex.lock(); }
#endif
};

Expand Down

0 comments on commit 127251f

Please sign in to comment.