mutexDebug.h 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /**
  2. * PANDA 3D SOFTWARE
  3. * Copyright (c) Carnegie Mellon University. All rights reserved.
  4. *
  5. * All use of this software is subject to the terms of the revised BSD
  6. * license. You should have received a copy of this license along
  7. * with this source code in a file named "LICENSE."
  8. *
  9. * @file mutexDebug.h
  10. * @author drose
  11. * @date 2006-02-13
  12. */
  13. #ifndef MUTEXDEBUG_H
  14. #define MUTEXDEBUG_H
  15. #include "pandabase.h"
  16. #include "mutexTrueImpl.h"
  17. #include "conditionVarImpl.h"
  18. #include "thread.h"
  19. #include "namable.h"
  20. #include "pmap.h"
  21. #ifdef DEBUG_THREADS
  22. /**
  23. * This class implements a standard mutex the hard way, by doing everything by
  24. * hand. This does allow fancy things like deadlock detection, however.
  25. */
  26. class EXPCL_PANDA_PIPELINE MutexDebug : public Namable {
  27. protected:
  28. MutexDebug(const std::string &name, bool allow_recursion, bool lightweight);
  29. MutexDebug(const MutexDebug &copy) = delete;
  30. virtual ~MutexDebug();
  31. void operator = (const MutexDebug &copy) = delete;
  32. public:
  33. INLINE void lock();
  34. INLINE bool try_lock();
  35. INLINE void unlock();
  36. PUBLISHED:
  37. BLOCKING INLINE void acquire(Thread *current_thread = Thread::get_current_thread()) const;
  38. BLOCKING INLINE bool try_acquire(Thread *current_thread = Thread::get_current_thread()) const;
  39. INLINE void elevate_lock() const;
  40. INLINE void release() const;
  41. INLINE bool debug_is_locked() const;
  42. virtual void output(std::ostream &out) const;
  43. void output_with_holder(std::ostream &out) const;
  44. typedef void VoidFunc();
  45. public:
  46. static void increment_pstats();
  47. static void decrement_pstats();
  48. private:
  49. void do_lock(Thread *current_thread);
  50. bool do_try_lock(Thread *current_thread);
  51. void do_unlock();
  52. bool do_debug_is_locked() const;
  53. void report_deadlock(Thread *current_thread);
  54. private:
  55. INLINE static MutexTrueImpl *get_global_lock();
  56. bool _allow_recursion;
  57. bool _lightweight;
  58. Thread *_locking_thread;
  59. int _lock_count;
  60. char *_deleted_name; // To help I.D. a destructed mutex.
  61. // For _lightweight mutexes.
  62. typedef pmap<Thread *, int> MissedThreads;
  63. MissedThreads _missed_threads;
  64. ConditionVarImpl _cvar_impl;
  65. static int _pstats_count;
  66. static MutexTrueImpl *_global_lock;
  67. friend class ConditionVarDebug;
  68. };
  69. INLINE std::ostream &
  70. operator << (std::ostream &out, const MutexDebug &m) {
  71. m.output(out);
  72. return out;
  73. }
  74. #include "mutexDebug.I"
  75. #endif // DEBUG_THREADS
  76. #endif