00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00029
00030
00031
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 ©);
00039 INLINE void operator = (const MutexDebug ©);
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;
00073
00074
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