diff options
author | Dwight <dmerriman@gmail.com> | 2009-10-14 15:48:13 -0400 |
---|---|---|
committer | Dwight <dmerriman@gmail.com> | 2009-10-14 15:48:13 -0400 |
commit | c43df1e5757f586202db6ddc957476e2a69cca09 (patch) | |
tree | 774678c307bfe4243936535601bb86b4740bee04 /util | |
parent | 41afc73c9c1399a946f579894ed795c89daeff25 (diff) | |
download | mongo-c43df1e5757f586202db6ddc957476e2a69cca09.tar.gz |
make Top threadsafe
Diffstat (limited to 'util')
-rw-r--r-- | util/top.h | 64 | ||||
-rw-r--r-- | util/util.cpp | 5 |
2 files changed, 49 insertions, 20 deletions
diff --git a/util/top.h b/util/top.h index ed319ece997..b115388d5f3 100644 --- a/util/top.h +++ b/util/top.h @@ -17,34 +17,61 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#pragma once + #include <boost/date_time/posix_time/posix_time.hpp> namespace mongo { -// Records per namespace utilization of the mongod process. -// No two functions of this class may be called concurrently. +/* Records per namespace utilization of the mongod process. + No two functions of this class may be called concurrently. +*/ class Top { -public: typedef boost::posix_time::ptime T; typedef boost::posix_time::time_duration D; - static void clientStart( const char *client ) { +public: + Top() : read_(false), write_(false) { } + + /* these are used to record activity: */ + + void clientStart( const char *client ) { clientStop(); currentStart_ = currentTime(); current_ = client; } - static void setRead() { read_ = true; } - static void setWrite() { write_ = true; } - static void clientStop() { + + /* indicate current request is a read operation. */ + void setRead() { read_ = true; } + + void setWrite() { write_ = true; } + + void clientStop() { if ( currentStart_ == T() ) return; D d = currentTime() - currentStart_; - recordUsage( current_, d ); + + { + boostlock L(topMutex); + recordUsage( current_, d ); + } + currentStart_ = T(); read_ = false; write_ = false; } - struct Usage { string ns; D time; double pct; int reads; int writes; int calls; }; + + /* these are used to fetch the stats: */ + + struct Usage { + string ns; + D time; + double pct; + int reads, writes, calls; + }; + static void usage( vector< Usage > &res ) { + boostlock L(topMutex); + // Populate parent namespaces UsageMap snapshot; UsageMap totalUsage; @@ -79,7 +106,10 @@ public: res.push_back( u ); } } + static void completeSnapshot() { + boostlock L(topMutex); + if ( &snapshot_ == &snapshotA_ ) { snapshot_ = snapshotB_; nextSnapshot_ = snapshotA_; @@ -91,7 +121,9 @@ public: snapshotStart_ = currentTime(); nextSnapshot_.clear(); } + private: + static boost::mutex topMutex; static bool trivialNs( const char *ns ) { const char *ret = strrchr( ns, '.' ); return ret && ret[ 1 ] == '\0'; @@ -100,11 +132,11 @@ private: static T currentTime() { return boost::posix_time::microsec_clock::universal_time(); } - static void recordUsage( const string &client, D duration ) { + void recordUsage( const string &client, D duration ) { recordUsageForMap( totalUsage_, client, duration ); recordUsageForMap( nextSnapshot_, client, duration ); } - static void recordUsageForMap( UsageMap &map, const string &client, D duration ) { + void recordUsageForMap( UsageMap &map, const string &client, D duration ) { map[ client ].get< 0 >() += duration; if ( read_ && !write_ ) map[ client ].get< 1 >()++; @@ -116,7 +148,7 @@ private: for( UsageMap::const_iterator i = from.begin(); i != from.end(); ++i ) { string current = i->first; size_t dot = current.rfind( "." ); - if ( dot == string::npos || dot != current_.length() - 1 ) { + if ( dot == string::npos || dot != current.length() - 1 ) { inc( to[ current ], i->second ); } while( dot != string::npos ) { @@ -133,8 +165,8 @@ private: to.get<3>() += from.get<3>(); } struct more { bool operator()( const D &a, const D &b ) { return a > b; } }; - static string current_; - static T currentStart_; + string current_; + T currentStart_; static T snapshotStart_; static D snapshotDuration_; static UsageMap totalUsage_; @@ -142,8 +174,8 @@ private: static UsageMap snapshotB_; static UsageMap &snapshot_; static UsageMap &nextSnapshot_; - static bool read_; - static bool write_; + bool read_; + bool write_; }; } // namespace mongo diff --git a/util/util.cpp b/util/util.cpp index ad57905d044..93602b0b99a 100644 --- a/util/util.cpp +++ b/util/util.cpp @@ -89,8 +89,6 @@ namespace mongo { } } utilTest; - string Top::current_; - Top::T Top::currentStart_; Top::T Top::snapshotStart_ = Top::currentTime(); Top::D Top::snapshotDuration_; Top::UsageMap Top::totalUsage_; @@ -98,8 +96,7 @@ namespace mongo { Top::UsageMap Top::snapshotB_; Top::UsageMap &Top::snapshot_ = Top::snapshotA_; Top::UsageMap &Top::nextSnapshot_ = Top::snapshotB_; - bool Top::read_ = false; - bool Top::write_ = false; + boost::mutex Top::topMutex; // The mutex contained in this object may be held on shutdown. FileAllocator &theFileAllocator_ = *(new FileAllocator()); |