diff options
Diffstat (limited to 'src/mongo/util/concurrency/spin_lock.h')
-rw-r--r-- | src/mongo/util/concurrency/spin_lock.h | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/mongo/util/concurrency/spin_lock.h b/src/mongo/util/concurrency/spin_lock.h new file mode 100644 index 00000000000..d90de51afac --- /dev/null +++ b/src/mongo/util/concurrency/spin_lock.h @@ -0,0 +1,77 @@ +// spin_lock.h + +/** +* Copyright (C) 2008 10gen Inc. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License, version 3, +* as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#pragma once + +#include "mutex.h" + +namespace mongo { + + /** + * The spinlock currently requires late GCC support routines to be efficient. + * Other platforms default to a mutex implemenation. + */ + class SpinLock : boost::noncopyable { + public: + SpinLock(); + ~SpinLock(); + + 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 + }; + + class scoped_spinlock : boost::noncopyable { + public: + scoped_spinlock( SpinLock& l ) : _l(l) { + _l.lock(); + } + ~scoped_spinlock() { + _l.unlock();} + private: + SpinLock& _l; + }; + +} // namespace mongo |