From 8a26ff4f8daffa350697d0267a24fd561fca9249 Mon Sep 17 00:00:00 2001 From: dwight Date: Sat, 28 Nov 2009 11:50:46 -0500 Subject: [PATCH] checkpoitn a little sync work --- db/concurrency.h | 75 +++++++++++++++++++++++++++++++++--------------- db/db.cpp | 11 ++++++- db/db.h | 8 ------ db/instance.cpp | 2 +- db/repl.cpp | 23 +++++++-------- 5 files changed, 74 insertions(+), 45 deletions(-) diff --git a/db/concurrency.h b/db/concurrency.h index 7120b2f8301..7ad5f18ab1f 100644 --- a/db/concurrency.h +++ b/db/concurrency.h @@ -13,8 +13,38 @@ #pragma once +#include + namespace mongo { +#if 0 + typedef boost::shared_mutex MongoMutex; +#else + /* this will be for old versions of boost */ + class MongoMutex { + boost::recursive_mutex m; + public: + void lock() { +#if BOOST_VERSION >= 103500 + m.lock(); +#else + boost::detail::thread::lock_ops::lock(m); +#endif + } + + void unlock() { +#if BOOST_VERSION >= 103500 + m.unlock(); +#else + boost::detail::thread::lock_ops::unlock(m); +#endif + } + + void lock_shared() { lock(); } + void unlock_shared() { unlock(); } + }; +#endif + /* mutex time stats */ class MutexInfo { unsigned long long start, enter, timeLocked; // all in microseconds @@ -45,9 +75,10 @@ namespace mongo { } }; - extern boost::recursive_mutex &dbMutex; + extern MongoMutex &dbMutex; extern MutexInfo dbMutexInfo; +/* struct lock { recursive_boostlock bl_; MutexInfo& info_; @@ -60,46 +91,43 @@ namespace mongo { info_.leaving(); } }; +*/ void dbunlocking_write(); void dbunlocking_read(); - /* use writelock and readlock instead */ - struct dblock : public lock { - dblock() : - lock( dbMutex, dbMutexInfo ) { - } - ~dblock() { - dbunlocking_write(); - } - }; - - struct writelock : public lock { - writelock(const string& ns) : - lock( dbMutex, dbMutexInfo ) { - } - writelock(const char * ns) : - lock( dbMutex, dbMutexInfo ) { + struct writelock { + writelock(const string& ns) { + dbMutex.lock(); + dbMutexInfo.entered(); } ~writelock() { dbunlocking_write(); + dbMutexInfo.leaving(); + dbMutex.unlock(); } }; - struct readlock : public lock { - readlock(const string& ns) : - lock( dbMutex, dbMutexInfo ) { - } - readlock(const char* ns) : - lock( dbMutex, dbMutexInfo ) { + struct readlock { + readlock(const string& ns) { + dbMutex.lock_shared(); } ~readlock() { dbunlocking_read(); + dbMutex.unlock_shared(); + } + }; + + /* use writelock and readlock instead */ + struct dblock : public writelock { + dblock() : writelock("") { } + ~dblock() { } }; /* a scoped release of a mutex temporarily -- like a scopedlock but reversed. */ +/* struct temprelease { boost::mutex& m; temprelease(boost::mutex& _m) : m(_m) { @@ -117,6 +145,7 @@ namespace mongo { #endif } }; +*/ inline void assertInWriteLock() { assert( dbMutexInfo.isLocked() ); diff --git a/db/db.cpp b/db/db.cpp index 34813560ca0..1f984c444b4 100644 --- a/db/db.cpp +++ b/db/db.cpp @@ -388,7 +388,7 @@ namespace mongo { sleepsecs(5); continue; } - sleepmillis( _sleepsecs * 1000 ); + sleepmillis( (int)(_sleepsecs * 1000) ); MemoryMappedFile::flushAll( false ); log(1) << "flushing mmmap" << endl; } @@ -1043,7 +1043,16 @@ BOOL CtrlHandler( DWORD fdwCtrlType ) } #endif +void temptestfoo() { + MongoMutex m; + m.lock(); +// m.lock_upgrade(); + m.lock_shared(); +} + + } // namespace mongo #include "recstore.h" #include "reccache.h" + diff --git a/db/db.h b/db/db.h index ccd69e677fd..d1d15de7f7d 100644 --- a/db/db.h +++ b/db/db.h @@ -120,18 +120,10 @@ namespace mongo { } client.top.clientStop(); dbMutexInfo.leaving(); -#if BOOST_VERSION >= 103500 dbMutex.unlock(); -#else - boost::detail::thread::lock_ops::unlock(dbMutex); -#endif } ~dbtemprelease() { -#if BOOST_VERSION >= 103500 dbMutex.lock(); -#else - boost::detail::thread::lock_ops::lock(dbMutex); -#endif dbMutexInfo.entered(); if ( clientname.empty() ) cc().setns("", 0); diff --git a/db/instance.cpp b/db/instance.cpp index 309500a8b1b..faca25035b6 100644 --- a/db/instance.cpp +++ b/db/instance.cpp @@ -49,7 +49,7 @@ namespace mongo { bool autoresync = false; /* we use new here so we don't have to worry about destructor orders at program shutdown */ - boost::recursive_mutex &dbMutex( *(new boost::recursive_mutex) ); + MongoMutex &dbMutex( *(new MongoMutex) ); MutexInfo dbMutexInfo; string dbExecCommand; diff --git a/db/repl.cpp b/db/repl.cpp index 8c66335dad1..27bb2fb470b 100644 --- a/db/repl.cpp +++ b/db/repl.cpp @@ -48,7 +48,6 @@ namespace mongo { - extern boost::recursive_mutex &dbMutex; void ensureHaveIdIndex(const char *ns); /* if 1 sync() is running */ @@ -1213,17 +1212,17 @@ namespace mongo { time_t saveLast = time(0); while ( 1 ) { /* from a.s.: - I think the idea here is that we can establish a sync point between the local op log and the remote log with the following steps: - - 1) identify most recent op in local log -- call it O - 2) ask "does nextOpTime reflect the tail of the remote op log?" (in other words, is more() false?) - If yes, all subsequent ops after nextOpTime in the remote log must have occurred after O. If no, we can't establish a sync point. - - Note that we can't do step (2) followed by step (1) because if we do so ops may be added to both machines between steps (2) and (1) and we can't establish a sync point. (In particular, between (2) and (1) an op may be added to the remote log before a different op is added to the local log. In this case, the newest remote op will have occurred after nextOpTime but before O.) - - Now, for performance reasons we don't want to have to identify the most recent op in the local log every time we call c->more() because in performance sensitive situations more() will be true most of the time. So we do: - - 0) more()? - 1) find most recent op in local log + I think the idea here is that we can establish a sync point between the local op log and the remote log with the following steps: + + 1) identify most recent op in local log -- call it O + 2) ask "does nextOpTime reflect the tail of the remote op log?" (in other words, is more() false?) - If yes, all subsequent ops after nextOpTime in the remote log must have occurred after O. If no, we can't establish a sync point. + + Note that we can't do step (2) followed by step (1) because if we do so ops may be added to both machines between steps (2) and (1) and we can't establish a sync point. (In particular, between (2) and (1) an op may be added to the remote log before a different op is added to the local log. In this case, the newest remote op will have occurred after nextOpTime but before O.) + + Now, for performance reasons we don't want to have to identify the most recent op in the local log every time we call c->more() because in performance sensitive situations more() will be true most of the time. So we do: + + 0) more()? + 1) find most recent op in local log 2) more()? */ if ( !c->more() ) {