diff options
Diffstat (limited to 'dbtests/spin_lock_test.cpp')
-rw-r--r-- | dbtests/spin_lock_test.cpp | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/dbtests/spin_lock_test.cpp b/dbtests/spin_lock_test.cpp new file mode 100644 index 0000000..d053d61 --- /dev/null +++ b/dbtests/spin_lock_test.cpp @@ -0,0 +1,115 @@ +// spin_lock_test.cpp : spin_lcok.{h, cpp} unit test + +/** + * Copyright (C) 2010 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/>. + */ + +#include "../pch.h" +#include <boost/thread/thread.hpp> + +#include "dbtests.h" +#include "../util/concurrency/spin_lock.h" + +namespace { + + using mongo::SpinLock; + + class LockTester{ + public: + LockTester( SpinLock* spin, int* counter ) + : _spin(spin), _counter(counter), _requests(0){} + + ~LockTester(){ + delete _t; + } + + void start( int increments ){ + _t = new boost::thread( boost::bind(&LockTester::test, this, increments) ); + } + + void join(){ + if ( _t ) _t->join(); + } + + int requests() const{ + return _requests; + } + + private: + SpinLock* _spin; // not owned here + int* _counter; // not owned here + int _requests; + boost::thread* _t; + + void test( int increments ){ + while ( increments-- > 0 ) { + _spin->lock(); + ++(*_counter); + ++_requests; + _spin->unlock(); + } + } + + LockTester( LockTester& ); + LockTester& operator=( LockTester& ); + }; + + class ConcurrentIncs{ + public: + void run(){ + +#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) + + SpinLock spin; + int counter = 0; + + const int threads = 64; + const int incs = 10000; + LockTester* testers[threads]; + + for ( int i = 0; i < threads; i++ ){ + testers[i] = new LockTester( &spin, &counter ); + } + for ( int i = 0; i < threads; i++ ){ + testers[i]->start( incs ); + } + for ( int i = 0; i < threads; i++ ){ + testers[i]->join(); + ASSERT_EQUALS( testers[i]->requests(), incs ); + delete testers[i]; + } + + ASSERT_EQUALS( counter, threads*incs ); +#else + + // WARNING "TODO Missing spin lock in this platform." + ASSERT( true ); + + +#endif + + } + }; + + class SpinLockSuite : public Suite{ + public: + SpinLockSuite() : Suite( "spinlock" ){} + + void setupTests(){ + add< ConcurrentIncs >(); + } + } spinLockSuite; + +} // anonymous namespace |