name mutexes for debugging; better UpdateSeq thread behavior
This commit is contained in:
parent
b4f84135d6
commit
889228f403
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ EventQueue *EventQueue::_global_event_queue = NULL;
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EventQueue::
|
||||
EventQueue() {
|
||||
EventQueue() : _lock("EventQueue") {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
#include "pset.h"
|
||||
#include "mutexImpl.h"
|
||||
|
||||
class WeakPointerToVoid;
|
||||
|
||||
|
|
@ -45,6 +46,7 @@ public:
|
|||
private:
|
||||
typedef pset<WeakPointerToVoid *> Pointers;
|
||||
Pointers _pointers;
|
||||
MutexImpl _lock;
|
||||
};
|
||||
|
||||
#include "weakReferenceList.I"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ©);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ©);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -194,6 +194,8 @@ private:
|
|||
// maintained separately for each thread.
|
||||
class InternalThread {
|
||||
public:
|
||||
InternalThread(Thread *thread);
|
||||
|
||||
WPT(Thread) _thread;
|
||||
string _name;
|
||||
string _sync_name;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -17,5 +17,3 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "updateSeq.h"
|
||||
|
||||
Mutex UpdateSeq::_lock;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue