Panda3D

mutexDebug.h

00001 // Filename: mutexDebug.h
00002 // Created by:  drose (13Feb06)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #ifndef MUTEXDEBUG_H
00016 #define MUTEXDEBUG_H
00017 
00018 #include "pandabase.h"
00019 #include "mutexTrueImpl.h"
00020 #include "conditionVarImpl.h"
00021 #include "thread.h"
00022 #include "namable.h"
00023 #include "pmap.h"
00024 
00025 #ifdef DEBUG_THREADS
00026 
00027 ////////////////////////////////////////////////////////////////////
00028 //       Class : MutexDebug
00029 // Description : This class implements a standard mutex the hard way,
00030 //               by doing everything by hand.  This does allow fancy
00031 //               things like deadlock detection, however.
00032 ////////////////////////////////////////////////////////////////////
00033 class EXPCL_PANDA_PIPELINE MutexDebug : public Namable {
00034 protected:
00035   MutexDebug(const string &name, bool allow_recursion, bool lightweight);
00036   virtual ~MutexDebug();
00037 private:
00038   INLINE MutexDebug(const MutexDebug &copy);
00039   INLINE void operator = (const MutexDebug &copy);
00040 
00041 PUBLISHED:
00042   BLOCKING INLINE void acquire(Thread *current_thread = Thread::get_current_thread()) const;
00043   BLOCKING INLINE bool try_acquire(Thread *current_thread = Thread::get_current_thread()) const;
00044   INLINE void elevate_lock() const;
00045   INLINE void release() const;
00046   INLINE bool debug_is_locked() const;
00047 
00048   virtual void output(ostream &out) const;
00049   void output_with_holder(ostream &out) const;
00050 
00051   typedef void VoidFunc();
00052 
00053 public:
00054   static void increment_pstats();
00055   static void decrement_pstats();
00056 
00057 private:
00058   void do_acquire(Thread *current_thread);
00059   bool do_try_acquire(Thread *current_thread);
00060   void do_release();
00061   bool do_debug_is_locked() const;
00062 
00063   void report_deadlock(Thread *current_thread);
00064 
00065 private:
00066   INLINE static MutexTrueImpl *get_global_lock();
00067 
00068   bool _allow_recursion;
00069   bool _lightweight;
00070   Thread *_locking_thread;
00071   int _lock_count;
00072   char *_deleted_name; // To help I.D. a destructed mutex.
00073 
00074   // For _lightweight mutexes.
00075   typedef pmap<Thread *, int> MissedThreads;
00076   MissedThreads _missed_threads;
00077 
00078   ConditionVarImpl _cvar_impl;
00079 
00080   static int _pstats_count;
00081   static MutexTrueImpl *_global_lock;
00082 
00083   friend class ConditionVarDebug;
00084   friend class ConditionVarFullDebug;
00085 };
00086 
00087 INLINE ostream &
00088 operator << (ostream &out, const MutexDebug &m) {
00089   m.output(out);
00090   return out;
00091 }
00092 
00093 #include "mutexDebug.I"
00094 
00095 #endif  //  DEBUG_THREADS
00096 
00097 #endif
 All Classes Functions Variables Enumerations