0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00
This commit is contained in:
Dwight 2009-08-25 16:14:55 -04:00
parent f42a88c9a9
commit 6a8b0363d9
8 changed files with 101 additions and 102 deletions

View File

@ -87,7 +87,7 @@ namespace mongo {
/* called every 4 seconds. millis is amount of idle time passed since the last call -- could be zero */
void idleTimeReport(unsigned millis) {
assert( dbMutexInfo.isLocked() );
requireInWriteLock();
for ( ByLoc::iterator i = byLoc.begin(); i != byLoc.end(); ) {
ByLoc::iterator j = i;
i++;
@ -117,7 +117,7 @@ namespace mongo {
if ( j == stop )
return;
assert( dbMutexInfo.isLocked() );
requireInWriteLock();
vector<ClientCursor*> toAdvance;
while ( 1 ) {

View File

@ -7,9 +7,87 @@
namespace mongo {
inline void requireInWriteLock() {
assert( dbMutexInfo.isLocked() );
}
/* mutex time stats */
class MutexInfo {
unsigned long long start, enter, timeLocked; // all in microseconds
int locked;
public:
MutexInfo() : locked(0) {
start = curTimeMicros64();
}
void entered() {
if ( locked == 0 )
enter = curTimeMicros64();
locked++;
assert( locked >= 1 );
}
void leaving() {
locked--;
assert( locked >= 0 );
if ( locked == 0 )
timeLocked += curTimeMicros64() - enter;
}
int isLocked() const {
return locked;
}
void timingInfo(unsigned long long &s, unsigned long long &tl) {
s = start;
tl = timeLocked;
}
};
extern boost::recursive_mutex &dbMutex;
extern MutexInfo dbMutexInfo;
struct lock {
recursive_boostlock bl_;
MutexInfo& info_;
lock( boost::recursive_mutex &mutex, MutexInfo &info ) :
bl_( mutex ),
info_( info ) {
info_.entered();
}
~lock() {
info_.leaving();
}
};
void dbunlocking();
struct dblock : public lock {
dblock() :
lock( dbMutex, dbMutexInfo ) {
}
~dblock() {
/* todo: this should be inlined */
dbunlocking();
Top::clientStop();
}
};
/* a scoped release of a mutex temporarily -- like a scopedlock but reversed.
*/
struct temprelease {
boost::mutex& m;
temprelease(boost::mutex& _m) : m(_m) {
#if BOOST_VERSION >= 103500
m.unlock();
#else
boost::detail::thread::lock_ops<boost::mutex>::unlock(m);
#endif
}
~temprelease() {
#if BOOST_VERSION >= 103500
m.lock();
#else
boost::detail::thread::lock_ops<boost::mutex>::lock(m);
#endif
}
};
inline void requireInWriteLock() {
assert( dbMutexInfo.isLocked() );
}
}

95
db/db.h
View File

@ -19,101 +19,14 @@
#include "../stdafx.h"
#include "../util/message.h"
#include "../util/top.h"
#include "boost/version.hpp"
#include "concurrency.h"
#include "pdfile.h"
namespace mongo {
void jniCallback(Message& m, Message& out);
class MutexInfo {
unsigned long long start, enter, timeLocked; // all in microseconds
int locked;
public:
MutexInfo() : locked(0) {
start = curTimeMicros64();
}
void entered() {
if ( locked == 0 )
enter = curTimeMicros64();
locked++;
assert( locked >= 1 );
}
void leaving() {
locked--;
assert( locked >= 0 );
if ( locked == 0 )
timeLocked += curTimeMicros64() - enter;
}
int isLocked() const {
return locked;
}
void timingInfo(unsigned long long &s, unsigned long long &tl) {
s = start;
tl = timeLocked;
}
};
extern boost::recursive_mutex &dbMutex;
extern MutexInfo dbMutexInfo;
struct lock {
recursive_boostlock bl_;
MutexInfo& info_;
lock( boost::recursive_mutex &mutex, MutexInfo &info ) :
bl_( mutex ),
info_( info ) {
info_.entered();
}
~lock() {
info_.leaving();
}
};
void dbunlocking();
struct dblock : public lock {
dblock() :
lock( dbMutex, dbMutexInfo ) {
}
~dblock() {
/* todo: this should be inlined */
dbunlocking();
Top::clientStop();
}
};
} // namespace mongo
#include "boost/version.hpp"
namespace mongo {
/* a scoped release of a mutex temporarily -- like a scopedlock but reversed.
*/
struct temprelease {
boost::mutex& m;
temprelease(boost::mutex& _m) : m(_m) {
#if BOOST_VERSION >= 103500
m.unlock();
#else
boost::detail::thread::lock_ops<boost::mutex>::unlock(m);
#endif
}
~temprelease() {
#if BOOST_VERSION >= 103500
m.lock();
#else
boost::detail::thread::lock_ops<boost::mutex>::lock(m);
#endif
}
};
} // namespace mongo
#include "pdfile.h"
namespace mongo {
// tempish...move to TLS or pass all the way down as a parm
extern map<string,Database*> databases;
extern Database *database;
@ -131,7 +44,7 @@ namespace mongo {
/* we must be in critical section at this point as these are global
variables.
*/
assert( dbMutexInfo.isLocked() );
requireInWriteLock();
log( 5 ) << "setClient: " << ns << endl;

View File

@ -379,6 +379,15 @@ namespace mongo {
}
} cmdProfile;
/*
> db.$cmd.findOne({timeinfo:1})
{
"totalTime" : 1.33875E8 ,
"lockTime" : 765625.0 ,
"ratio" : 0.005718954248366013 ,
"ok" : 1.0
}
*/
class CmdTimeInfo : public Command {
public:
virtual bool slaveOk() {

View File

@ -49,9 +49,9 @@ namespace mongo {
extern int curOp;
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) );
MutexInfo dbMutexInfo;
//int dbLocked = 0;
string dbExecCommand;

View File

@ -221,7 +221,7 @@ inline void RecCache::writeIfDirty(Node *n) {
}
void RecCache::closeFiles(string dbname, string path) {
dassert( dbMutexInfo.isLocked() );
requireInWriteLock();
boostlock lk(rcmutex);
// first we write all dirty pages. it is not easy to check which Nodes are for a particular

View File

@ -224,7 +224,6 @@ public:
};
inline void dbunlocking() {
// dassert( dbMutexInfo.isLocked() );
theRecCache.ejectOld();
}

View File

@ -45,11 +45,11 @@ namespace mongo {
virtual ~AuthenticationInfo() {
}
void logout(const char *dbname) {
assert( dbMutexInfo.isLocked() );
requireInWriteLock();
m.erase(dbname);
}
void authorize(const char *dbname) {
assert( dbMutexInfo.isLocked() );
requireInWriteLock();
m[dbname].level = 2;
}
virtual bool isAuthorized(const char *dbname) {