protect threaded pstats better

This commit is contained in:
David Rose 2009-01-22 23:44:03 +00:00
parent c85f5e39f5
commit 264608d008
6 changed files with 63 additions and 3 deletions

View File

@ -49,7 +49,16 @@ PUBLISHED:
void output(ostream &out) const; void output(ostream &out) const;
private: private:
#ifdef DO_PSTATS
// When PStats is compiled in, we use the full implementation of
// LightMutex, even in the SIMPLE_THREADS case. We have to do this
// since any PStatTimer call may trigger a context switch, and any
// low-level context switch requires all containing mutexes to be
// true mutexes.
MutexTrueImpl _impl;
#else
MutexImpl _impl; MutexImpl _impl;
#endif // DO_PSTATS
}; };
INLINE ostream & INLINE ostream &

View File

@ -15,6 +15,8 @@
#include "lightReMutexDirect.h" #include "lightReMutexDirect.h"
#include "thread.h" #include "thread.h"
#ifndef DEBUG_THREADS
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: LightReMutexDirect::output // Function: LightReMutexDirect::output
// Access: Published // Access: Published
@ -25,3 +27,5 @@ void LightReMutexDirect::
output(ostream &out) const { output(ostream &out) const {
out << "LightReMutex " << (void *)this; out << "LightReMutex " << (void *)this;
} }
#endif // !DEBUG_THREADS

View File

@ -21,6 +21,8 @@
class Thread; class Thread;
#ifndef DEBUG_THREADS
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : LightReMutexDirect // Class : LightReMutexDirect
// Description : This class implements a standard lightReMutex by making // Description : This class implements a standard lightReMutex by making
@ -51,7 +53,7 @@ PUBLISHED:
void output(ostream &out) const; void output(ostream &out) const;
private: private:
#ifdef HAVE_REMUTEXIMPL #if defined(HAVE_REMUTEXIMPL) && !defined(DO_PSTATS)
ReMutexImpl _impl; ReMutexImpl _impl;
#else #else
@ -69,4 +71,6 @@ operator << (ostream &out, const LightReMutexDirect &m) {
#include "lightReMutexDirect.I" #include "lightReMutexDirect.I"
#endif // !DEBUG_THREADS
#endif #endif

View File

@ -18,6 +18,7 @@
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
int MutexDebug::_pstats_count = 0;
MutexTrueImpl *MutexDebug::_global_lock; MutexTrueImpl *MutexDebug::_global_lock;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -100,6 +101,36 @@ output_with_holder(ostream &out) const {
_global_lock->release(); _global_lock->release();
} }
////////////////////////////////////////////////////////////////////
// Function: MutexDebug::increment_pstats
// Access: Public, Static
// Description: Intended to be called only by
// PStatClientImpl::client_connect(), this tells the
// global mutex system that PStats is active. Once
// PStats is active, all "light" mutexes are treated the
// same as full mutexes.
////////////////////////////////////////////////////////////////////
void MutexDebug::
increment_pstats() {
_global_lock->acquire();
++_pstats_count;
_global_lock->release();
}
////////////////////////////////////////////////////////////////////
// Function: MutexDebug::decrement_pstats
// Access: Public, Static
// Description: Intended to be called only by
// PStatClientImpl::client_disconnect(), this tells the
// global mutex system that PStats is no longer active.
////////////////////////////////////////////////////////////////////
void MutexDebug::
decrement_pstats() {
_global_lock->acquire();
--_pstats_count;
_global_lock->release();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: MutexDebug::do_acquire // Function: MutexDebug::do_acquire
// Access: Private // Access: Private
@ -144,7 +175,7 @@ do_acquire(Thread *current_thread) {
} else { } else {
// The mutex is locked by some other thread. // The mutex is locked by some other thread.
if (_lightweight) { if (_lightweight && _pstats_count == 0) {
// In this case, it's not a real mutex. Just watch it go by. // In this case, it's not a real mutex. Just watch it go by.
MissedThreads::iterator mi = _missed_threads.insert(MissedThreads::value_type(current_thread, 0)).first; MissedThreads::iterator mi = _missed_threads.insert(MissedThreads::value_type(current_thread, 0)).first;
if ((*mi).second == 0) { if ((*mi).second == 0) {
@ -263,7 +294,7 @@ do_try_acquire(Thread *current_thread) {
} else { } else {
// The mutex is locked by some other thread. Return false. // The mutex is locked by some other thread. Return false.
if (_lightweight) { if (_lightweight && _pstats_count == 0) {
// In this case, it's not a real mutex. Just watch it go by. // In this case, it's not a real mutex. Just watch it go by.
MissedThreads::iterator mi = _missed_threads.insert(MissedThreads::value_type(current_thread, 0)).first; MissedThreads::iterator mi = _missed_threads.insert(MissedThreads::value_type(current_thread, 0)).first;
if ((*mi).second == 0) { if ((*mi).second == 0) {

View File

@ -49,6 +49,10 @@ PUBLISHED:
typedef void VoidFunc(); typedef void VoidFunc();
public:
static void increment_pstats();
static void decrement_pstats();
private: private:
void do_acquire(Thread *current_thread); void do_acquire(Thread *current_thread);
bool do_try_acquire(Thread *current_thread); bool do_try_acquire(Thread *current_thread);
@ -72,6 +76,7 @@ private:
ConditionVarImpl _cvar_impl; ConditionVarImpl _cvar_impl;
static int _pstats_count;
static MutexTrueImpl *_global_lock; static MutexTrueImpl *_global_lock;
friend class ConditionVarDebug; friend class ConditionVarDebug;

View File

@ -127,6 +127,10 @@ client_connect(string hostname, int port) {
send_hello(); send_hello();
#ifdef DEBUG_THREADS
MutexDebug::increment_pstats();
#endif // DEBUG_THREADS
return _is_connected; return _is_connected;
} }
@ -138,6 +142,9 @@ client_connect(string hostname, int port) {
void PStatClientImpl:: void PStatClientImpl::
client_disconnect() { client_disconnect() {
if (_is_connected) { if (_is_connected) {
#ifdef DEBUG_THREADS
MutexDebug::decrement_pstats();
#endif // DEBUG_THREADS
_reader.remove_connection(_tcp_connection); _reader.remove_connection(_tcp_connection);
close_connection(_tcp_connection); close_connection(_tcp_connection);
close_connection(_udp_connection); close_connection(_udp_connection);