Panda3D
mutexDebug.h
1 // Filename: mutexDebug.h
2 // Created by: drose (13Feb06)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #ifndef MUTEXDEBUG_H
16 #define MUTEXDEBUG_H
17 
18 #include "pandabase.h"
19 #include "mutexTrueImpl.h"
20 #include "conditionVarImpl.h"
21 #include "thread.h"
22 #include "namable.h"
23 #include "pmap.h"
24 
25 #ifdef DEBUG_THREADS
26 
27 ////////////////////////////////////////////////////////////////////
28 // Class : MutexDebug
29 // Description : This class implements a standard mutex the hard way,
30 // by doing everything by hand. This does allow fancy
31 // things like deadlock detection, however.
32 ////////////////////////////////////////////////////////////////////
33 class EXPCL_PANDA_PIPELINE MutexDebug : public Namable {
34 protected:
35  MutexDebug(const string &name, bool allow_recursion, bool lightweight);
36  virtual ~MutexDebug();
37 private:
38  INLINE MutexDebug(const MutexDebug &copy);
39  INLINE void operator = (const MutexDebug &copy);
40 
41 PUBLISHED:
42  BLOCKING INLINE void acquire(Thread *current_thread = Thread::get_current_thread()) const;
43  BLOCKING INLINE bool try_acquire(Thread *current_thread = Thread::get_current_thread()) const;
44  INLINE void elevate_lock() const;
45  INLINE void release() const;
46  INLINE bool debug_is_locked() const;
47 
48  virtual void output(ostream &out) const;
49  void output_with_holder(ostream &out) const;
50 
51  typedef void VoidFunc();
52 
53 public:
54  static void increment_pstats();
55  static void decrement_pstats();
56 
57 private:
58  void do_acquire(Thread *current_thread);
59  bool do_try_acquire(Thread *current_thread);
60  void do_release();
61  bool do_debug_is_locked() const;
62 
63  void report_deadlock(Thread *current_thread);
64 
65 private:
66  INLINE static MutexTrueImpl *get_global_lock();
67 
68  bool _allow_recursion;
69  bool _lightweight;
70  Thread *_locking_thread;
71  int _lock_count;
72  char *_deleted_name; // To help I.D. a destructed mutex.
73 
74  // For _lightweight mutexes.
75  typedef pmap<Thread *, int> MissedThreads;
76  MissedThreads _missed_threads;
77 
78  ConditionVarImpl _cvar_impl;
79 
80  static int _pstats_count;
81  static MutexTrueImpl *_global_lock;
82 
83  friend class ConditionVarDebug;
84  friend class ConditionVarFullDebug;
85 };
86 
87 INLINE ostream &
88 operator << (ostream &out, const MutexDebug &m) {
89  m.output(out);
90  return out;
91 }
92 
93 #include "mutexDebug.I"
94 
95 #endif // DEBUG_THREADS
96 
97 #endif
This is our own Panda specialization on the default STL map.
Definition: pmap.h:52
void output(ostream &out) const
Outputs the Namable.
Definition: namable.I:97
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
Definition: thread.I:145
A base class for all things which can have a name.
Definition: namable.h:29
A thread; that is, a lightweight process.
Definition: thread.h:51
A fake mutex implementation for single-threaded applications that don&#39;t need any synchronization cont...