Browse Source

protect threaded pstats better

David Rose 17 years ago
parent
commit
264608d008

+ 9 - 0
panda/src/pipeline/lightMutexDirect.h

@@ -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 &

+ 4 - 0
panda/src/pipeline/lightReMutexDirect.cxx

@@ -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

+ 5 - 1
panda/src/pipeline/lightReMutexDirect.h

@@ -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

+ 33 - 2
panda/src/pipeline/mutexDebug.cxx

@@ -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) {

+ 5 - 0
panda/src/pipeline/mutexDebug.h

@@ -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;

+ 7 - 0
panda/src/pstatclient/pStatClientImpl.cxx

@@ -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);