summaryrefslogtreecommitdiff
path: root/dbtests/threadedtests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dbtests/threadedtests.cpp')
-rw-r--r--dbtests/threadedtests.cpp85
1 files changed, 85 insertions, 0 deletions
diff --git a/dbtests/threadedtests.cpp b/dbtests/threadedtests.cpp
index 3a5ee10..cdee052 100644
--- a/dbtests/threadedtests.cpp
+++ b/dbtests/threadedtests.cpp
@@ -544,6 +544,15 @@ namespace ThreadedTests {
};
#endif
+ void sleepalittle() {
+ Timer t;
+ while( 1 ) {
+ boost::this_thread::yield();
+ if( t.micros() > 8 )
+ break;
+ }
+ }
+
class WriteLocksAreGreedy : public ThreadedTest<3> {
public:
WriteLocksAreGreedy() : m("gtest") {}
@@ -579,6 +588,81 @@ namespace ThreadedTests {
}
};
+ // Tests waiting on the TicketHolder by running many more threads than can fit into the "hotel", but only
+ // max _nRooms threads should ever get in at once
+ class TicketHolderWaits : public ThreadedTest<10> {
+
+ static const int checkIns = 1000;
+ static const int rooms = 3;
+
+ public:
+ TicketHolderWaits() : _hotel( rooms ), _tickets( _hotel._nRooms ) {}
+
+ private:
+
+ class Hotel {
+ public:
+ Hotel( int nRooms ) : _frontDesk( "frontDesk" ), _nRooms( nRooms ), _checkedIn( 0 ), _maxRooms( 0 ) {}
+
+ void checkIn(){
+ scoped_lock lk( _frontDesk );
+ _checkedIn++;
+ assert( _checkedIn <= _nRooms );
+ if( _checkedIn > _maxRooms ) _maxRooms = _checkedIn;
+ }
+
+ void checkOut(){
+ scoped_lock lk( _frontDesk );
+ _checkedIn--;
+ assert( _checkedIn >= 0 );
+ }
+
+ mongo::mutex _frontDesk;
+ int _nRooms;
+ int _checkedIn;
+ int _maxRooms;
+ };
+
+ Hotel _hotel;
+ TicketHolder _tickets;
+
+ virtual void subthread(int x) {
+
+ string threadName = ( str::stream() << "ticketHolder" << x );
+ Client::initThread( threadName.c_str() );
+
+ for( int i = 0; i < checkIns; i++ ){
+
+ _tickets.waitForTicket();
+ TicketHolderReleaser whenDone( &_tickets );
+
+ _hotel.checkIn();
+
+ sleepalittle();
+ if( i == checkIns - 1 ) sleepsecs( 2 );
+
+ _hotel.checkOut();
+
+ if( ( i % ( checkIns / 10 ) ) == 0 )
+ log() << "checked in " << i << " times..." << endl;
+
+ }
+
+ cc().shutdown();
+
+ }
+
+ virtual void validate() {
+
+ // This should always be true, assuming that it takes < 1 sec for the hardware to process a check-out/check-in
+ // Time for test is then ~ #threads / _nRooms * 2 seconds
+ assert( _hotel._maxRooms == _hotel._nRooms );
+
+ }
+
+ };
+
+
class All : public Suite {
public:
All() : Suite( "threading" ) { }
@@ -600,6 +684,7 @@ namespace ThreadedTests {
add< RWLockTest4 >();
add< MongoMutexTest >();
+ add< TicketHolderWaits >();
}
} myall;
}