From 889228f403c683476b5553cd735716c2bb154cd0 Mon Sep 17 00:00:00 2001 From: David Rose Date: Sun, 9 Apr 2006 23:23:15 +0000 Subject: [PATCH] name mutexes for debugging; better UpdateSeq thread behavior --- panda/src/collide/collisionSolid.cxx | 5 +- panda/src/display/graphicsEngine.cxx | 17 +++- panda/src/display/graphicsEngine.h | 2 + panda/src/display/graphicsOutput.cxx | 4 +- panda/src/display/graphicsPipe.cxx | 4 +- panda/src/display/graphicsPipeSelection.cxx | 2 +- panda/src/display/graphicsWindow.cxx | 3 +- panda/src/display/lru.cxx | 2 +- panda/src/event/eventQueue.cxx | 2 +- panda/src/express/referenceCount.I | 2 +- panda/src/express/referenceCount.cxx | 30 ++++++- panda/src/express/referenceCount.h | 3 + panda/src/express/weakReferenceList.cxx | 13 ++- panda/src/express/weakReferenceList.h | 2 + panda/src/gobj/geomCacheManager.cxx | 3 +- panda/src/pgraph/nodePathComponent.cxx | 2 +- panda/src/pgraph/pandaNode.cxx | 6 +- panda/src/pgraph/renderState.cxx | 2 +- panda/src/pgraph/transformState.cxx | 2 +- panda/src/pipeline/mutexDebug.I | 14 --- panda/src/pipeline/mutexDebug.cxx | 22 ++++- panda/src/pipeline/mutexDebug.h | 3 +- panda/src/pipeline/pipeline.cxx | 3 + panda/src/pipeline/pmutex.I | 32 ++++++- panda/src/pipeline/pmutex.h | 2 + panda/src/pipeline/reMutex.I | 45 ++++++---- panda/src/pipeline/reMutex.h | 2 + panda/src/pstatclient/pStatClient.cxx | 29 +++++-- panda/src/pstatclient/pStatClient.h | 2 + panda/src/putil/updateSeq.I | 95 ++++++++++----------- panda/src/putil/updateSeq.cxx | 2 - panda/src/putil/updateSeq.h | 13 +-- panda/src/tform/mouseWatcherGroup.cxx | 4 +- 33 files changed, 253 insertions(+), 121 deletions(-) diff --git a/panda/src/collide/collisionSolid.cxx b/panda/src/collide/collisionSolid.cxx index 04591d3c90..c824c7f0ca 100644 --- a/panda/src/collide/collisionSolid.cxx +++ b/panda/src/collide/collisionSolid.cxx @@ -45,7 +45,7 @@ TypeHandle CollisionSolid::_type_handle; // Description: //////////////////////////////////////////////////////////////////// CollisionSolid:: -CollisionSolid() { +CollisionSolid() : _lock("CollisionSolid") { _flags = F_viz_geom_stale | F_tangible | F_internal_bounds_stale; } @@ -58,7 +58,8 @@ CollisionSolid:: CollisionSolid(const CollisionSolid ©) : _effective_normal(copy._effective_normal), _internal_bounds(copy._internal_bounds), - _flags(copy._flags) + _flags(copy._flags), + _lock("CollisionSolid") { _flags |= F_viz_geom_stale; } diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index a9ba75de8e..30de77e03a 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -100,7 +100,9 @@ PStatCollector GraphicsEngine::_test_geom_pcollector("Collision Tests:CollisionG //////////////////////////////////////////////////////////////////// GraphicsEngine:: GraphicsEngine(Pipeline *pipeline) : - _pipeline(pipeline) + _pipeline(pipeline), + _app("app"), + _lock("GraphicsEngine") { if (_pipeline == (Pipeline *)NULL) { _pipeline = Pipeline::get_render_pipeline(); @@ -1727,6 +1729,17 @@ get_window_renderer(const string &name, int pipeline_stage) { return thread.p(); } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::WindowRenderer::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +GraphicsEngine::WindowRenderer:: +WindowRenderer(const string &name) : + _wl_lock(string("GraphicsEngine::WindowRenderer ") + name) +{ +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsEngine::WindowRenderer::add_gsg // Access: Public @@ -2026,7 +2039,9 @@ do_callbacks(GraphicsEngine::CallbackTime callback_time) { GraphicsEngine::RenderThread:: RenderThread(const string &name, GraphicsEngine *engine) : Thread(name, "Main"), + WindowRenderer(name), _engine(engine), + _cv_mutex(string("GraphicsEngine::RenderThread ") + name), _cv_start(_cv_mutex), _cv_done(_cv_mutex) { diff --git a/panda/src/display/graphicsEngine.h b/panda/src/display/graphicsEngine.h index 96a5dcce2e..7d0547a0cf 100644 --- a/panda/src/display/graphicsEngine.h +++ b/panda/src/display/graphicsEngine.h @@ -269,6 +269,8 @@ private: class WindowRenderer { public: + WindowRenderer(const string &name); + void add_gsg(GraphicsStateGuardian *gsg); void add_window(Windows &wlist, GraphicsOutput *window); void remove_window(GraphicsOutput *window); diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index 15a325ab3c..a7433d7e1f 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -74,7 +74,9 @@ GraphicsOutput(GraphicsPipe *pipe, const FrameBufferProperties &properties, int x_size, int y_size, int flags, GraphicsStateGuardian *gsg, - GraphicsOutput *host) { + GraphicsOutput *host) : + _lock("GraphicsOutput") +{ #ifdef DO_MEMORY_USAGE MemoryUsage::update_type(this, this); #endif diff --git a/panda/src/display/graphicsPipe.cxx b/panda/src/display/graphicsPipe.cxx index c588414067..b4a7cb2fd5 100644 --- a/panda/src/display/graphicsPipe.cxx +++ b/panda/src/display/graphicsPipe.cxx @@ -66,7 +66,9 @@ const int GraphicsPipe::strip_properties[] = { // Description: //////////////////////////////////////////////////////////////////// GraphicsPipe:: -GraphicsPipe() { +GraphicsPipe() : + _lock("GraphicsPipe") +{ // Initially, we assume the GraphicsPipe is valid. A derived class // should set this to false if it determines otherwise. _is_valid = true; diff --git a/panda/src/display/graphicsPipeSelection.cxx b/panda/src/display/graphicsPipeSelection.cxx index 88d14d6242..014fd1a804 100644 --- a/panda/src/display/graphicsPipeSelection.cxx +++ b/panda/src/display/graphicsPipeSelection.cxx @@ -34,7 +34,7 @@ GraphicsPipeSelection *GraphicsPipeSelection::_global_ptr = NULL; // Description: //////////////////////////////////////////////////////////////////// GraphicsPipeSelection:: -GraphicsPipeSelection() { +GraphicsPipeSelection() : _lock("GraphicsPipeSelection") { // We declare these variables here instead of in config_display, in // case this constructor is running at static init time. ConfigVariableString load_display diff --git a/panda/src/display/graphicsWindow.cxx b/panda/src/display/graphicsWindow.cxx index 2c975c6129..caa0318e98 100644 --- a/panda/src/display/graphicsWindow.cxx +++ b/panda/src/display/graphicsWindow.cxx @@ -42,7 +42,8 @@ GraphicsWindow(GraphicsPipe *pipe, int x_size, int y_size, int flags, GraphicsStateGuardian *gsg, GraphicsOutput *host) : - GraphicsOutput(pipe, name, properties, x_size, y_size, flags, gsg, host) + GraphicsOutput(pipe, name, properties, x_size, y_size, flags, gsg, host), + _input_lock("GraphicsWindow::_input_lock") { #ifdef DO_MEMORY_USAGE MemoryUsage::update_type(this, this); diff --git a/panda/src/display/lru.cxx b/panda/src/display/lru.cxx index f270e21023..9e74c3a86f 100644 --- a/panda/src/display/lru.cxx +++ b/panda/src/display/lru.cxx @@ -79,7 +79,7 @@ Lru::Lru (int maximum_memory, int maximum_pages, int maximum_page_types) } #if ENABLE_MUTEX - this -> _m.mutex = new Mutex ( ); + this -> _m.mutex = new Mutex ("lru"); #endif } diff --git a/panda/src/event/eventQueue.cxx b/panda/src/event/eventQueue.cxx index d04f396c5f..00dd39bcdb 100644 --- a/panda/src/event/eventQueue.cxx +++ b/panda/src/event/eventQueue.cxx @@ -29,7 +29,7 @@ EventQueue *EventQueue::_global_event_queue = NULL; // Description: //////////////////////////////////////////////////////////////////// EventQueue:: -EventQueue() { +EventQueue() : _lock("EventQueue") { } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/express/referenceCount.I b/panda/src/express/referenceCount.I index fc2e6610b5..3af97f7e51 100644 --- a/panda/src/express/referenceCount.I +++ b/panda/src/express/referenceCount.I @@ -301,7 +301,7 @@ has_weak_list() const { INLINE WeakReferenceList *ReferenceCount:: get_weak_list() const { if (_weak_list == (WeakReferenceList *)NULL) { - ((ReferenceCount *)this)->_weak_list = new WeakReferenceList; + ((ReferenceCount *)this)->create_weak_list(); } return _weak_list; } diff --git a/panda/src/express/referenceCount.cxx b/panda/src/express/referenceCount.cxx index c36512eace..26c68c38d2 100644 --- a/panda/src/express/referenceCount.cxx +++ b/panda/src/express/referenceCount.cxx @@ -16,8 +16,9 @@ // //////////////////////////////////////////////////////////////////// - #include "referenceCount.h" +#include "atomicAdjust.h" +#include "mutexImpl.h" TypeHandle ReferenceCount::_type_handle; @@ -48,3 +49,30 @@ do_test_ref_count_integrity() const { return true; } + +//////////////////////////////////////////////////////////////////// +// Function: ReferenceCount::create_weak_list +// Access: Private +// Description: Allocates a new WeakReferenceList structure and +// stores it on the object. +//////////////////////////////////////////////////////////////////// +void ReferenceCount:: +create_weak_list() { +#ifdef HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR + WeakReferenceList *weak_list = new WeakReferenceList; + void *orig = + AtomicAdjust::compare_and_exchange_ptr((void *&)_weak_list, NULL, weak_list); + if (orig != (void *)NULL) { + // Someone else created it first. + delete weak_list; + } +#else + static MutexImpl lock("ReferenceCount::create_weak_list"); + lock.lock(); + if (_weak_list != (WeakReferenceList *)NULL) { + _weak_list = new WeakReferenceList; + } + lock.release(); +#endif // HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR +} + diff --git a/panda/src/express/referenceCount.h b/panda/src/express/referenceCount.h index 0f3e1e3562..a43f8f9bff 100644 --- a/panda/src/express/referenceCount.h +++ b/panda/src/express/referenceCount.h @@ -66,6 +66,9 @@ public: protected: bool do_test_ref_count_integrity() const; +private: + void create_weak_list(); + private: enum { // We use this value as a flag to indicate an object has been diff --git a/panda/src/express/weakReferenceList.cxx b/panda/src/express/weakReferenceList.cxx index 44c5ff2211..d923da048b 100644 --- a/panda/src/express/weakReferenceList.cxx +++ b/panda/src/express/weakReferenceList.cxx @@ -37,10 +37,12 @@ WeakReferenceList() { //////////////////////////////////////////////////////////////////// WeakReferenceList:: ~WeakReferenceList() { + _lock.lock(); Pointers::iterator pi; for (pi = _pointers.begin(); pi != _pointers.end(); ++pi) { (*pi)->mark_deleted(); } + _lock.release(); } //////////////////////////////////////////////////////////////////// @@ -58,7 +60,9 @@ WeakReferenceList:: //////////////////////////////////////////////////////////////////// void WeakReferenceList:: add_reference(WeakPointerToVoid *ptv) { + _lock.lock(); bool inserted = _pointers.insert(ptv).second; + _lock.release(); nassertv(inserted); } @@ -73,7 +77,12 @@ add_reference(WeakPointerToVoid *ptv) { //////////////////////////////////////////////////////////////////// void WeakReferenceList:: clear_reference(WeakPointerToVoid *ptv) { + _lock.lock(); Pointers::iterator pi = _pointers.find(ptv); - nassertv_always(pi != _pointers.end()); - _pointers.erase(pi); + bool valid = (pi != _pointers.end()); + if (valid) { + _pointers.erase(pi); + } + _lock.release(); + nassertv(valid); } diff --git a/panda/src/express/weakReferenceList.h b/panda/src/express/weakReferenceList.h index 036c276b17..72b055585e 100644 --- a/panda/src/express/weakReferenceList.h +++ b/panda/src/express/weakReferenceList.h @@ -21,6 +21,7 @@ #include "pandabase.h" #include "pset.h" +#include "mutexImpl.h" class WeakPointerToVoid; @@ -45,6 +46,7 @@ public: private: typedef pset Pointers; Pointers _pointers; + MutexImpl _lock; }; #include "weakReferenceList.I" diff --git a/panda/src/gobj/geomCacheManager.cxx b/panda/src/gobj/geomCacheManager.cxx index 55e51e5d38..a4e9fbee08 100644 --- a/panda/src/gobj/geomCacheManager.cxx +++ b/panda/src/gobj/geomCacheManager.cxx @@ -35,7 +35,8 @@ PStatCollector GeomCacheManager::_geom_cache_evict_pcollector("Geom cache operat //////////////////////////////////////////////////////////////////// GeomCacheManager:: GeomCacheManager() : - _total_size(0) + _total_size(0), + _lock("GeomCacheManager") { // We deliberately hang on to this pointer forever. _list = new GeomCacheEntry; diff --git a/panda/src/pgraph/nodePathComponent.cxx b/panda/src/pgraph/nodePathComponent.cxx index d59440c2d2..0d77c0e114 100644 --- a/panda/src/pgraph/nodePathComponent.cxx +++ b/panda/src/pgraph/nodePathComponent.cxx @@ -22,7 +22,7 @@ // We start the key counters off at 1, since 0 is reserved for an // empty NodePath (and also for an unassigned key). int NodePathComponent::_next_key = 1; -Mutex NodePathComponent::_key_lock; +Mutex NodePathComponent::_key_lock("NodePathComponent::_key_lock"); TypeHandle NodePathComponent::_type_handle; diff --git a/panda/src/pgraph/pandaNode.cxx b/panda/src/pgraph/pandaNode.cxx index 08e99ccc6a..d5f099ef3d 100644 --- a/panda/src/pgraph/pandaNode.cxx +++ b/panda/src/pgraph/pandaNode.cxx @@ -67,7 +67,8 @@ TypeHandle PandaNode::_type_handle; //////////////////////////////////////////////////////////////////// PandaNode:: PandaNode(const string &name) : - Namable(name) + Namable(name), + _paths_lock("PandaNode::_paths_lock") { if (pgraph_cat.is_debug()) { pgraph_cat.debug() @@ -113,7 +114,8 @@ PandaNode:: PandaNode(const PandaNode ©) : ReferenceCount(copy), TypedWritable(copy), - Namable(copy) + Namable(copy), + _paths_lock("PandaNode::_paths_lock") { if (pgraph_cat.is_debug()) { pgraph_cat.debug() diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index 1b8dd8601c..26181a5c8e 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/panda/src/pgraph/renderState.cxx @@ -1696,7 +1696,7 @@ init_states() { // meantime, this is OK because we guarantee that this method is // called at static init time, presumably when there is still only // one thread in the world. - _states_lock = new ReMutex; + _states_lock = new ReMutex("RenderState"); nassertv(Thread::get_current_thread() == Thread::get_main_thread()); } diff --git a/panda/src/pgraph/transformState.cxx b/panda/src/pgraph/transformState.cxx index ef3760a9a9..95edb3b8e7 100644 --- a/panda/src/pgraph/transformState.cxx +++ b/panda/src/pgraph/transformState.cxx @@ -1274,7 +1274,7 @@ init_states() { // meantime, this is OK because we guarantee that this method is // called at static init time, presumably when there is still only // one thread in the world. - _states_lock = new ReMutex; + _states_lock = new ReMutex("TransformState"); nassertv(Thread::get_current_thread() == Thread::get_main_thread()); } diff --git a/panda/src/pipeline/mutexDebug.I b/panda/src/pipeline/mutexDebug.I index 5ccf8e0974..824fe09f90 100755 --- a/panda/src/pipeline/mutexDebug.I +++ b/panda/src/pipeline/mutexDebug.I @@ -17,20 +17,6 @@ //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Function: MutexDebug::Constructor -// Access: Protected -// Description: -//////////////////////////////////////////////////////////////////// -INLINE MutexDebug:: -MutexDebug(bool allow_recursion) : - _allow_recursion(allow_recursion), - _locking_thread(NULL), - _lock_count(0), - _cvar(_global_mutex) -{ -} - //////////////////////////////////////////////////////////////////// // Function: MutexDebug::Copy Constructor // Access: Private diff --git a/panda/src/pipeline/mutexDebug.cxx b/panda/src/pipeline/mutexDebug.cxx index ffa5ef9981..272f8039f1 100755 --- a/panda/src/pipeline/mutexDebug.cxx +++ b/panda/src/pipeline/mutexDebug.cxx @@ -27,6 +27,21 @@ MutexDebug::VoidFunc *MutexDebug::_pstats_wait_stop; MutexImpl MutexDebug::_global_mutex; +//////////////////////////////////////////////////////////////////// +// Function: MutexDebug::Constructor +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +MutexDebug:: +MutexDebug(const string &name, bool allow_recursion) : + _name(name), + _allow_recursion(allow_recursion), + _locking_thread(NULL), + _lock_count(0), + _cvar(_global_mutex) +{ +} + //////////////////////////////////////////////////////////////////// // Function: MutexDebug::Destructor // Access: Protected, Virtual @@ -50,9 +65,9 @@ MutexDebug:: void MutexDebug:: output(ostream &out) const { if (_allow_recursion) { - out << "ReMutex " << (void *)this; + out << "ReMutex " << _name << " " << (void *)this; } else { - out << "Mutex " << (void *)this; + out << "Mutex " << _name << " " << (void *)this; } } @@ -152,7 +167,8 @@ do_lock() { if (thread_cat.is_spam()) { thread_cat.spam() - << *this_thread << " blocking on " << *this << "\n"; + << *this_thread << " blocking on " << *this << " (held by " + << *_locking_thread << ")\n"; } while (_locking_thread != (Thread *)NULL) { _cvar.wait(); diff --git a/panda/src/pipeline/mutexDebug.h b/panda/src/pipeline/mutexDebug.h index 83c2c83fc1..12449baf90 100644 --- a/panda/src/pipeline/mutexDebug.h +++ b/panda/src/pipeline/mutexDebug.h @@ -35,7 +35,7 @@ class Thread; //////////////////////////////////////////////////////////////////// class EXPCL_PANDA MutexDebug { protected: - INLINE MutexDebug(bool allow_recursion); + MutexDebug(const string &name, bool allow_recursion); virtual ~MutexDebug(); private: INLINE MutexDebug(const MutexDebug ©); @@ -59,6 +59,7 @@ private: void report_deadlock(Thread *this_thread); private: + string _name; bool _allow_recursion; Thread *_locking_thread; int _lock_count; diff --git a/panda/src/pipeline/pipeline.cxx b/panda/src/pipeline/pipeline.cxx index e09015fbe9..730a5e7957 100644 --- a/panda/src/pipeline/pipeline.cxx +++ b/panda/src/pipeline/pipeline.cxx @@ -32,6 +32,9 @@ Pipeline *Pipeline::_render_pipeline = (Pipeline *)NULL; Pipeline:: Pipeline(const string &name, int num_stages) : Namable(name) +#ifdef THREADED_PIPELINE + , _lock("Pipeline") +#endif { #ifdef THREADED_PIPELINE // Set up the linked list of cyclers to be a circular list that diff --git a/panda/src/pipeline/pmutex.I b/panda/src/pipeline/pmutex.I index 6cef5d539a..5ca712c24b 100644 --- a/panda/src/pipeline/pmutex.I +++ b/panda/src/pipeline/pmutex.I @@ -24,13 +24,41 @@ //////////////////////////////////////////////////////////////////// INLINE Mutex:: #ifdef DEBUG_THREADS -Mutex() : MutexDebug(false) +Mutex() : MutexDebug(string(), false) #else Mutex() #endif // DEBUG_THREADS { } +//////////////////////////////////////////////////////////////////// +// Function: Mutex::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE Mutex:: +#ifdef DEBUG_THREADS +Mutex(const char *name) : MutexDebug(string(name), false) +#else +Mutex(const char *) +#endif // DEBUG_THREADS +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: Mutex::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE Mutex:: +#ifdef DEBUG_THREADS +Mutex(const string &name) : MutexDebug(name, false) +#else +Mutex(const string &) +#endif // DEBUG_THREADS +{ +} + //////////////////////////////////////////////////////////////////// // Function: Mutex::Destructor // Access: Public @@ -47,7 +75,7 @@ INLINE Mutex:: //////////////////////////////////////////////////////////////////// INLINE Mutex:: #ifdef DEBUG_THREADS -Mutex(const Mutex ©) : MutexDebug(false) +Mutex(const Mutex ©) : MutexDebug(string(), false) #else Mutex(const Mutex ©) #endif // DEBUG_THREADS diff --git a/panda/src/pipeline/pmutex.h b/panda/src/pipeline/pmutex.h index c113a7f935..8bc81ac294 100644 --- a/panda/src/pipeline/pmutex.h +++ b/panda/src/pipeline/pmutex.h @@ -50,6 +50,8 @@ class EXPCL_PANDA Mutex : public MutexDirect { public: INLINE Mutex(); + INLINE Mutex(const char *name); + INLINE Mutex(const string &name); INLINE ~Mutex(); private: INLINE Mutex(const Mutex ©); diff --git a/panda/src/pipeline/reMutex.I b/panda/src/pipeline/reMutex.I index 098acc86af..2c1dc9a463 100644 --- a/panda/src/pipeline/reMutex.I +++ b/panda/src/pipeline/reMutex.I @@ -24,13 +24,41 @@ //////////////////////////////////////////////////////////////////// INLINE ReMutex:: #ifdef DEBUG_THREADS -ReMutex() : MutexDebug(true) +ReMutex() : MutexDebug(string(), true) #else ReMutex() #endif // DEBUG_THREADS { } +//////////////////////////////////////////////////////////////////// +// Function: ReMutex::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE ReMutex:: +#ifdef DEBUG_THREADS +ReMutex(const char *name) : MutexDebug(string(name), true) +#else +ReMutex(const char *) +#endif // DEBUG_THREADS +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: ReMutex::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE ReMutex:: +#ifdef DEBUG_THREADS +ReMutex(const string &name) : MutexDebug(name, true) +#else +ReMutex(const string &) +#endif // DEBUG_THREADS +{ +} + //////////////////////////////////////////////////////////////////// // Function: ReMutex::Destructor // Access: Public @@ -40,21 +68,6 @@ INLINE ReMutex:: ~ReMutex() { } -//////////////////////////////////////////////////////////////////// -// Function: ReMutex::Copy Constructor -// Access: Private -// Description: Do not attempt to copy mutexes. -//////////////////////////////////////////////////////////////////// -INLINE ReMutex:: -#ifdef DEBUG_THREADS -ReMutex(const ReMutex ©) : MutexDebug(true) -#else - ReMutex(const ReMutex ©) -#endif // DEBUG_THREADS -{ - nassertv(false); -} - //////////////////////////////////////////////////////////////////// // Function: ReMutex::Copy Assignment Operator // Access: Private diff --git a/panda/src/pipeline/reMutex.h b/panda/src/pipeline/reMutex.h index e01c14fcc0..724551e893 100644 --- a/panda/src/pipeline/reMutex.h +++ b/panda/src/pipeline/reMutex.h @@ -42,6 +42,8 @@ class EXPCL_PANDA ReMutex : public ReMutexDirect { public: INLINE ReMutex(); + INLINE ReMutex(const char *name); + INLINE ReMutex(const string &name); INLINE ~ReMutex(); private: INLINE ReMutex(const ReMutex ©); diff --git a/panda/src/pstatclient/pStatClient.cxx b/panda/src/pstatclient/pStatClient.cxx index 927a43e8e6..0cf9ec5cee 100644 --- a/panda/src/pstatclient/pStatClient.cxx +++ b/panda/src/pstatclient/pStatClient.cxx @@ -58,7 +58,8 @@ PerThreadData() { //////////////////////////////////////////////////////////////////// PStatClient:: PStatClient() : - _impl(NULL) + _impl(NULL), + _lock("PStatClient") { _collectors = NULL; _collectors_size = 0; @@ -489,14 +490,7 @@ do_make_thread(Thread *thread) { _threads_by_name[thread->get_name()].push_back(new_index); _threads_by_sync_name[thread->get_sync_name()].push_back(new_index); - InternalThread *pthread = new InternalThread; - pthread->_thread = thread; - pthread->_name = thread->get_name(); - pthread->_sync_name = thread->get_sync_name(); - pthread->_is_active = false; - pthread->_next_packet = 0.0; - pthread->_frame_number = 0; - + InternalThread *pthread = new InternalThread(thread); add_thread(pthread); // We need an additional PerThreadData for this thread in all of the @@ -899,4 +893,21 @@ make_def(const PStatClient *client, int this_index) { } } +//////////////////////////////////////////////////////////////////// +// Function: PStatClient::Collector::make_def +// Access: Private +// Description: Creates the new PStatCollectorDef for this collector. +//////////////////////////////////////////////////////////////////// +PStatClient::InternalThread:: +InternalThread(Thread *thread) : + _thread(thread), + _name(thread->get_name()), + _sync_name(thread->get_sync_name()), + _is_active(false), + _next_packet(0.0), + _frame_number(0), + _thread_lock(string("PStatClient::InternalThread ") + thread->get_name()) +{ +} + #endif // DO_PSTATS diff --git a/panda/src/pstatclient/pStatClient.h b/panda/src/pstatclient/pStatClient.h index 077a56ec5d..46eeebe29b 100644 --- a/panda/src/pstatclient/pStatClient.h +++ b/panda/src/pstatclient/pStatClient.h @@ -194,6 +194,8 @@ private: // maintained separately for each thread. class InternalThread { public: + InternalThread(Thread *thread); + WPT(Thread) _thread; string _name; string _sync_name; diff --git a/panda/src/putil/updateSeq.I b/panda/src/putil/updateSeq.I index 6eedaeee66..a13f844cc3 100644 --- a/panda/src/putil/updateSeq.I +++ b/panda/src/putil/updateSeq.I @@ -23,7 +23,7 @@ // Description: Creates an UpdateSeq in the 'initial' state. //////////////////////////////////////////////////////////////////// INLINE UpdateSeq:: -UpdateSeq() { +UpdateSeq() : _lock("UpdateSeq") { _seq = (unsigned int)SC_initial; } @@ -67,9 +67,8 @@ fresh() { // Description: //////////////////////////////////////////////////////////////////// INLINE UpdateSeq:: -UpdateSeq(const UpdateSeq ©) { - MutexHolder holder(_lock); - _seq = copy._seq; +UpdateSeq(const UpdateSeq ©) : _lock("UpdateSeq") { + _seq = AtomicAdjust::get(copy._seq); } //////////////////////////////////////////////////////////////////// @@ -79,8 +78,7 @@ UpdateSeq(const UpdateSeq ©) { //////////////////////////////////////////////////////////////////// INLINE UpdateSeq &UpdateSeq:: operator = (const UpdateSeq ©) { - MutexHolder holder(_lock); - _seq = copy._seq; + AtomicAdjust::set(_seq, AtomicAdjust::get(copy._seq)); return *this; } @@ -91,8 +89,7 @@ operator = (const UpdateSeq ©) { //////////////////////////////////////////////////////////////////// INLINE void UpdateSeq:: clear() { - MutexHolder holder(_lock); - _seq = (unsigned int)SC_initial; + AtomicAdjust::set(_seq, (PN_int32)SC_initial); } //////////////////////////////////////////////////////////////////// @@ -103,8 +100,7 @@ clear() { //////////////////////////////////////////////////////////////////// INLINE bool UpdateSeq:: is_initial() const { - MutexHolder holder(_lock); - return _seq == (unsigned int)SC_initial; + return AtomicAdjust::get(_seq) == (PN_int32)SC_initial; } //////////////////////////////////////////////////////////////////// @@ -114,8 +110,7 @@ is_initial() const { //////////////////////////////////////////////////////////////////// INLINE bool UpdateSeq:: is_old() const { - MutexHolder holder(_lock); - return _seq == (unsigned int)SC_old; + return AtomicAdjust::get(_seq) == (PN_int32)SC_old; } //////////////////////////////////////////////////////////////////// @@ -126,8 +121,7 @@ is_old() const { //////////////////////////////////////////////////////////////////// INLINE bool UpdateSeq:: is_fresh() const { - MutexHolder holder(_lock); - return _seq == (unsigned int)SC_fresh; + return AtomicAdjust::get(_seq) == (PN_int32)SC_fresh; } //////////////////////////////////////////////////////////////////// @@ -138,8 +132,8 @@ is_fresh() const { //////////////////////////////////////////////////////////////////// INLINE bool UpdateSeq:: is_special() const { - MutexHolder holder(_lock); - return priv_is_special(); + // This relies on the assumption that (~0 + 1) == 0. + return ((AtomicAdjust::get(_seq) + 1) <= 2); } //////////////////////////////////////////////////////////////////// @@ -149,8 +143,7 @@ is_special() const { //////////////////////////////////////////////////////////////////// INLINE bool UpdateSeq:: operator == (const UpdateSeq &other) const { - MutexHolder holder(_lock); - return (_seq == other._seq); + return AtomicAdjust::get(_seq) == AtomicAdjust::get(other._seq); } //////////////////////////////////////////////////////////////////// @@ -160,8 +153,7 @@ operator == (const UpdateSeq &other) const { //////////////////////////////////////////////////////////////////// INLINE bool UpdateSeq:: operator != (const UpdateSeq &other) const { - MutexHolder holder(_lock); - return (_seq != other._seq); + return AtomicAdjust::get(_seq) != AtomicAdjust::get(other._seq); } //////////////////////////////////////////////////////////////////// @@ -171,8 +163,7 @@ operator != (const UpdateSeq &other) const { //////////////////////////////////////////////////////////////////// INLINE bool UpdateSeq:: operator < (const UpdateSeq &other) const { - MutexHolder holder(_lock); - return priv_lt(other); + return priv_lt(AtomicAdjust::get(_seq), AtomicAdjust::get(other._seq)); } //////////////////////////////////////////////////////////////////// @@ -182,8 +173,7 @@ operator < (const UpdateSeq &other) const { //////////////////////////////////////////////////////////////////// INLINE bool UpdateSeq:: operator <= (const UpdateSeq &other) const { - MutexHolder holder(_lock); - return _seq == other._seq || priv_lt(other); + return priv_le(AtomicAdjust::get(_seq), AtomicAdjust::get(other._seq)); } //////////////////////////////////////////////////////////////////// @@ -215,11 +205,14 @@ INLINE UpdateSeq UpdateSeq:: operator ++ () { { MutexHolder holder(_lock); - ++_seq; - if (priv_is_special()) { + + PN_int32 new_seq = _seq + 1; + if (priv_is_special(new_seq)) { // Oops, wraparound. We don't want to confuse the new value // with our special cases. - _seq = (unsigned int)SC_old + 1; + AtomicAdjust::set(_seq, (PN_int32)SC_old + 1); + } else { + AtomicAdjust::set(_seq, new_seq); } } @@ -237,10 +230,12 @@ operator ++ (int) { { MutexHolder holder(_lock); temp._seq = _seq; - - ++_seq; - if (priv_is_special()) { - _seq = (unsigned int)SC_old + 1; + + PN_int32 new_seq = _seq + 1; + if (priv_is_special(new_seq)) { + AtomicAdjust::set(_seq, (PN_int32)SC_old + 1); + } else { + AtomicAdjust::set(_seq, new_seq); } } @@ -254,11 +249,7 @@ operator ++ (int) { //////////////////////////////////////////////////////////////////// INLINE void UpdateSeq:: output(ostream &out) const { - unsigned int seq; - { - MutexHolder holder(_lock); - seq = _seq; - } + PN_int32 seq = AtomicAdjust::get(_seq); switch (seq) { case SC_initial: out << "initial"; @@ -273,38 +264,46 @@ output(ostream &out) const { break; default: - out << (long unsigned int)seq; + out << (unsigned int)seq; } } //////////////////////////////////////////////////////////////////// // Function: UpdateSeq::priv_is_special -// Access: Published -// Description: The private implementation of is_special(). Assumes -// the lock is already held. +// Access: Private, Static +// Description: The private implementation of is_special(). //////////////////////////////////////////////////////////////////// INLINE bool UpdateSeq:: -priv_is_special() const { +priv_is_special(PN_int32 seq) { // This relies on the assumption that (~0 + 1) == 0. - return ((_seq + 1) <= 2); + return (((unsigned int)seq + 1) <= 2); } //////////////////////////////////////////////////////////////////// // Function: UpdateSeq::priv_lt -// Access: Published -// Description: The private implementation of operator < (). Assumes -// the lock is already held. +// Access: Private, Static +// Description: The private implementation of operator < (). //////////////////////////////////////////////////////////////////// INLINE bool UpdateSeq:: -priv_lt(const UpdateSeq &other) const { +priv_lt(PN_int32 a, PN_int32 b) { // The special cases of SC_initial or SC_old are less than all other // non-special numbers, and SC_initial is less than SC_old. The // special case of SC_fresh is greater than all other non-special // numbers. For all other cases, we use a circular comparision such // that n < m iff (signed)(n - m) < 0. return - (priv_is_special() || other.priv_is_special()) ? (_seq < other._seq) : - ((signed int)(_seq - other._seq) < 0); + (priv_is_special(a) || priv_is_special(b)) ? ((unsigned int)a < (unsigned int)b) : + ((signed int)(a - b) < 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: UpdateSeq::priv_le +// Access: Private, Static +// Description: The private implementation of operator <= (). +//////////////////////////////////////////////////////////////////// +INLINE bool UpdateSeq:: +priv_le(PN_int32 a, PN_int32 b) { + return (a == b) || priv_lt(a, b); } INLINE ostream &operator << (ostream &out, const UpdateSeq &value) { diff --git a/panda/src/putil/updateSeq.cxx b/panda/src/putil/updateSeq.cxx index 7f42606720..b6ec159bda 100644 --- a/panda/src/putil/updateSeq.cxx +++ b/panda/src/putil/updateSeq.cxx @@ -17,5 +17,3 @@ //////////////////////////////////////////////////////////////////// #include "updateSeq.h" - -Mutex UpdateSeq::_lock; diff --git a/panda/src/putil/updateSeq.h b/panda/src/putil/updateSeq.h index 5c2fec5ca3..6a3a33e798 100644 --- a/panda/src/putil/updateSeq.h +++ b/panda/src/putil/updateSeq.h @@ -22,6 +22,8 @@ #include "pandabase.h" #include "pmutex.h" #include "mutexHolder.h" +#include "atomicAdjust.h" +#include "numeric_types.h" //////////////////////////////////////////////////////////////////// // Class : UpdateSeq @@ -72,8 +74,9 @@ PUBLISHED: INLINE void output(ostream &out) const; private: - INLINE bool priv_is_special() const; - INLINE bool priv_lt(const UpdateSeq &other) const; + INLINE static bool priv_is_special(PN_int32 seq); + INLINE static bool priv_lt(PN_int32 a, PN_int32 b); + INLINE static bool priv_le(PN_int32 a, PN_int32 b); private: enum SpecialCases { @@ -82,10 +85,8 @@ private: SC_fresh = ~(unsigned int)0, }; - unsigned int _seq; - - // This mutex globally protects all UpdateSeqs in the world. - static Mutex _lock; + PN_int32 _seq; + Mutex _lock; }; INLINE ostream &operator << (ostream &out, const UpdateSeq &value); diff --git a/panda/src/tform/mouseWatcherGroup.cxx b/panda/src/tform/mouseWatcherGroup.cxx index 0e02b9920e..32bbfd0f5b 100644 --- a/panda/src/tform/mouseWatcherGroup.cxx +++ b/panda/src/tform/mouseWatcherGroup.cxx @@ -29,7 +29,9 @@ TypeHandle MouseWatcherGroup::_type_handle; // Description: //////////////////////////////////////////////////////////////////// MouseWatcherGroup:: -MouseWatcherGroup() { +MouseWatcherGroup() : + _lock("MouseWatcherGroup") +{ #ifndef NDEBUG _show_regions = false; _color.set(0.4f, 0.6f, 1.0f, 1.0f);