diff --git a/panda/src/gobj/geom.I b/panda/src/gobj/geom.I index 13ec240bf0..6adeda7b7e 100644 --- a/panda/src/gobj/geom.I +++ b/panda/src/gobj/geom.I @@ -467,15 +467,17 @@ CData(const Geom::CData ©) : // Description: //////////////////////////////////////////////////////////////////// INLINE GeomPipelineReader:: -GeomPipelineReader(const Geom *object, int pipeline_stage) : +GeomPipelineReader(const Geom *object, Thread *current_thread) : _object(object), - _pipeline_stage(pipeline_stage), - _cdata(object->_cycler.read_stage(pipeline_stage)) + _current_thread(current_thread), + _cdata(object->_cycler.read(current_thread)) { +#ifdef _DEBUG nassertv(_object->test_ref_count_nonzero()); #ifdef DO_PIPELINING nassertv(_cdata->test_ref_count_nonzero()); #endif // DO_PIPELINING +#endif // _DEBUG } //////////////////////////////////////////////////////////////////// @@ -505,13 +507,18 @@ operator = (const GeomPipelineReader &) { //////////////////////////////////////////////////////////////////// INLINE GeomPipelineReader:: ~GeomPipelineReader() { +#ifdef _DEBUG nassertv(_object->test_ref_count_nonzero()); #ifdef DO_PIPELINING nassertv(_cdata->test_ref_count_nonzero()); #endif // DO_PIPELINING - _object->_cycler.release_read_stage(_pipeline_stage, _cdata); +#endif // _DEBUG + _object->_cycler.release_read(_cdata); + +#ifdef _DEBUG _object = NULL; _cdata = NULL; +#endif // _DEBUG } //////////////////////////////////////////////////////////////////// @@ -525,13 +532,13 @@ get_object() const { } //////////////////////////////////////////////////////////////////// -// Function: GeomPipelineReader::get_pipeline_stage +// Function: GeomPipelineReader::get_current_thread // Access: Public // Description: //////////////////////////////////////////////////////////////////// -INLINE int GeomPipelineReader:: -get_pipeline_stage() const { - return _pipeline_stage; +INLINE Thread *GeomPipelineReader:: +get_current_thread() const { + return _current_thread; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/geom.cxx b/panda/src/gobj/geom.cxx index f0ebc090ec..0901663259 100644 --- a/panda/src/gobj/geom.cxx +++ b/panda/src/gobj/geom.cxx @@ -685,9 +685,9 @@ transform_vertices(const LMatrix4f &mat) { //////////////////////////////////////////////////////////////////// bool Geom:: check_valid() const { - int pipeline_stage = Thread::get_current_pipeline_stage(); - GeomPipelineReader geom_reader(this, pipeline_stage); - GeomVertexDataPipelineReader data_reader(geom_reader.get_vertex_data(), pipeline_stage); + Thread *current_thread = Thread::get_current_thread(); + GeomPipelineReader geom_reader(this, current_thread); + GeomVertexDataPipelineReader data_reader(geom_reader.get_vertex_data(), current_thread); data_reader.check_array_readers(); return geom_reader.check_valid(&data_reader); } @@ -702,9 +702,9 @@ check_valid() const { //////////////////////////////////////////////////////////////////// bool Geom:: check_valid(const GeomVertexData *vertex_data) const { - int pipeline_stage = Thread::get_current_pipeline_stage(); - GeomPipelineReader geom_reader(this, pipeline_stage); - GeomVertexDataPipelineReader data_reader(vertex_data, pipeline_stage); + Thread *current_thread = Thread::get_current_thread(); + GeomPipelineReader geom_reader(this, current_thread); + GeomVertexDataPipelineReader data_reader(vertex_data, current_thread); data_reader.check_array_readers(); return geom_reader.check_valid(&data_reader); } @@ -931,11 +931,11 @@ prepare_now(PreparedGraphicsObjects *prepared_objects, void Geom:: draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger, const GeomVertexData *vertex_data) const { - int pipeline_stage = Thread::get_current_pipeline_stage(); - GeomPipelineReader geom_reader(this, pipeline_stage); + Thread *current_thread = Thread::get_current_thread(); + GeomPipelineReader geom_reader(this, current_thread); geom_reader.check_usage_hint(); - GeomVertexDataPipelineReader data_reader(vertex_data, pipeline_stage); + GeomVertexDataPipelineReader data_reader(vertex_data, current_thread); data_reader.check_array_readers(); geom_reader.draw(gsg, munger, &data_reader); @@ -1343,7 +1343,7 @@ check_valid(const GeomVertexDataPipelineReader *data_reader) const { pi != _cdata->_primitives.end(); ++pi) { const GeomPrimitive *primitive = (*pi); - GeomPrimitivePipelineReader reader(primitive, _pipeline_stage); + GeomPrimitivePipelineReader reader(primitive, _current_thread); reader.check_minmax(); if (!reader.check_valid(data_reader)) { return false; @@ -1368,7 +1368,7 @@ draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger, pi != _cdata->_primitives.end(); ++pi) { const GeomPrimitive *primitive = (*pi); - GeomPrimitivePipelineReader reader(primitive, _pipeline_stage); + GeomPrimitivePipelineReader reader(primitive, _current_thread); if (reader.get_num_vertices() != 0) { reader.check_minmax(); primitive->draw(gsg, &reader); diff --git a/panda/src/gobj/geom.h b/panda/src/gobj/geom.h index f20955ddbc..d059902cef 100644 --- a/panda/src/gobj/geom.h +++ b/panda/src/gobj/geom.h @@ -302,7 +302,7 @@ private: //////////////////////////////////////////////////////////////////// class EXPCL_PANDA GeomPipelineReader : public GeomEnums { public: - INLINE GeomPipelineReader(const Geom *object, int pipeline_stage); + INLINE GeomPipelineReader(const Geom *object, Thread *current_thread); private: INLINE GeomPipelineReader(const GeomPipelineReader ©); INLINE void operator = (const GeomPipelineReader ©); @@ -312,7 +312,7 @@ public: ALLOC_DELETED_CHAIN(GeomPipelineReader); INLINE const Geom *get_object() const; - INLINE int get_pipeline_stage() const; + INLINE Thread *get_current_thread() const; INLINE void check_usage_hint() const; @@ -333,7 +333,7 @@ public: private: const Geom *_object; - int _pipeline_stage; + Thread *_current_thread; const Geom::CData *_cdata; }; diff --git a/panda/src/gobj/geomPrimitive.I b/panda/src/gobj/geomPrimitive.I index e5478635c9..aa39f9ffef 100644 --- a/panda/src/gobj/geomPrimitive.I +++ b/panda/src/gobj/geomPrimitive.I @@ -111,7 +111,7 @@ is_composite() const { //////////////////////////////////////////////////////////////////// INLINE bool GeomPrimitive:: is_indexed() const { - GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage()); + GeomPrimitivePipelineReader reader(this, Thread::get_current_thread()); return reader.is_indexed(); } @@ -126,7 +126,7 @@ is_indexed() const { //////////////////////////////////////////////////////////////////// INLINE int GeomPrimitive:: get_first_vertex() const { - GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage()); + GeomPrimitivePipelineReader reader(this, Thread::get_current_thread()); return reader.get_first_vertex(); } @@ -138,7 +138,7 @@ get_first_vertex() const { //////////////////////////////////////////////////////////////////// INLINE int GeomPrimitive:: get_num_vertices() const { - GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage()); + GeomPrimitivePipelineReader reader(this, Thread::get_current_thread()); return reader.get_num_vertices(); } @@ -149,7 +149,7 @@ get_num_vertices() const { //////////////////////////////////////////////////////////////////// INLINE int GeomPrimitive:: get_vertex(int i) const { - GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage()); + GeomPrimitivePipelineReader reader(this, Thread::get_current_thread()); return reader.get_vertex(i); } @@ -162,7 +162,7 @@ get_vertex(int i) const { //////////////////////////////////////////////////////////////////// INLINE int GeomPrimitive:: get_num_primitives() const { - GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage()); + GeomPrimitivePipelineReader reader(this, Thread::get_current_thread()); return reader.get_num_primitives(); } @@ -214,7 +214,7 @@ get_primitive_num_faces(int n) const { //////////////////////////////////////////////////////////////////// INLINE int GeomPrimitive:: get_min_vertex() const { - GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage()); + GeomPrimitivePipelineReader reader(this, Thread::get_current_thread()); reader.check_minmax(); return reader.get_min_vertex(); } @@ -227,7 +227,7 @@ get_min_vertex() const { //////////////////////////////////////////////////////////////////// INLINE int GeomPrimitive:: get_max_vertex() const { - GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage()); + GeomPrimitivePipelineReader reader(this, Thread::get_current_thread()); reader.check_minmax(); return reader.get_max_vertex(); } @@ -267,10 +267,10 @@ get_modified() const { //////////////////////////////////////////////////////////////////// INLINE bool GeomPrimitive:: check_valid(const GeomVertexData *vertex_data) const { - int pipeline_stage = Thread::get_current_pipeline_stage(); - GeomPrimitivePipelineReader reader(this, pipeline_stage); + Thread *current_thread = Thread::get_current_thread(); + GeomPrimitivePipelineReader reader(this, current_thread); reader.check_minmax(); - GeomVertexDataPipelineReader data_reader(vertex_data, pipeline_stage); + GeomVertexDataPipelineReader data_reader(vertex_data, current_thread); data_reader.check_array_readers(); return reader.check_valid(&data_reader); } @@ -299,7 +299,7 @@ get_vertices() const { //////////////////////////////////////////////////////////////////// INLINE int GeomPrimitive:: get_index_stride() const { - GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage()); + GeomPrimitivePipelineReader reader(this, Thread::get_current_thread()); return reader.get_index_stride(); } @@ -346,7 +346,7 @@ get_ends() const { //////////////////////////////////////////////////////////////////// INLINE const GeomVertexArrayData *GeomPrimitive:: get_mins() const { - GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage()); + GeomPrimitivePipelineReader reader(this, Thread::get_current_thread()); reader.check_minmax(); return reader.get_mins(); } @@ -364,7 +364,7 @@ get_mins() const { //////////////////////////////////////////////////////////////////// INLINE const GeomVertexArrayData *GeomPrimitive:: get_maxs() const { - GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage()); + GeomPrimitivePipelineReader reader(this, Thread::get_current_thread()); reader.check_minmax(); return reader.get_maxs(); } @@ -468,6 +468,29 @@ CData(const GeomPrimitive::CData ©) : _max_vertex(copy._max_vertex) { } +//////////////////////////////////////////////////////////////////// +// Function: GeomPrimitivePipelineReader::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE GeomPrimitivePipelineReader:: +GeomPrimitivePipelineReader(const GeomPrimitive *object, + Thread *current_thread) : + _object(object), + _current_thread(current_thread), + _cdata(object->_cycler.read(current_thread)), + _vertices_reader(NULL) +{ + nassertv(_object->test_ref_count_nonzero()); +#ifdef DO_PIPELINING + nassertv(_cdata->test_ref_count_nonzero()); +#endif // DO_PIPELINING + if (_cdata->_vertices != (GeomVertexArrayData *)NULL) { + _vertices_reader = + new GeomVertexArrayDataPipelineReader(_cdata->_vertices, _current_thread); + nassertv(_vertices_reader->get_object() == _cdata->_vertices); + } +} //////////////////////////////////////////////////////////////////// // Function: GeomPrimitivePipelineReader::Copy Constructor @@ -489,6 +512,32 @@ operator = (const GeomPrimitivePipelineReader &) { nassertv(false); } +//////////////////////////////////////////////////////////////////// +// Function: GeomPrimitivePipelineReader::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE GeomPrimitivePipelineReader:: +~GeomPrimitivePipelineReader() { + if (_vertices_reader != (GeomVertexArrayDataPipelineReader *)NULL) { + nassertv(_vertices_reader->get_object() == _cdata->_vertices); + delete _vertices_reader; + } +#ifdef _DEBUG + nassertv(_object->test_ref_count_nonzero()); +#ifdef DO_PIPELINING + nassertv(_cdata->test_ref_count_nonzero()); +#endif // DO_PIPELINING +#endif // _DEBUG + _object->_cycler.release_read(_cdata); + +#ifdef _DEBUG + _vertices_reader = NULL; + _object = NULL; + _cdata = NULL; +#endif // _DEBUG +} + //////////////////////////////////////////////////////////////////// // Function: GeomPrimitivePipelineReader::get_object // Access: Public @@ -500,13 +549,13 @@ get_object() const { } //////////////////////////////////////////////////////////////////// -// Function: GeomPrimitivePipelineReader::get_pipeline_stage +// Function: GeomPrimitivePipelineReader::get_current_thread // Access: Public // Description: //////////////////////////////////////////////////////////////////// -INLINE int GeomPrimitivePipelineReader:: -get_pipeline_stage() const { - return _pipeline_stage; +INLINE Thread *GeomPrimitivePipelineReader:: +get_current_thread() const { + return _current_thread; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/geomPrimitive.cxx b/panda/src/gobj/geomPrimitive.cxx index ff30547ec6..a7ef2a3a2e 100644 --- a/panda/src/gobj/geomPrimitive.cxx +++ b/panda/src/gobj/geomPrimitive.cxx @@ -1483,50 +1483,6 @@ fillin(DatagramIterator &scan, BamReader *manager) { _got_minmax = false; } -//////////////////////////////////////////////////////////////////// -// Function: GeomPrimitivePipelineReader::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -GeomPrimitivePipelineReader:: -GeomPrimitivePipelineReader(const GeomPrimitive *object, - int pipeline_stage) : - _object(object), - _pipeline_stage(pipeline_stage), - _cdata(object->_cycler.read_stage(pipeline_stage)), - _vertices_reader(NULL) -{ - nassertv(_object->test_ref_count_nonzero()); -#ifdef DO_PIPELINING - nassertv(_cdata->test_ref_count_nonzero()); -#endif // DO_PIPELINING - if (_cdata->_vertices != (GeomVertexArrayData *)NULL) { - _vertices_reader = - new GeomVertexArrayDataPipelineReader(_cdata->_vertices, _pipeline_stage); - nassertv(_vertices_reader->get_object() == _cdata->_vertices); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: GeomPrimitivePipelineReader::Destructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -GeomPrimitivePipelineReader:: -~GeomPrimitivePipelineReader() { - if (_vertices_reader != (GeomVertexArrayDataPipelineReader *)NULL) { - nassertv(_vertices_reader->get_object() == _cdata->_vertices); - delete _vertices_reader; - _vertices_reader = NULL; - } - nassertv(_object->test_ref_count_nonzero()); -#ifdef DO_PIPELINING - nassertv(_cdata->test_ref_count_nonzero()); -#endif // DO_PIPELINING - _object->_cycler.release_read_stage(_pipeline_stage, _cdata); - _object = NULL; - _cdata = NULL; -} //////////////////////////////////////////////////////////////////// // Function: GeomPrimitivePipelineReader::get_first_vertex diff --git a/panda/src/gobj/geomPrimitive.h b/panda/src/gobj/geomPrimitive.h index ed2ddd8863..c6ba60e152 100644 --- a/panda/src/gobj/geomPrimitive.h +++ b/panda/src/gobj/geomPrimitive.h @@ -296,17 +296,17 @@ private: //////////////////////////////////////////////////////////////////// class EXPCL_PANDA GeomPrimitivePipelineReader : public GeomEnums { public: - GeomPrimitivePipelineReader(const GeomPrimitive *object, int pipeline_stage); + INLINE GeomPrimitivePipelineReader(const GeomPrimitive *object, Thread *current_thread); private: INLINE GeomPrimitivePipelineReader(const GeomPrimitivePipelineReader ©); INLINE void operator = (const GeomPrimitivePipelineReader ©); public: - ~GeomPrimitivePipelineReader(); + INLINE ~GeomPrimitivePipelineReader(); ALLOC_DELETED_CHAIN(GeomPrimitivePipelineReader); INLINE const GeomPrimitive *get_object() const; - INLINE int get_pipeline_stage() const; + INLINE Thread *get_current_thread() const; INLINE void check_minmax() const; @@ -331,7 +331,7 @@ public: private: const GeomPrimitive *_object; - int _pipeline_stage; + Thread *_current_thread; const GeomPrimitive::CData *_cdata; GeomVertexArrayDataPipelineReader *_vertices_reader; }; diff --git a/panda/src/gobj/geomVertexArrayData.I b/panda/src/gobj/geomVertexArrayData.I index d4781fb14d..8921c12e5e 100644 --- a/panda/src/gobj/geomVertexArrayData.I +++ b/panda/src/gobj/geomVertexArrayData.I @@ -62,7 +62,7 @@ has_column(const InternalName *name) const { //////////////////////////////////////////////////////////////////// INLINE int GeomVertexArrayData:: get_num_rows() const { - GeomVertexArrayDataPipelineReader reader(this, Thread::get_current_pipeline_stage()); + GeomVertexArrayDataPipelineReader reader(this, Thread::get_current_thread()); return reader.get_num_rows(); } @@ -89,7 +89,7 @@ get_num_rows() const { //////////////////////////////////////////////////////////////////// INLINE bool GeomVertexArrayData:: set_num_rows(int n) { - GeomVertexArrayDataPipelineWriter writer(this, Thread::get_current_pipeline_stage(), true); + GeomVertexArrayDataPipelineWriter writer(this, true, Thread::get_current_thread()); return writer.set_num_rows(n); } @@ -154,7 +154,7 @@ get_data() const { //////////////////////////////////////////////////////////////////// INLINE PTA_uchar GeomVertexArrayData:: modify_data() { - GeomVertexArrayDataPipelineWriter writer(this, Thread::get_current_pipeline_stage(), true); + GeomVertexArrayDataPipelineWriter writer(this, true, Thread::get_current_thread()); return writer.modify_data(); } @@ -170,7 +170,7 @@ modify_data() { //////////////////////////////////////////////////////////////////// INLINE void GeomVertexArrayData:: set_data(CPTA_uchar array) { - GeomVertexArrayDataPipelineWriter writer(this, Thread::get_current_pipeline_stage(), true); + GeomVertexArrayDataPipelineWriter writer(this, true, Thread::get_current_thread()); writer.set_data(array); } @@ -205,22 +205,22 @@ CData(const GeomVertexArrayData::CData ©) : //////////////////////////////////////////////////////////////////// INLINE GeomVertexArrayDataPipelineBase:: GeomVertexArrayDataPipelineBase(GeomVertexArrayData *object, - int pipeline_stage, + Thread *current_thread, GeomVertexArrayData::CData *cdata) : _object(object), - _pipeline_stage(pipeline_stage), + _current_thread(current_thread), _cdata(cdata) { } //////////////////////////////////////////////////////////////////// -// Function: GeomVertexArrayDataPipelineBase::get_pipeline_stage +// Function: GeomVertexArrayDataPipelineBase::get_current_thread // Access: Public // Description: //////////////////////////////////////////////////////////////////// -INLINE int GeomVertexArrayDataPipelineBase:: -get_pipeline_stage() const { - return _pipeline_stage; +INLINE Thread *GeomVertexArrayDataPipelineBase:: +get_current_thread() const { + return _current_thread; } //////////////////////////////////////////////////////////////////// @@ -290,15 +290,17 @@ get_modified() const { //////////////////////////////////////////////////////////////////// INLINE GeomVertexArrayDataPipelineReader:: GeomVertexArrayDataPipelineReader(const GeomVertexArrayData *object, - int pipeline_stage) : + Thread *current_thread) : GeomVertexArrayDataPipelineBase((GeomVertexArrayData *)object, - pipeline_stage, - (GeomVertexArrayData::CData *)object->_cycler.read_stage(pipeline_stage)) + current_thread, + (GeomVertexArrayData::CData *)object->_cycler.read(current_thread)) { +#ifdef _DEBUG nassertv(_object->test_ref_count_nonzero()); #ifdef DO_PIPELINING nassertv(_cdata->test_ref_count_nonzero()); #endif // DO_PIPELINING +#endif // _DEBUG } //////////////////////////////////////////////////////////////////// @@ -330,13 +332,18 @@ operator = (const GeomVertexArrayDataPipelineReader &) { //////////////////////////////////////////////////////////////////// INLINE GeomVertexArrayDataPipelineReader:: ~GeomVertexArrayDataPipelineReader() { +#ifdef _DEBUG nassertv(_object->test_ref_count_nonzero()); #ifdef DO_PIPELINING nassertv(_cdata->test_ref_count_nonzero()); #endif // DO_PIPELINING - _object->_cycler.release_read_stage(_pipeline_stage, _cdata); +#endif // _DEBUG + _object->_cycler.release_read(_cdata); + +#ifdef _DEBUG _object = NULL; _cdata = NULL; +#endif // _DEBUG } //////////////////////////////////////////////////////////////////// @@ -355,15 +362,17 @@ get_object() const { // Description: //////////////////////////////////////////////////////////////////// INLINE GeomVertexArrayDataPipelineWriter:: -GeomVertexArrayDataPipelineWriter(GeomVertexArrayData *object, - int pipeline_stage, bool force_to_0) : - GeomVertexArrayDataPipelineBase(object, pipeline_stage, - object->_cycler.write_stage_upstream(pipeline_stage, force_to_0)) +GeomVertexArrayDataPipelineWriter(GeomVertexArrayData *object, bool force_to_0, + Thread *current_thread) : + GeomVertexArrayDataPipelineBase(object, current_thread, + object->_cycler.write_upstream(force_to_0, current_thread)) { +#ifdef _DEBUG nassertv(_object->test_ref_count_nonzero()); #ifdef DO_PIPELINING nassertv(_cdata->test_ref_count_nonzero()); #endif // DO_PIPELINING +#endif // _DEBUG } //////////////////////////////////////////////////////////////////// @@ -395,13 +404,18 @@ operator = (const GeomVertexArrayDataPipelineWriter &) { //////////////////////////////////////////////////////////////////// INLINE GeomVertexArrayDataPipelineWriter:: ~GeomVertexArrayDataPipelineWriter() { +#ifdef _DEBUG nassertv(_object->test_ref_count_nonzero()); #ifdef DO_PIPELINING nassertv(_cdata->test_ref_count_nonzero()); #endif // DO_PIPELINING - _object->_cycler.release_write_stage(_pipeline_stage, _cdata); +#endif // _DEBUG + _object->_cycler.release_write(_cdata); + +#ifdef _DEBUG _object = NULL; _cdata = NULL; +#endif // _DEBUG } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/geomVertexArrayData.h b/panda/src/gobj/geomVertexArrayData.h index 23c6669334..a6e32b1f94 100644 --- a/panda/src/gobj/geomVertexArrayData.h +++ b/panda/src/gobj/geomVertexArrayData.h @@ -190,11 +190,11 @@ private: class EXPCL_PANDA GeomVertexArrayDataPipelineBase : public GeomEnums { protected: INLINE GeomVertexArrayDataPipelineBase(GeomVertexArrayData *object, - int pipeline_stage, + Thread *current_thread, GeomVertexArrayData::CData *cdata); public: - INLINE int get_pipeline_stage() const; + INLINE Thread *get_current_thread() const; INLINE const GeomVertexArrayFormat *get_array_format() const; @@ -206,7 +206,7 @@ public: protected: GeomVertexArrayData *_object; - int _pipeline_stage; + Thread *_current_thread; GeomVertexArrayData::CData *_cdata; }; @@ -217,7 +217,7 @@ protected: //////////////////////////////////////////////////////////////////// class EXPCL_PANDA GeomVertexArrayDataPipelineReader : public GeomVertexArrayDataPipelineBase { public: - INLINE GeomVertexArrayDataPipelineReader(const GeomVertexArrayData *object, int pipeline_stage); + INLINE GeomVertexArrayDataPipelineReader(const GeomVertexArrayData *object, Thread *current_thread); private: INLINE GeomVertexArrayDataPipelineReader(const GeomVertexArrayDataPipelineReader ©); INLINE void operator = (const GeomVertexArrayDataPipelineReader ©); @@ -236,7 +236,7 @@ public: //////////////////////////////////////////////////////////////////// class EXPCL_PANDA GeomVertexArrayDataPipelineWriter : public GeomVertexArrayDataPipelineBase { public: - INLINE GeomVertexArrayDataPipelineWriter(GeomVertexArrayData *object, int pipeline_stage, bool force_to_0); + INLINE GeomVertexArrayDataPipelineWriter(GeomVertexArrayData *object, bool force_to_0, Thread *current_thread); private: INLINE GeomVertexArrayDataPipelineWriter(const GeomVertexArrayDataPipelineWriter ©); INLINE void operator = (const GeomVertexArrayDataPipelineWriter ©); diff --git a/panda/src/gobj/geomVertexData.I b/panda/src/gobj/geomVertexData.I index 8afe90fc46..0361a9ba02 100644 --- a/panda/src/gobj/geomVertexData.I +++ b/panda/src/gobj/geomVertexData.I @@ -83,7 +83,7 @@ has_column(const InternalName *name) const { //////////////////////////////////////////////////////////////////// INLINE int GeomVertexData:: get_num_rows() const { - GeomVertexDataPipelineReader reader(this, Thread::get_current_pipeline_stage()); + GeomVertexDataPipelineReader reader(this, Thread::get_current_thread()); reader.check_array_readers(); return reader.get_num_rows(); } @@ -115,7 +115,7 @@ get_num_rows() const { //////////////////////////////////////////////////////////////////// INLINE bool GeomVertexData:: set_num_rows(int n) { - GeomVertexDataPipelineWriter writer(this, Thread::get_current_pipeline_stage(), true); + GeomVertexDataPipelineWriter writer(this, true, Thread::get_current_thread()); writer.check_array_writers(); return writer.set_num_rows(n); } @@ -163,7 +163,7 @@ get_array(int i) const { //////////////////////////////////////////////////////////////////// INLINE GeomVertexArrayData *GeomVertexData:: modify_array(int i) { - GeomVertexDataPipelineWriter writer(this, Thread::get_current_pipeline_stage(), true); + GeomVertexDataPipelineWriter writer(this, true, Thread::get_current_thread()); return writer.modify_array(i); } @@ -181,7 +181,7 @@ modify_array(int i) { //////////////////////////////////////////////////////////////////// INLINE void GeomVertexData:: set_array(int i, const GeomVertexArrayData *array) { - GeomVertexDataPipelineWriter writer(this, Thread::get_current_pipeline_stage(), true); + GeomVertexDataPipelineWriter writer(this, true, Thread::get_current_thread()); writer.set_array(i, array); } @@ -288,7 +288,7 @@ clear_slider_table() { //////////////////////////////////////////////////////////////////// INLINE int GeomVertexData:: get_num_bytes() const { - GeomVertexDataPipelineReader reader(this, Thread::get_current_pipeline_stage()); + GeomVertexDataPipelineReader reader(this, Thread::get_current_thread()); return reader.get_num_bytes(); } @@ -482,22 +482,22 @@ CData(const GeomVertexData::CData ©) : //////////////////////////////////////////////////////////////////// INLINE GeomVertexDataPipelineBase:: GeomVertexDataPipelineBase(GeomVertexData *object, - int pipeline_stage, - GeomVertexData::CData *cdata) : + Thread *current_thread, + GeomVertexData::CData *cdata) : _object(object), - _pipeline_stage(pipeline_stage), + _current_thread(current_thread), _cdata(cdata) { } //////////////////////////////////////////////////////////////////// -// Function: GeomVertexDataPipelineBase::get_pipeline_stage +// Function: GeomVertexDataPipelineBase::get_current_thread // Access: Public // Description: //////////////////////////////////////////////////////////////////// -INLINE int GeomVertexDataPipelineBase:: -get_pipeline_stage() const { - return _pipeline_stage; +INLINE Thread *GeomVertexDataPipelineBase:: +get_current_thread() const { + return _current_thread; } //////////////////////////////////////////////////////////////////// @@ -598,9 +598,9 @@ get_modified() const { //////////////////////////////////////////////////////////////////// INLINE GeomVertexDataPipelineReader:: GeomVertexDataPipelineReader(const GeomVertexData *object, - int pipeline_stage) : - GeomVertexDataPipelineBase((GeomVertexData *)object, pipeline_stage, - (GeomVertexData::CData *)object->_cycler.read_stage(pipeline_stage)), + Thread *current_thread) : + GeomVertexDataPipelineBase((GeomVertexData *)object, current_thread, + (GeomVertexData::CData *)object->_cycler.read(current_thread)), _got_array_readers(false) { nassertv(_object->test_ref_count_nonzero()); @@ -641,13 +641,18 @@ INLINE GeomVertexDataPipelineReader:: if (_got_array_readers) { delete_array_readers(); } +#ifdef _DEBUG nassertv(_object->test_ref_count_nonzero()); #ifdef DO_PIPELINING nassertv(_cdata->test_ref_count_nonzero()); #endif // DO_PIPELINING - _object->_cycler.release_read_stage(_pipeline_stage, _cdata); +#endif // _DEBUG + _object->_cycler.release_read(_cdata); + +#ifdef _DEBUG _object = NULL; _cdata = NULL; +#endif // _DEBUG } //////////////////////////////////////////////////////////////////// @@ -735,17 +740,19 @@ has_color() const { // Description: //////////////////////////////////////////////////////////////////// INLINE GeomVertexDataPipelineWriter:: -GeomVertexDataPipelineWriter(GeomVertexData *object, - int pipeline_stage, bool force_to_0) : - GeomVertexDataPipelineBase(object, pipeline_stage, - object->_cycler.write_stage_upstream(pipeline_stage, force_to_0)), +GeomVertexDataPipelineWriter(GeomVertexData *object, bool force_to_0, + Thread *current_thread) : + GeomVertexDataPipelineBase(object, current_thread, + object->_cycler.write_upstream(force_to_0, current_thread)), _force_to_0(force_to_0), _got_array_writers(false) { +#ifdef _DEBUG nassertv(_object->test_ref_count_nonzero()); #ifdef DO_PIPELINING nassertv(_cdata->test_ref_count_nonzero()); #endif // DO_PIPELINING +#endif // _DEBUG } //////////////////////////////////////////////////////////////////// @@ -780,13 +787,18 @@ INLINE GeomVertexDataPipelineWriter:: if (_got_array_writers) { delete_array_writers(); } +#ifdef _DEBUG nassertv(_object->test_ref_count_nonzero()); #ifdef DO_PIPELINING nassertv(_cdata->test_ref_count_nonzero()); #endif // DO_PIPELINING - _object->_cycler.release_write_stage(_pipeline_stage, _cdata); +#endif // _DEBUG + _object->_cycler.release_write(_cdata); + +#ifdef _DEBUG _object = NULL; _cdata = NULL; +#endif // _DEBUG } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/geomVertexData.cxx b/panda/src/gobj/geomVertexData.cxx index 00151e45ac..1e46c635ec 100644 --- a/panda/src/gobj/geomVertexData.cxx +++ b/panda/src/gobj/geomVertexData.cxx @@ -1713,7 +1713,7 @@ make_array_readers() { _array_readers.reserve(_cdata->_arrays.size()); GeomVertexData::Arrays::const_iterator ai; for (ai = _cdata->_arrays.begin(); ai != _cdata->_arrays.end(); ++ai) { - _array_readers.push_back(new GeomVertexArrayDataPipelineReader(*ai, _pipeline_stage)); + _array_readers.push_back(new GeomVertexArrayDataPipelineReader(*ai, _current_thread)); } _got_array_readers = true; @@ -1778,7 +1778,7 @@ set_num_rows(int n) { if (_cdata->_arrays[i]->get_ref_count() > 1) { delete _array_writers[i]; _cdata->_arrays[i] = new GeomVertexArrayData(*_cdata->_arrays[i]); - _array_writers[i] = new GeomVertexArrayDataPipelineWriter(_cdata->_arrays[i], _pipeline_stage, _force_to_0); + _array_writers[i] = new GeomVertexArrayDataPipelineWriter(_cdata->_arrays[i], _force_to_0, _current_thread); } if (_cdata->_arrays[i]->has_column(InternalName::get_color())) { color_array = i; @@ -1856,7 +1856,7 @@ modify_array(int i) { if (_got_array_writers) { delete _array_writers[i]; - _array_writers[i] = new GeomVertexArrayDataPipelineWriter(_cdata->_arrays[i], _pipeline_stage, _force_to_0); + _array_writers[i] = new GeomVertexArrayDataPipelineWriter(_cdata->_arrays[i], _force_to_0, _current_thread); } return _cdata->_arrays[i]; @@ -1877,7 +1877,7 @@ set_array(int i, const GeomVertexArrayData *array) { if (_got_array_writers) { delete _array_writers[i]; - _array_writers[i] = new GeomVertexArrayDataPipelineWriter(_cdata->_arrays[i], _pipeline_stage, _force_to_0); + _array_writers[i] = new GeomVertexArrayDataPipelineWriter(_cdata->_arrays[i], _force_to_0, _current_thread); } } @@ -1893,7 +1893,7 @@ make_array_writers() { _array_writers.reserve(_cdata->_arrays.size()); GeomVertexData::Arrays::const_iterator ai; for (ai = _cdata->_arrays.begin(); ai != _cdata->_arrays.end(); ++ai) { - _array_writers.push_back(new GeomVertexArrayDataPipelineWriter(*ai, _pipeline_stage, _force_to_0)); + _array_writers.push_back(new GeomVertexArrayDataPipelineWriter(*ai, _force_to_0, _current_thread)); } _got_array_writers = true; diff --git a/panda/src/gobj/geomVertexData.h b/panda/src/gobj/geomVertexData.h index d7112a35e3..01e255f78e 100644 --- a/panda/src/gobj/geomVertexData.h +++ b/panda/src/gobj/geomVertexData.h @@ -307,11 +307,11 @@ private: class EXPCL_PANDA GeomVertexDataPipelineBase : public GeomEnums { protected: INLINE GeomVertexDataPipelineBase(GeomVertexData *object, - int pipeline_stage, + Thread *current_thread, GeomVertexData::CData *cdata); public: - INLINE int get_pipeline_stage() const; + INLINE Thread *get_current_thread() const; INLINE const GeomVertexFormat *get_format() const; INLINE bool has_column(const InternalName *name) const; @@ -327,7 +327,7 @@ public: protected: GeomVertexData *_object; - int _pipeline_stage; + Thread *_current_thread; GeomVertexData::CData *_cdata; }; @@ -338,7 +338,7 @@ protected: //////////////////////////////////////////////////////////////////// class EXPCL_PANDA GeomVertexDataPipelineReader : public GeomVertexDataPipelineBase { public: - INLINE GeomVertexDataPipelineReader(const GeomVertexData *object, int pipeline_stage); + INLINE GeomVertexDataPipelineReader(const GeomVertexData *object, Thread *current_thread); private: INLINE GeomVertexDataPipelineReader(const GeomVertexDataPipelineReader ©); INLINE void operator = (const GeomVertexDataPipelineReader ©); @@ -390,8 +390,8 @@ private: //////////////////////////////////////////////////////////////////// class EXPCL_PANDA GeomVertexDataPipelineWriter : public GeomVertexDataPipelineBase { public: - INLINE GeomVertexDataPipelineWriter(GeomVertexData *object, int pipeline_stage, - bool force_to_0); + INLINE GeomVertexDataPipelineWriter(GeomVertexData *object, bool force_to_0, + Thread *current_thread); private: INLINE GeomVertexDataPipelineWriter(const GeomVertexDataPipelineWriter ©); INLINE void operator = (const GeomVertexDataPipelineWriter ©); diff --git a/panda/src/gobj/geomVertexReader.I b/panda/src/gobj/geomVertexReader.I index 996238991e..9455800404 100644 --- a/panda/src/gobj/geomVertexReader.I +++ b/panda/src/gobj/geomVertexReader.I @@ -42,7 +42,7 @@ GeomVertexReader() : //////////////////////////////////////////////////////////////////// INLINE GeomVertexReader:: GeomVertexReader(const GeomVertexData *vertex_data) : - _data_reader(new GeomVertexDataPipelineReader(vertex_data, Thread::get_current_pipeline_stage())), + _data_reader(new GeomVertexDataPipelineReader(vertex_data, Thread::get_current_thread())), _array_reader(NULL), _owns_reader(true) { @@ -58,7 +58,7 @@ GeomVertexReader(const GeomVertexData *vertex_data) : //////////////////////////////////////////////////////////////////// INLINE GeomVertexReader:: GeomVertexReader(const GeomVertexData *vertex_data, const string &name) : - _data_reader(new GeomVertexDataPipelineReader(vertex_data, Thread::get_current_pipeline_stage())), + _data_reader(new GeomVertexDataPipelineReader(vertex_data, Thread::get_current_thread())), _array_reader(NULL), _owns_reader(true) { @@ -76,7 +76,7 @@ GeomVertexReader(const GeomVertexData *vertex_data, const string &name) : INLINE GeomVertexReader:: GeomVertexReader(const GeomVertexData *vertex_data, const InternalName *name) : - _data_reader(new GeomVertexDataPipelineReader(vertex_data, Thread::get_current_pipeline_stage())), + _data_reader(new GeomVertexDataPipelineReader(vertex_data, Thread::get_current_thread())), _array_reader(NULL), _owns_reader(true) { @@ -93,7 +93,7 @@ GeomVertexReader(const GeomVertexData *vertex_data, INLINE GeomVertexReader:: GeomVertexReader(const GeomVertexArrayData *array_data) : _data_reader(NULL), - _array_reader(new GeomVertexArrayDataPipelineReader(array_data, Thread::get_current_pipeline_stage())), + _array_reader(new GeomVertexArrayDataPipelineReader(array_data, Thread::get_current_thread())), _owns_reader(true) { initialize(); @@ -108,7 +108,7 @@ GeomVertexReader(const GeomVertexArrayData *array_data) : INLINE GeomVertexReader:: GeomVertexReader(const GeomVertexArrayData *array_data, int column) : _data_reader(NULL), - _array_reader(new GeomVertexArrayDataPipelineReader(array_data, Thread::get_current_pipeline_stage())), + _array_reader(new GeomVertexArrayDataPipelineReader(array_data, Thread::get_current_thread())), _owns_reader(true) { initialize(); diff --git a/panda/src/gobj/geomVertexWriter.I b/panda/src/gobj/geomVertexWriter.I index abf9edbb63..fdd8e1344c 100644 --- a/panda/src/gobj/geomVertexWriter.I +++ b/panda/src/gobj/geomVertexWriter.I @@ -42,7 +42,7 @@ GeomVertexWriter() : //////////////////////////////////////////////////////////////////// INLINE GeomVertexWriter:: GeomVertexWriter(GeomVertexData *vertex_data) : - _data_writer(new GeomVertexDataPipelineWriter(vertex_data, Thread::get_current_pipeline_stage(), true)), + _data_writer(new GeomVertexDataPipelineWriter(vertex_data, true, Thread::get_current_thread())), _array_writer(NULL), _owns_writer(true) { @@ -58,7 +58,7 @@ GeomVertexWriter(GeomVertexData *vertex_data) : //////////////////////////////////////////////////////////////////// INLINE GeomVertexWriter:: GeomVertexWriter(GeomVertexData *vertex_data, const string &name) : - _data_writer(new GeomVertexDataPipelineWriter(vertex_data, Thread::get_current_pipeline_stage(), true)), + _data_writer(new GeomVertexDataPipelineWriter(vertex_data, true, Thread::get_current_thread())), _array_writer(NULL), _owns_writer(true) { @@ -75,7 +75,7 @@ GeomVertexWriter(GeomVertexData *vertex_data, const string &name) : //////////////////////////////////////////////////////////////////// INLINE GeomVertexWriter:: GeomVertexWriter(GeomVertexData *vertex_data, const InternalName *name) : - _data_writer(new GeomVertexDataPipelineWriter(vertex_data, Thread::get_current_pipeline_stage(), true)), + _data_writer(new GeomVertexDataPipelineWriter(vertex_data, true, Thread::get_current_thread())), _array_writer(NULL), _owns_writer(true) { @@ -92,7 +92,7 @@ GeomVertexWriter(GeomVertexData *vertex_data, const InternalName *name) : INLINE GeomVertexWriter:: GeomVertexWriter(GeomVertexArrayData *array_data) : _data_writer(NULL), - _array_writer(new GeomVertexArrayDataPipelineWriter(array_data, Thread::get_current_pipeline_stage(), true)), + _array_writer(new GeomVertexArrayDataPipelineWriter(array_data, true, Thread::get_current_thread())), _owns_writer(true) { initialize(); @@ -107,7 +107,7 @@ GeomVertexWriter(GeomVertexArrayData *array_data) : INLINE GeomVertexWriter:: GeomVertexWriter(GeomVertexArrayData *array_data, int column) : _data_writer(NULL), - _array_writer(new GeomVertexArrayDataPipelineWriter(array_data, Thread::get_current_pipeline_stage(), true)), + _array_writer(new GeomVertexArrayDataPipelineWriter(array_data, true, Thread::get_current_thread())), _owns_writer(true) { initialize(); diff --git a/panda/src/pipeline/cycleDataReader.I b/panda/src/pipeline/cycleDataReader.I index 91c4abc4cf..f06b6fd769 100644 --- a/panda/src/pipeline/cycleDataReader.I +++ b/panda/src/pipeline/cycleDataReader.I @@ -27,10 +27,12 @@ //////////////////////////////////////////////////////////////////// template INLINE CycleDataReader:: -CycleDataReader(const PipelineCycler &cycler) : - _cycler(&cycler) +CycleDataReader(const PipelineCycler &cycler, + Thread *current_thread) : + _cycler(&cycler), + _current_thread(current_thread) { - _pointer = _cycler->read(); + _pointer = _cycler->read(_current_thread); nassertv(_pointer != (const CycleDataType *)NULL); } @@ -43,6 +45,7 @@ template INLINE CycleDataReader:: CycleDataReader(const CycleDataReader ©) : _cycler(copy._cycler), + _current_thread(copy._current_thread), _pointer(copy._pointer) { nassertv(_pointer != (const CycleDataType *)NULL); @@ -58,6 +61,7 @@ template INLINE void CycleDataReader:: operator = (const CycleDataReader ©) { nassertv(_pointer == (CycleDataType *)NULL); + nassertv(_current_thread == copy._current_thread); _cycler = copy._cycler; _pointer = copy._pointer; @@ -124,6 +128,18 @@ take_pointer() { return pointer; } +//////////////////////////////////////////////////////////////////// +// Function: CycleDataReader::get_current_thread (full) +// Access: Public +// Description: Returns the Thread pointer of the currently-executing +// thread, as passed to the constructor of this object. +//////////////////////////////////////////////////////////////////// +template +INLINE Thread *CycleDataReader:: +get_current_thread() const { + return _current_thread; +} + #else // !DO_PIPELINING // This is the trivial, do-nothing implementation. @@ -134,8 +150,8 @@ take_pointer() { //////////////////////////////////////////////////////////////////// template INLINE CycleDataReader:: -CycleDataReader(const PipelineCycler &cycler) { - _pointer = cycler.read(); +CycleDataReader(const PipelineCycler &cycler, Thread *) { + _pointer = cycler.cheat(); } //////////////////////////////////////////////////////////////////// @@ -211,4 +227,16 @@ take_pointer() { return _pointer; } +//////////////////////////////////////////////////////////////////// +// Function: CycleDataReader::get_current_thread (trivial) +// Access: Public +// Description: Returns the Thread pointer of the currently-executing +// thread, as passed to the constructor of this object. +//////////////////////////////////////////////////////////////////// +template +INLINE Thread *CycleDataReader:: +get_current_thread() const { + return Thread::get_current_thread(); +} + #endif // DO_PIPELINING diff --git a/panda/src/pipeline/cycleDataReader.h b/panda/src/pipeline/cycleDataReader.h index cbfae4d1c3..f09df2bba4 100644 --- a/panda/src/pipeline/cycleDataReader.h +++ b/panda/src/pipeline/cycleDataReader.h @@ -23,6 +23,7 @@ #include "cycleData.h" #include "pipelineCycler.h" +#include "thread.h" //////////////////////////////////////////////////////////////////// // Class : CycleDataReader @@ -39,7 +40,8 @@ template class CycleDataReader { public: - INLINE CycleDataReader(const PipelineCycler &cycler); + INLINE CycleDataReader(const PipelineCycler &cycler, + Thread *current_thread = Thread::get_current_thread()); INLINE CycleDataReader(const CycleDataReader ©); INLINE void operator = (const CycleDataReader ©); @@ -49,11 +51,13 @@ public: INLINE operator const CycleDataType * () const; INLINE const CycleDataType *take_pointer(); + INLINE Thread *get_current_thread() const; private: #ifdef DO_PIPELINING // This is the data stored for a real pipelining implementation. const PipelineCycler *_cycler; + Thread *_current_thread; const CycleDataType *_pointer; CycleDataType *_write_pointer; #else // !DO_PIPELINING diff --git a/panda/src/pipeline/cycleDataStageReader.I b/panda/src/pipeline/cycleDataStageReader.I index 9f28525980..8bee04547e 100644 --- a/panda/src/pipeline/cycleDataStageReader.I +++ b/panda/src/pipeline/cycleDataStageReader.I @@ -29,11 +29,12 @@ template INLINE CycleDataStageReader:: CycleDataStageReader(const PipelineCycler &cycler, - int stage) : + int stage, Thread *current_thread) : _cycler(&cycler), + _current_thread(current_thread), _stage(stage) { - _pointer = _cycler->read_stage(_stage); + _pointer = _cycler->read_stage(_stage, _current_thread); nassertv(_pointer != (const CycleDataType *)NULL); } @@ -46,6 +47,7 @@ template INLINE CycleDataStageReader:: CycleDataStageReader(const CycleDataStageReader ©) : _cycler(copy._cycler), + _current_thread(copy._current_thread), _pointer(copy._pointer), _stage(copy._stage) { @@ -62,6 +64,7 @@ template INLINE void CycleDataStageReader:: operator = (const CycleDataStageReader ©) { nassertv(_pointer == (CycleDataType *)NULL); + nassertv(_current_thread == copy._current_thread); _cycler = copy._cycler; _pointer = copy._pointer; @@ -129,6 +132,18 @@ take_pointer() { return pointer; } +//////////////////////////////////////////////////////////////////// +// Function: CycleDataStageReader::get_current_thread (full) +// Access: Public +// Description: Returns the Thread pointer of the currently-executing +// thread, as passed to the constructor of this object. +//////////////////////////////////////////////////////////////////// +template +INLINE Thread *CycleDataStageReader:: +get_current_thread() const { + return _current_thread; +} + #else // !DO_PIPELINING // This is the trivial, do-nothing implementation. @@ -139,8 +154,9 @@ take_pointer() { //////////////////////////////////////////////////////////////////// template INLINE CycleDataStageReader:: -CycleDataStageReader(const PipelineCycler &cycler, int) { - _pointer = cycler.read(); +CycleDataStageReader(const PipelineCycler &cycler, int, + Thread *) { + _pointer = cycler.cheat(); } //////////////////////////////////////////////////////////////////// @@ -216,4 +232,16 @@ take_pointer() { return _pointer; } +//////////////////////////////////////////////////////////////////// +// Function: CycleDataStageReader::get_current_thread (trivial) +// Access: Public +// Description: Returns the Thread pointer of the currently-executing +// thread, as passed to the constructor of this object. +//////////////////////////////////////////////////////////////////// +template +INLINE Thread *CycleDataStageReader:: +get_current_thread() const { + return Thread::get_current_thread(); +} + #endif // DO_PIPELINING diff --git a/panda/src/pipeline/cycleDataStageReader.h b/panda/src/pipeline/cycleDataStageReader.h index 3bb320601c..0d86a3c43f 100644 --- a/panda/src/pipeline/cycleDataStageReader.h +++ b/panda/src/pipeline/cycleDataStageReader.h @@ -33,7 +33,8 @@ template class CycleDataStageReader { public: - INLINE CycleDataStageReader(const PipelineCycler &cycler, int stage); + INLINE CycleDataStageReader(const PipelineCycler &cycler, + int stage, Thread *current_thread = Thread::get_current_thread()); INLINE CycleDataStageReader(const CycleDataStageReader ©); INLINE void operator = (const CycleDataStageReader ©); @@ -43,11 +44,13 @@ public: INLINE operator const CycleDataType * () const; INLINE const CycleDataType *take_pointer(); + INLINE Thread *get_current_thread() const; private: #ifdef DO_PIPELINING // This is the data stored for a real pipelining implementation. const PipelineCycler *_cycler; + Thread *_current_thread; const CycleDataType *_pointer; int _stage; #else // !DO_PIPELINING diff --git a/panda/src/pipeline/cycleDataStageWriter.I b/panda/src/pipeline/cycleDataStageWriter.I index 73f185b397..11d20f9ff3 100644 --- a/panda/src/pipeline/cycleDataStageWriter.I +++ b/panda/src/pipeline/cycleDataStageWriter.I @@ -27,11 +27,13 @@ //////////////////////////////////////////////////////////////////// template INLINE CycleDataStageWriter:: -CycleDataStageWriter(PipelineCycler &cycler, int stage) : +CycleDataStageWriter(PipelineCycler &cycler, int stage, + Thread *current_thread) : _cycler(&cycler), + _current_thread(current_thread), _stage(stage) { - _pointer = _cycler->write_stage(_stage); + _pointer = _cycler->write_stage(_stage, _current_thread); nassertv(_pointer != (CycleDataType *)NULL); } @@ -43,11 +45,12 @@ CycleDataStageWriter(PipelineCycler &cycler, int stage) : template INLINE CycleDataStageWriter:: CycleDataStageWriter(PipelineCycler &cycler, int stage, - bool force_to_0) : + bool force_to_0, Thread *current_thread) : _cycler(&cycler), + _current_thread(current_thread), _stage(stage) { - _pointer = _cycler->write_stage_upstream(_stage, force_to_0); + _pointer = _cycler->write_stage_upstream(_stage, force_to_0, _current_thread); nassertv(_pointer != (CycleDataType *)NULL); } @@ -60,6 +63,7 @@ template INLINE CycleDataStageWriter:: CycleDataStageWriter(const CycleDataStageWriter ©) : _cycler(copy._cycler), + _current_thread(copy._current_thread), _pointer(copy._pointer), _stage(copy._stage) { @@ -76,6 +80,7 @@ template INLINE void CycleDataStageWriter:: operator = (const CycleDataStageWriter ©) { nassertv(_pointer == (CycleDataType *)NULL); + nassertv(_current_thread == copy._current_thread); _cycler = copy._cycler; _pointer = copy._pointer; @@ -97,9 +102,11 @@ INLINE CycleDataStageWriter:: CycleDataStageWriter(PipelineCycler &cycler, int stage, CycleDataStageReader &take_from) : _cycler(&cycler), + _current_thread(take_from.get_current_thread()), _stage(stage) { - _pointer = _cycler->elevate_read_stage(_stage, take_from.take_pointer()); + _pointer = _cycler->elevate_read_stage(_stage, take_from.take_pointer(), + _current_thread); } //////////////////////////////////////////////////////////////////// @@ -115,10 +122,11 @@ CycleDataStageWriter(PipelineCycler &cycler, int stage, CycleDataStageReader &take_from, bool force_to_0) : _cycler(&cycler), + _current_thread(take_from.get_current_thread()), _stage(stage) { _pointer = _cycler->elevate_read_stage_upstream(_stage, take_from.take_pointer(), - force_to_0); + force_to_0, _current_thread); } //////////////////////////////////////////////////////////////////// @@ -173,6 +181,18 @@ operator CycleDataType * () { return _pointer; } +//////////////////////////////////////////////////////////////////// +// Function: CycleDataStageWriter::get_current_thread (full) +// Access: Public +// Description: Returns the Thread pointer of the currently-executing +// thread, as passed to the constructor of this object. +//////////////////////////////////////////////////////////////////// +template +INLINE Thread *CycleDataStageWriter:: +get_current_thread() const { + return _current_thread; +} + #else // !DO_PIPELINING // This is the trivial, do-nothing implementation. @@ -183,8 +203,8 @@ operator CycleDataType * () { //////////////////////////////////////////////////////////////////// template INLINE CycleDataStageWriter:: -CycleDataStageWriter(PipelineCycler &cycler, int) { - _pointer = cycler.write(); +CycleDataStageWriter(PipelineCycler &cycler, int, Thread *) { + _pointer = cycler.cheat(); } //////////////////////////////////////////////////////////////////// @@ -194,8 +214,8 @@ CycleDataStageWriter(PipelineCycler &cycler, int) { //////////////////////////////////////////////////////////////////// template INLINE CycleDataStageWriter:: -CycleDataStageWriter(PipelineCycler &cycler, int, bool) { - _pointer = cycler.write(); +CycleDataStageWriter(PipelineCycler &cycler, int, bool, Thread *) { + _pointer = cycler.cheat(); } //////////////////////////////////////////////////////////////////// @@ -298,4 +318,16 @@ operator CycleDataType * () { return _pointer; } +//////////////////////////////////////////////////////////////////// +// Function: CycleDataStageWriter::get_current_thread (trivial) +// Access: Public +// Description: Returns the Thread pointer of the currently-executing +// thread, as passed to the constructor of this object. +//////////////////////////////////////////////////////////////////// +template +INLINE Thread *CycleDataStageWriter:: +get_current_thread() const { + return Thread::get_current_thread(); +} + #endif // DO_PIPELINING diff --git a/panda/src/pipeline/cycleDataStageWriter.h b/panda/src/pipeline/cycleDataStageWriter.h index 411ce3e68e..b79ec04749 100644 --- a/panda/src/pipeline/cycleDataStageWriter.h +++ b/panda/src/pipeline/cycleDataStageWriter.h @@ -37,9 +37,11 @@ template class CycleDataStageWriter { public: - INLINE CycleDataStageWriter(PipelineCycler &cycler, int stage); INLINE CycleDataStageWriter(PipelineCycler &cycler, int stage, - bool force_to_0); + Thread *current_thread = Thread::get_current_thread()); + INLINE CycleDataStageWriter(PipelineCycler &cycler, int stage, + bool force_to_0, Thread *current_thread = Thread::get_current_thread()); + INLINE CycleDataStageWriter(const CycleDataStageWriter ©); INLINE void operator = (const CycleDataStageWriter ©); @@ -56,10 +58,13 @@ public: INLINE operator CycleDataType * (); + INLINE Thread *get_current_thread() const; + private: #ifdef DO_PIPELINING // This is the data stored for a real pipelining implementation. PipelineCycler *_cycler; + Thread *_current_thread; CycleDataType *_pointer; int _stage; #else // !DO_PIPELINING diff --git a/panda/src/pipeline/cycleDataWriter.I b/panda/src/pipeline/cycleDataWriter.I index d33b9db49f..a01dcf0463 100644 --- a/panda/src/pipeline/cycleDataWriter.I +++ b/panda/src/pipeline/cycleDataWriter.I @@ -27,10 +27,11 @@ //////////////////////////////////////////////////////////////////// template INLINE CycleDataWriter:: -CycleDataWriter(PipelineCycler &cycler) : - _cycler(&cycler) +CycleDataWriter(PipelineCycler &cycler, Thread *current_thread) : + _cycler(&cycler), + _current_thread(current_thread) { - _pointer = _cycler->write(); + _pointer = _cycler->write(_current_thread); nassertv(_pointer != (CycleDataType *)NULL); } @@ -47,10 +48,12 @@ CycleDataWriter(PipelineCycler &cycler) : //////////////////////////////////////////////////////////////////// template INLINE CycleDataWriter:: -CycleDataWriter(PipelineCycler &cycler, bool force_to_0) : - _cycler(&cycler) +CycleDataWriter(PipelineCycler &cycler, bool force_to_0, + Thread *current_thread) : + _cycler(&cycler), + _current_thread(current_thread) { - _pointer = _cycler->write_upstream(force_to_0); + _pointer = _cycler->write_upstream(force_to_0, _current_thread); nassertv(_pointer != (CycleDataType *)NULL); } @@ -63,6 +66,7 @@ template INLINE CycleDataWriter:: CycleDataWriter(const CycleDataWriter ©) : _cycler(copy._cycler), + _current_thread(copy._current_thread), _pointer(copy._pointer) { nassertv(_pointer != (CycleDataType *)NULL); @@ -78,6 +82,7 @@ template INLINE void CycleDataWriter:: operator = (const CycleDataWriter ©) { nassertv(_pointer == (CycleDataType *)NULL); + nassertv(_current_thread == copy._current_thread); _cycler = copy._cycler; _pointer = copy._pointer; @@ -97,9 +102,10 @@ template INLINE CycleDataWriter:: CycleDataWriter(PipelineCycler &cycler, CycleDataReader &take_from) : - _cycler(&cycler) + _cycler(&cycler), + _current_thread(take_from.get_current_thread()) { - _pointer = _cycler->elevate_read(take_from.take_pointer()); + _pointer = _cycler->elevate_read(take_from.take_pointer(), _current_thread); } //////////////////////////////////////////////////////////////////// @@ -116,9 +122,11 @@ INLINE CycleDataWriter:: CycleDataWriter(PipelineCycler &cycler, CycleDataReader &take_from, bool force_to_0) : - _cycler(&cycler) + _cycler(&cycler), + _current_thread(take_from.get_current_thread()) { - _pointer = _cycler->elevate_read_upstream(take_from.take_pointer(), force_to_0); + _pointer = _cycler->elevate_read_upstream(take_from.take_pointer(), + force_to_0, _current_thread); } //////////////////////////////////////////////////////////////////// @@ -173,6 +181,18 @@ operator CycleDataType * () { return _pointer; } +//////////////////////////////////////////////////////////////////// +// Function: CycleDataWriter::get_current_thread (full) +// Access: Public +// Description: Returns the Thread pointer of the currently-executing +// thread, as passed to the constructor of this object. +//////////////////////////////////////////////////////////////////// +template +INLINE Thread *CycleDataWriter:: +get_current_thread() const { + return _current_thread; +} + #else // !DO_PIPELINING // This is the trivial, do-nothing implementation. @@ -183,25 +203,19 @@ operator CycleDataType * () { //////////////////////////////////////////////////////////////////// template INLINE CycleDataWriter:: -CycleDataWriter(PipelineCycler &cycler) { - _pointer = cycler.write(); +CycleDataWriter(PipelineCycler &cycler, Thread *) { + _pointer = cycler.cheat(); } //////////////////////////////////////////////////////////////////// -// Function: CycleDataWriter::Constructor (full) +// Function: CycleDataWriter::Constructor (trivial) // Access: Public -// Description: This two-parameter constructor, with a bool parameter -// for the second parameter, automatically propagates -// the CycleData pointer upstream from the current -// stage, either stopping at the first pointer -// encountered that's different, going or all the way to -// stage 0, according to force_to_0. See -// PipelineCycler::write_upstream(). +// Description: //////////////////////////////////////////////////////////////////// template INLINE CycleDataWriter:: -CycleDataWriter(PipelineCycler &cycler, bool) { - _pointer = cycler.write(); +CycleDataWriter(PipelineCycler &cycler, bool, Thread *) { + _pointer = cycler.cheat(); } //////////////////////////////////////////////////////////////////// @@ -306,4 +320,16 @@ operator CycleDataType * () { return _pointer; } +//////////////////////////////////////////////////////////////////// +// Function: CycleDataWriter::get_current_thread (trivial) +// Access: Public +// Description: Returns the Thread pointer of the currently-executing +// thread, as passed to the constructor of this object. +//////////////////////////////////////////////////////////////////// +template +INLINE Thread *CycleDataWriter:: +get_current_thread() const { + return Thread::get_current_thread(); +} + #endif // DO_PIPELINING diff --git a/panda/src/pipeline/cycleDataWriter.h b/panda/src/pipeline/cycleDataWriter.h index fbddff3101..9f7c1bfa4e 100644 --- a/panda/src/pipeline/cycleDataWriter.h +++ b/panda/src/pipeline/cycleDataWriter.h @@ -24,6 +24,7 @@ #include "cycleData.h" #include "pipelineCycler.h" #include "cycleDataReader.h" +#include "thread.h" //////////////////////////////////////////////////////////////////// // Class : CycleDataWriter @@ -40,8 +41,10 @@ template class CycleDataWriter { public: - INLINE CycleDataWriter(PipelineCycler &cycler); - INLINE CycleDataWriter(PipelineCycler &cycler, bool force_to_0); + INLINE CycleDataWriter(PipelineCycler &cycler, + Thread *current_thread = Thread::get_current_thread()); + INLINE CycleDataWriter(PipelineCycler &cycler, bool force_to_0, + Thread *current_thread = Thread::get_current_thread()); INLINE CycleDataWriter(const CycleDataWriter ©); INLINE void operator = (const CycleDataWriter ©); @@ -55,10 +58,13 @@ public: INLINE operator CycleDataType * (); + INLINE Thread *get_current_thread() const; + private: #ifdef DO_PIPELINING // This is the data stored for a real pipelining implementation. PipelineCycler *_cycler; + Thread *_current_thread; CycleDataType *_pointer; #else // !DO_PIPELINING // This is all we need for the trivial, do-nothing implementation. diff --git a/panda/src/pipeline/mutexDebug.I b/panda/src/pipeline/mutexDebug.I index 34ceb0dd42..69431e4116 100755 --- a/panda/src/pipeline/mutexDebug.I +++ b/panda/src/pipeline/mutexDebug.I @@ -60,6 +60,51 @@ lock() const { _global_mutex.release(); } +//////////////////////////////////////////////////////////////////// +// Function: MutexDebug::lock +// Access: Public +// Description: This variant on lock() accepts the current thread as +// a parameter, if it is already known, as an +// optimization. +//////////////////////////////////////////////////////////////////// +INLINE void MutexDebug:: +lock(Thread *current_thread) const { + TAU_PROFILE("void MutexDebug::lock(Thread *)", " ", TAU_USER); + nassertv(current_thread == Thread::get_current_thread()); + // You may only pass a Thread parameter to a ReMutex--that is, to a + // mutex whose _allow_recursion flag is true. + nassertv(_allow_recursion); + lock(); +} + +//////////////////////////////////////////////////////////////////// +// Function: MutexDebug::elevate_lock +// Access: Public +// Description: This method increments the lock count, assuming the +// calling thread already holds the lock. After this +// call, release() will need to be called one additional +// time to release the lock. +// +// This method really performs the same function as +// lock(), but it offers a potential (slight) +// performance benefit when the calling thread knows +// that it already holds the lock. It is an error to +// call this when the calling thread does not hold the +// lock. +//////////////////////////////////////////////////////////////////// +INLINE void MutexDebug:: +elevate_lock() const { + TAU_PROFILE("void MutexDebug::elevate_lock()", " ", TAU_USER); + // You may only pass call elevate_lock() on a ReMutex--that is, to a + // mutex whose _allow_recursion flag is true. + nassertv(_allow_recursion); + + // Also, it's an error to call this if the lock is not already held. + nassertv(debug_is_locked()); + + lock(); +} + //////////////////////////////////////////////////////////////////// // Function: MutexDebug::release // Access: Public diff --git a/panda/src/pipeline/mutexDebug.h b/panda/src/pipeline/mutexDebug.h index f504c8c7a9..5689ff7fe9 100644 --- a/panda/src/pipeline/mutexDebug.h +++ b/panda/src/pipeline/mutexDebug.h @@ -43,6 +43,8 @@ private: public: INLINE void lock() const; + INLINE void lock(Thread *current_thread) const; + INLINE void elevate_lock() const; INLINE void release() const; INLINE bool debug_is_locked() const; diff --git a/panda/src/pipeline/pipelineCycler.I b/panda/src/pipeline/pipelineCycler.I index 19be7b9393..4cbb0a7324 100644 --- a/panda/src/pipeline/pipelineCycler.I +++ b/panda/src/pipeline/pipelineCycler.I @@ -63,19 +63,8 @@ operator = (const PipelineCycler ©) { //////////////////////////////////////////////////////////////////// template INLINE const CycleDataType *PipelineCycler:: -read() const { - return (const CycleDataType *)PipelineCyclerBase::read(); -} - -//////////////////////////////////////////////////////////////////// -// Function: PipelineCycler::read (dummy or true) -// Access: Public -// Description: See PipelineCyclerBase::read_stage(). -//////////////////////////////////////////////////////////////////// -template -INLINE const CycleDataType *PipelineCycler:: -read_stage(int n) const { - return (const CycleDataType *)PipelineCyclerBase::read_stage(n); +read(Thread *current_thread) const { + return (const CycleDataType *)PipelineCyclerBase::read(current_thread); } //////////////////////////////////////////////////////////////////// @@ -85,52 +74,8 @@ read_stage(int n) const { //////////////////////////////////////////////////////////////////// template INLINE CycleDataType *PipelineCycler:: -write() { - return (CycleDataType *)PipelineCyclerBase::write(); -} - -//////////////////////////////////////////////////////////////////// -// Function: PipelineCycler::elevate_read (dummy or true) -// Access: Public -// Description: See PipelineCyclerBase::elevate_read(). -//////////////////////////////////////////////////////////////////// -template -INLINE CycleDataType *PipelineCycler:: -elevate_read(const CycleDataType *pointer) { - return (CycleDataType *)PipelineCyclerBase::elevate_read(pointer); -} - -//////////////////////////////////////////////////////////////////// -// Function: PipelineCycler::elevate_read_upstream (dummy or true) -// Access: Public -// Description: See PipelineCyclerBase::elevate_read_upstream(). -//////////////////////////////////////////////////////////////////// -template -INLINE CycleDataType *PipelineCycler:: -elevate_read_upstream(const CycleDataType *pointer, bool force_to_0) { - return (CycleDataType *)PipelineCyclerBase::elevate_read_upstream(pointer, force_to_0); -} - -//////////////////////////////////////////////////////////////////// -// Function: PipelineCycler::elevate_read_stage (dummy or true) -// Access: Public -// Description: See PipelineCyclerBase::elevate_read_stage(). -//////////////////////////////////////////////////////////////////// -template -INLINE CycleDataType *PipelineCycler:: -elevate_read_stage(int n, const CycleDataType *pointer) { - return (CycleDataType *)PipelineCyclerBase::elevate_read_stage(n, pointer); -} - -//////////////////////////////////////////////////////////////////// -// Function: PipelineCycler::elevate_read_stage_upstream (dummy or true) -// Access: Public -// Description: See PipelineCyclerBase::elevate_read_stage_upstream(). -//////////////////////////////////////////////////////////////////// -template -INLINE CycleDataType *PipelineCycler:: -elevate_read_stage_upstream(int n, const CycleDataType *pointer, bool force_to_0) { - return (CycleDataType *)PipelineCyclerBase::elevate_read_stage_upstream(n, pointer, force_to_0); +write(Thread *current_thread) { + return (CycleDataType *)PipelineCyclerBase::write(current_thread); } //////////////////////////////////////////////////////////////////// @@ -140,8 +85,66 @@ elevate_read_stage_upstream(int n, const CycleDataType *pointer, bool force_to_0 //////////////////////////////////////////////////////////////////// template INLINE CycleDataType *PipelineCycler:: -write_upstream(bool force_to_0) { - return (CycleDataType *)PipelineCyclerBase::write_upstream(force_to_0); +write_upstream(bool force_to_0, Thread *current_thread) { + return (CycleDataType *)PipelineCyclerBase::write_upstream(force_to_0, current_thread); +} + +//////////////////////////////////////////////////////////////////// +// Function: PipelineCycler::elevate_read (dummy or true) +// Access: Public +// Description: See PipelineCyclerBase::elevate_read(). +//////////////////////////////////////////////////////////////////// +template +INLINE CycleDataType *PipelineCycler:: +elevate_read(const CycleDataType *pointer, Thread *current_thread) { + return (CycleDataType *)PipelineCyclerBase::elevate_read(pointer, current_thread); +} + +//////////////////////////////////////////////////////////////////// +// Function: PipelineCycler::elevate_read_upstream (dummy or true) +// Access: Public +// Description: See PipelineCyclerBase::elevate_read_upstream(). +//////////////////////////////////////////////////////////////////// +template +INLINE CycleDataType *PipelineCycler:: +elevate_read_upstream(const CycleDataType *pointer, bool force_to_0, + Thread *current_thread) { + return (CycleDataType *)PipelineCyclerBase::elevate_read_upstream(pointer, force_to_0, current_thread); +} + +//////////////////////////////////////////////////////////////////// +// Function: PipelineCycler::read (dummy or true) +// Access: Public +// Description: See PipelineCyclerBase::read_stage(). +//////////////////////////////////////////////////////////////////// +template +INLINE const CycleDataType *PipelineCycler:: +read_stage(int pipeline_stage, Thread *current_thread) const { + return (const CycleDataType *)PipelineCyclerBase::read_stage(pipeline_stage, current_thread); +} + +//////////////////////////////////////////////////////////////////// +// Function: PipelineCycler::elevate_read_stage (dummy or true) +// Access: Public +// Description: See PipelineCyclerBase::elevate_read_stage(). +//////////////////////////////////////////////////////////////////// +template +INLINE CycleDataType *PipelineCycler:: +elevate_read_stage(int pipeline_stage, const CycleDataType *pointer, + Thread *current_thread) { + return (CycleDataType *)PipelineCyclerBase::elevate_read_stage(pipeline_stage, pointer, current_thread); +} + +//////////////////////////////////////////////////////////////////// +// Function: PipelineCycler::elevate_read_stage_upstream (dummy or true) +// Access: Public +// Description: See PipelineCyclerBase::elevate_read_stage_upstream(). +//////////////////////////////////////////////////////////////////// +template +INLINE CycleDataType *PipelineCycler:: +elevate_read_stage_upstream(int pipeline_stage, const CycleDataType *pointer, + bool force_to_0, Thread *current_thread) { + return (CycleDataType *)PipelineCyclerBase::elevate_read_stage_upstream(pipeline_stage, pointer, force_to_0, current_thread); } //////////////////////////////////////////////////////////////////// @@ -151,8 +154,8 @@ write_upstream(bool force_to_0) { //////////////////////////////////////////////////////////////////// template INLINE CycleDataType *PipelineCycler:: -write_stage(int n) { - return (CycleDataType *)PipelineCyclerBase::write_stage(n); +write_stage(int pipeline_stage, Thread *current_thread) { + return (CycleDataType *)PipelineCyclerBase::write_stage(pipeline_stage, current_thread); } //////////////////////////////////////////////////////////////////// @@ -162,8 +165,9 @@ write_stage(int n) { //////////////////////////////////////////////////////////////////// template INLINE CycleDataType *PipelineCycler:: -write_stage_upstream(int pipeline_stage, bool force_to_0) { - return (CycleDataType *)PipelineCyclerBase::write_stage_upstream(pipeline_stage, force_to_0); +write_stage_upstream(int pipeline_stage, bool force_to_0, + Thread *current_thread) { + return (CycleDataType *)PipelineCyclerBase::write_stage_upstream(pipeline_stage, force_to_0, current_thread); } //////////////////////////////////////////////////////////////////// @@ -230,18 +234,7 @@ operator = (const PipelineCycler ©) { //////////////////////////////////////////////////////////////////// template INLINE const CycleDataType *PipelineCycler:: -read() const { - return &_typed_data; -} - -//////////////////////////////////////////////////////////////////// -// Function: PipelineCycler::read_stage (trivial) -// Access: Public -// Description: See PipelineCyclerBase::read_stage(). -//////////////////////////////////////////////////////////////////// -template -INLINE const CycleDataType *PipelineCycler:: -read_stage(int) const { +read(Thread *) const { return &_typed_data; } @@ -252,51 +245,7 @@ read_stage(int) const { //////////////////////////////////////////////////////////////////// template INLINE CycleDataType *PipelineCycler:: -write() { - return &_typed_data; -} - -//////////////////////////////////////////////////////////////////// -// Function: PipelineCycler::elevate_read (trivial) -// Access: Public -// Description: See PipelineCyclerBase::elevate_read(). -//////////////////////////////////////////////////////////////////// -template -INLINE CycleDataType *PipelineCycler:: -elevate_read(const CycleDataType *) { - return &_typed_data; -} - -//////////////////////////////////////////////////////////////////// -// Function: PipelineCycler::elevate_read_upstream (trivial) -// Access: Public -// Description: See PipelineCyclerBase::elevate_read_upstream(). -//////////////////////////////////////////////////////////////////// -template -INLINE CycleDataType *PipelineCycler:: -elevate_read_upstream(const CycleDataType *, bool) { - return &_typed_data; -} - -//////////////////////////////////////////////////////////////////// -// Function: PipelineCycler::elevate_read_stage (trivial) -// Access: Public -// Description: See PipelineCyclerBase::elevate_read_stage(). -//////////////////////////////////////////////////////////////////// -template -INLINE CycleDataType *PipelineCycler:: -elevate_read_stage(int, const CycleDataType *) { - return &_typed_data; -} - -//////////////////////////////////////////////////////////////////// -// Function: PipelineCycler::elevate_read_stage_upstream (trivial) -// Access: Public -// Description: See PipelineCyclerBase::elevate_read_stage_upstream(). -//////////////////////////////////////////////////////////////////// -template -INLINE CycleDataType *PipelineCycler:: -elevate_read_stage_upstream(int, const CycleDataType *, bool) { +write(Thread *) { return &_typed_data; } @@ -307,7 +256,62 @@ elevate_read_stage_upstream(int, const CycleDataType *, bool) { //////////////////////////////////////////////////////////////////// template INLINE CycleDataType *PipelineCycler:: -write_upstream(bool) { +write_upstream(bool, Thread *) { + return &_typed_data; +} + +//////////////////////////////////////////////////////////////////// +// Function: PipelineCycler::elevate_read (trivial) +// Access: Public +// Description: See PipelineCyclerBase::elevate_read(). +//////////////////////////////////////////////////////////////////// +template +INLINE CycleDataType *PipelineCycler:: +elevate_read(const CycleDataType *, Thread *) { + return &_typed_data; +} + +//////////////////////////////////////////////////////////////////// +// Function: PipelineCycler::elevate_read_upstream (trivial) +// Access: Public +// Description: See PipelineCyclerBase::elevate_read_upstream(). +//////////////////////////////////////////////////////////////////// +template +INLINE CycleDataType *PipelineCycler:: +elevate_read_upstream(const CycleDataType *, bool, Thread *) { + return &_typed_data; +} + +//////////////////////////////////////////////////////////////////// +// Function: PipelineCycler::read_stage (trivial) +// Access: Public +// Description: See PipelineCyclerBase::read_stage(). +//////////////////////////////////////////////////////////////////// +template +INLINE const CycleDataType *PipelineCycler:: +read_stage(int, Thread *) const { + return &_typed_data; +} + +//////////////////////////////////////////////////////////////////// +// Function: PipelineCycler::elevate_read_stage (trivial) +// Access: Public +// Description: See PipelineCyclerBase::elevate_read_stage(). +//////////////////////////////////////////////////////////////////// +template +INLINE CycleDataType *PipelineCycler:: +elevate_read_stage(int, const CycleDataType *, Thread *) { + return &_typed_data; +} + +//////////////////////////////////////////////////////////////////// +// Function: PipelineCycler::elevate_read_stage_upstream (trivial) +// Access: Public +// Description: See PipelineCyclerBase::elevate_read_stage_upstream(). +//////////////////////////////////////////////////////////////////// +template +INLINE CycleDataType *PipelineCycler:: +elevate_read_stage_upstream(int, const CycleDataType *, bool, Thread *) { return &_typed_data; } @@ -318,7 +322,7 @@ write_upstream(bool) { //////////////////////////////////////////////////////////////////// template INLINE CycleDataType *PipelineCycler:: -write_stage(int) { +write_stage(int, Thread *) { return &_typed_data; } @@ -329,7 +333,7 @@ write_stage(int) { //////////////////////////////////////////////////////////////////// template INLINE CycleDataType *PipelineCycler:: -write_stage_upstream(int, bool) { +write_stage_upstream(int, bool, Thread *) { return &_typed_data; } diff --git a/panda/src/pipeline/pipelineCycler.h b/panda/src/pipeline/pipelineCycler.h index a464b8aa1d..f96f0ecaad 100644 --- a/panda/src/pipeline/pipelineCycler.h +++ b/panda/src/pipeline/pipelineCycler.h @@ -22,7 +22,7 @@ #include "pandabase.h" #include "pipelineCyclerBase.h" #include "cyclerHolder.h" -#include "thread.h" // for convenience of code that uses PipelineReader classes +#include "thread.h" //////////////////////////////////////////////////////////////////// // Class : PipelineCycler @@ -63,16 +63,17 @@ public: INLINE PipelineCycler(const PipelineCycler ©); INLINE void operator = (const PipelineCycler ©); - INLINE const CycleDataType *read() const; - INLINE const CycleDataType *read_stage(int n) const; - INLINE CycleDataType *write(); - INLINE CycleDataType *elevate_read(const CycleDataType *pointer); - INLINE CycleDataType *elevate_read_upstream(const CycleDataType *pointer, bool force_to_0); - INLINE CycleDataType *elevate_read_stage(int n, const CycleDataType *pointer); - INLINE CycleDataType *elevate_read_stage_upstream(int n, const CycleDataType *pointer, bool force_to_0); - INLINE CycleDataType *write_upstream(bool force_to_0); - INLINE CycleDataType *write_stage_upstream(int pipeline_stage, bool force_to_0); - INLINE CycleDataType *write_stage(int n); + INLINE const CycleDataType *read(Thread *current_thread) const; + INLINE CycleDataType *write(Thread *current_thread); + INLINE CycleDataType *write_upstream(bool force_to_0, Thread *current_thread); + INLINE CycleDataType *elevate_read(const CycleDataType *pointer, Thread *current_thread); + INLINE CycleDataType *elevate_read_upstream(const CycleDataType *pointer, bool force_to_0, Thread *current_thread); + + INLINE const CycleDataType *read_stage(int pipeline_stage, Thread *current_thread) const; + INLINE CycleDataType *elevate_read_stage(int pipeline_stage, const CycleDataType *pointer, Thread *current_thread); + INLINE CycleDataType *elevate_read_stage_upstream(int pipeline_stage, const CycleDataType *pointer, bool force_to_0, Thread *current_thread); + INLINE CycleDataType *write_stage_upstream(int pipeline_stage, bool force_to_0, Thread *current_thread); + INLINE CycleDataType *write_stage(int pipeline_stage, Thread *current_thread); INLINE CycleDataType *cheat() const; diff --git a/panda/src/pipeline/pipelineCyclerDummyImpl.I b/panda/src/pipeline/pipelineCyclerDummyImpl.I index d2e855783a..8e3767a339 100644 --- a/panda/src/pipeline/pipelineCyclerDummyImpl.I +++ b/panda/src/pipeline/pipelineCyclerDummyImpl.I @@ -80,8 +80,8 @@ INLINE PipelineCyclerDummyImpl:: // walking the list of stages. //////////////////////////////////////////////////////////////////// INLINE void PipelineCyclerDummyImpl:: -lock() { - TAU_PROFILE("void PipelineCyclerDummyImpl::lock()", " ", TAU_USER); +lock(Thread *) { + TAU_PROFILE("void PipelineCyclerDummyImpl::lock(Thread *)", " ", TAU_USER); nassertv(!_locked); _locked = true; } @@ -111,7 +111,7 @@ release() { // data when this function is called. //////////////////////////////////////////////////////////////////// INLINE const CycleData *PipelineCyclerDummyImpl:: -read() const { +read(Thread *) const { TAU_PROFILE("const CycleData *PipelineCyclerDummyImpl::read()", " ", TAU_USER); // This function isn't truly const, but it doesn't change the data // in any meaningful way, so we pretend it is. @@ -172,7 +172,7 @@ release_read(const CycleData *pointer) const { // stage (but see elevate_read). //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerDummyImpl:: -write() { +write(Thread *) { TAU_PROFILE("CycleData *PipelineCyclerDummyImpl::write()", " ", TAU_USER); _write_count++; @@ -186,6 +186,42 @@ write() { return _data; } +//////////////////////////////////////////////////////////////////// +// Function: PipelineCyclerDummyImpl::write_upstream +// Access: Public +// Description: This special variant on write() will automatically +// propagate changes back to upstream pipeline stages. +// If force_to_0 is false, then it propagates back only +// as long as the CycleData pointers are equivalent, +// guaranteeing that it does not modify upstream data +// (other than the modification that will be performed +// by the code that returns this pointer). This is +// particularly appropriate for minor updates, where it +// doesn't matter much if the update is lost, such as +// storing a cached value. +// +// If force_to_0 is dummy, then the CycleData pointer for +// the current pipeline stage is propagated all the way +// back up to stage 0; after this call, there will be +// only one CycleData pointer that is duplicated in all +// stages between stage 0 and the current stage. This +// may undo some recent changes that were made +// independently at pipeline stage 0 (or any other +// upstream stage). However, it guarantees that the +// change that is to be applied at this pipeline stage +// will stick. This is slightly dangerous because of +// the risk of losing upstream changes; generally, this +// should only be done when you are confident that there +// are no upstream changes to be lost (for instance, for +// an object that has been recently created). +//////////////////////////////////////////////////////////////////// +CycleData *PipelineCyclerDummyImpl:: +write_upstream(bool, Thread *) { + TAU_PROFILE("CycleData *PipelineCyclerDummyImpl::write_upstream(bool)", " ", TAU_USER); + _write_count++; + return _data; +} + //////////////////////////////////////////////////////////////////// // Function: PipelineCyclerDummyImpl::elevate_read // Access: Public @@ -196,7 +232,7 @@ write() { // current stage. //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerDummyImpl:: -elevate_read(const CycleData *pointer) { +elevate_read(const CycleData *pointer, Thread *) { TAU_PROFILE("CycleData *PipelineCyclerDummyImpl::elevate_read(const CycleData *)", " ", TAU_USER); release_read(pointer); return write(); @@ -211,7 +247,7 @@ elevate_read(const CycleData *pointer) { // write_upstream(). //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerDummyImpl:: -elevate_read_upstream(const CycleData *pointer, bool force_to_0) { +elevate_read_upstream(const CycleData *pointer, bool force_to_0, Thread *) { TAU_PROFILE("CycleData *PipelineCyclerDummyImpl::elevate_read_upstream(const CycleData *, bool)", " ", TAU_USER); release_read(pointer); return write_upstream(force_to_0); @@ -270,11 +306,11 @@ get_num_stages() { // data when this function is called. //////////////////////////////////////////////////////////////////// INLINE const CycleData *PipelineCyclerDummyImpl:: -read_stage(int n) const { +read_stage(int pipeline_stage, Thread *) const { TAU_PROFILE("const CycleData *PipelineCyclerDummyImpl::read_stage(int)", " ", TAU_USER); // This function isn't truly const, but it doesn't change the data // in any meaningful way, so we pretend it is. - nassertr(n == 0, NULL); + nassertr(pipeline_stage == 0, NULL); ((PipelineCyclerDummyImpl *)this)->_read_count++; // It's not an error to grab a read pointer while someone else holds @@ -289,52 +325,16 @@ read_stage(int n) const { // read_stage(). //////////////////////////////////////////////////////////////////// INLINE void PipelineCyclerDummyImpl:: -release_read_stage(int n, const CycleData *pointer) const { +release_read_stage(int pipeline_stage, const CycleData *pointer) const { TAU_PROFILE("void PipelineCyclerDummyImpl::release_read_stage(int, const CycleData *)", " ", TAU_USER); // This function isn't truly const, but it doesn't change the data // in any meaningful way, so we pretend it is. - nassertv(n == 0); + nassertv(pipeline_stage == 0); nassertv(pointer == _data); nassertv(_read_count > 0); ((PipelineCyclerDummyImpl *)this)->_read_count--; } -//////////////////////////////////////////////////////////////////// -// Function: PipelineCyclerDummyImpl::write_upstream -// Access: Public -// Description: This special variant on write() will automatically -// propagate changes back to upstream pipeline stages. -// If force_to_0 is false, then it propagates back only -// as long as the CycleData pointers are equivalent, -// guaranteeing that it does not modify upstream data -// (other than the modification that will be performed -// by the code that returns this pointer). This is -// particularly appropriate for minor updates, where it -// doesn't matter much if the update is lost, such as -// storing a cached value. -// -// If force_to_0 is dummy, then the CycleData pointer for -// the current pipeline stage is propagated all the way -// back up to stage 0; after this call, there will be -// only one CycleData pointer that is duplicated in all -// stages between stage 0 and the current stage. This -// may undo some recent changes that were made -// independently at pipeline stage 0 (or any other -// upstream stage). However, it guarantees that the -// change that is to be applied at this pipeline stage -// will stick. This is slightly dangerous because of -// the risk of losing upstream changes; generally, this -// should only be done when you are confident that there -// are no upstream changes to be lost (for instance, for -// an object that has been recently created). -//////////////////////////////////////////////////////////////////// -CycleData *PipelineCyclerDummyImpl:: -write_upstream(bool) { - TAU_PROFILE("CycleData *PipelineCyclerDummyImpl::write_upstream(bool)", " ", TAU_USER); - _write_count++; - return _data; -} - //////////////////////////////////////////////////////////////////// // Function: PipelineCyclerDummyImpl::write_stage // Access: Public @@ -346,9 +346,9 @@ write_upstream(bool) { // release_write_stage(). //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerDummyImpl:: -write_stage(int n) { +write_stage(int pipeline_stage, Thread *) { TAU_PROFILE("CycleData *PipelineCyclerDummyImpl::write_stage(int)", " ", TAU_USER); - nassertr(n == 0, (CycleData *)NULL); + nassertr(pipeline_stage == 0, (CycleData *)NULL); _write_count++; return _data; } @@ -364,9 +364,9 @@ write_stage(int n) { // release_write_stage(). //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerDummyImpl:: -write_stage_upstream(int n, bool) { +write_stage_upstream(int pipeline_stage, bool, Thread *) { TAU_PROFILE("CycleData *PipelineCyclerDummyImpl::write_stage_upstream(int)", " ", TAU_USER); - nassertr(n == 0, (CycleData *)NULL); + nassertr(pipeline_stage == 0, (CycleData *)NULL); _write_count++; return _data; } @@ -381,9 +381,9 @@ write_stage_upstream(int n, bool) { // current stage. //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerDummyImpl:: -elevate_read_stage(int n, const CycleData *pointer) { +elevate_read_stage(int pipeline_stage, const CycleData *pointer, Thread *) { TAU_PROFILE("CycleData *PipelineCyclerDummyImpl::elevate_read_stage(int, CycleData *)", " ", TAU_USER); - nassertr(n == 0, NULL); + nassertr(pipeline_stage == 0, NULL); release_read(pointer); return write(); } @@ -398,9 +398,10 @@ elevate_read_stage(int n, const CycleData *pointer) { // current stage. //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerDummyImpl:: -elevate_read_stage_upstream(int n, const CycleData *pointer, bool) { +elevate_read_stage_upstream(int pipeline_stage, const CycleData *pointer, + bool, Thread *) { TAU_PROFILE("CycleData *PipelineCyclerDummyImpl::elevate_read_stage(int, CycleData *)", " ", TAU_USER); - nassertr(n == 0, NULL); + nassertr(pipeline_stage == 0, NULL); release_read(pointer); return write(); } @@ -412,9 +413,9 @@ elevate_read_stage_upstream(int n, const CycleData *pointer, bool) { // write_stage(). //////////////////////////////////////////////////////////////////// INLINE void PipelineCyclerDummyImpl:: -release_write_stage(int n, CycleData *pointer) { +release_write_stage(int pipeline_stage, CycleData *pointer) { TAU_PROFILE("void PipelineCyclerDummyImpl::release_write_stage(int, CycleData *)", " ", TAU_USER); - nassertv(n == 0 && pointer == _data); + nassertv(pipeline_stage == 0 && pointer == _data); nassertv(_write_count > 0); _write_count--; } diff --git a/panda/src/pipeline/pipelineCyclerDummyImpl.h b/panda/src/pipeline/pipelineCyclerDummyImpl.h index 19d0a8cb00..f46a927a5a 100644 --- a/panda/src/pipeline/pipelineCyclerDummyImpl.h +++ b/panda/src/pipeline/pipelineCyclerDummyImpl.h @@ -52,29 +52,29 @@ public: INLINE void operator = (const PipelineCyclerDummyImpl ©); INLINE ~PipelineCyclerDummyImpl(); - INLINE void lock(); + INLINE void lock(Thread *current_thread = NULL); INLINE void release(); - INLINE const CycleData *read() const; + INLINE const CycleData *read(Thread *current_thread) const; INLINE void increment_read(const CycleData *pointer) const; INLINE void release_read(const CycleData *pointer) const; - INLINE CycleData *write(); - INLINE CycleData *elevate_read(const CycleData *pointer); - INLINE CycleData *elevate_read_upstream(const CycleData *pointer, bool force_to_0); + INLINE CycleData *write(Thread *current_thread); + INLINE CycleData *write_upstream(bool force_to_0, Thread *current_thread); + INLINE CycleData *elevate_read(const CycleData *pointer, Thread *current_thread); + INLINE CycleData *elevate_read_upstream(const CycleData *pointer, bool force_to_0, Thread *current_thread); INLINE void increment_write(CycleData *pointer) const; INLINE void release_write(CycleData *pointer); INLINE int get_num_stages(); - INLINE const CycleData *read_stage(int n) const; - INLINE void release_read_stage(int n, const CycleData *pointer) const; - INLINE CycleData *write_upstream(bool force_to_0); - INLINE CycleData *write_stage(int n); - INLINE CycleData *write_stage_upstream(int n, bool force_to_0); - INLINE CycleData *elevate_read_stage(int n, const CycleData *pointer); - INLINE CycleData *elevate_read_stage_upstream(int n, const CycleData *pointer, - bool force_to_0); - INLINE void release_write_stage(int n, CycleData *pointer); + INLINE const CycleData *read_stage(int pipeline_stage, Thread *current_thread) const; + INLINE void release_read_stage(int pipeline_stage, const CycleData *pointer) const; + INLINE CycleData *write_stage(int pipeline_stage, Thread *current_thread); + INLINE CycleData *write_stage_upstream(int pipeline_stage, bool force_to_0, Thread *current_thread); + INLINE CycleData *elevate_read_stage(int pipeline_stage, const CycleData *pointer, Thread *current_thread); + INLINE CycleData *elevate_read_stage_upstream(int pipeline_stage, const CycleData *pointer, + bool force_to_0, Thread *current_thread); + INLINE void release_write_stage(int pipeline_stage, CycleData *pointer); INLINE TypeHandle get_parent_type() const; diff --git a/panda/src/pipeline/pipelineCyclerTrivialImpl.I b/panda/src/pipeline/pipelineCyclerTrivialImpl.I index f59be52588..59b38789dc 100644 --- a/panda/src/pipeline/pipelineCyclerTrivialImpl.I +++ b/panda/src/pipeline/pipelineCyclerTrivialImpl.I @@ -85,7 +85,7 @@ INLINE PipelineCyclerTrivialImpl:: // walking the list of stages. //////////////////////////////////////////////////////////////////// INLINE void PipelineCyclerTrivialImpl:: -lock() { +lock(Thread *) { } //////////////////////////////////////////////////////////////////// @@ -107,7 +107,7 @@ release() { // released by calling release_read(). //////////////////////////////////////////////////////////////////// INLINE const CycleData *PipelineCyclerTrivialImpl:: -read() const { +read(Thread *) const { #ifdef SIMPLE_STRUCT_POINTERS return (const CycleData *)this; #else @@ -153,7 +153,45 @@ release_read(const CycleData *) const { // stage (but see elevate_read). //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerTrivialImpl:: -write() { +write(Thread *) { +#ifdef SIMPLE_STRUCT_POINTERS + return (CycleData *)this; +#else + return _data; +#endif // SIMPLE_STRUCT_POINTERS +} + +//////////////////////////////////////////////////////////////////// +// Function: PipelineCyclerTrivialImpl::write_upstream +// Access: Public +// Description: This special variant on write() will automatically +// propagate changes back to upstream pipeline stages. +// If force_to_0 is false, then it propagates back only +// as long as the CycleData pointers are equivalent, +// guaranteeing that it does not modify upstream data +// (other than the modification that will be performed +// by the code that returns this pointer). This is +// particularly appropriate for minor updates, where it +// doesn't matter much if the update is lost, such as +// storing a cached value. +// +// If force_to_0 is trivial, then the CycleData pointer for +// the current pipeline stage is propagated all the way +// back up to stage 0; after this call, there will be +// only one CycleData pointer that is duplicated in all +// stages between stage 0 and the current stage. This +// may undo some recent changes that were made +// independently at pipeline stage 0 (or any other +// upstream stage). However, it guarantees that the +// change that is to be applied at this pipeline stage +// will stick. This is slightly dangerous because of +// the risk of losing upstream changes; generally, this +// should only be done when you are confident that there +// are no upstream changes to be lost (for instance, for +// an object that has been recently created). +//////////////////////////////////////////////////////////////////// +CycleData *PipelineCyclerTrivialImpl:: +write_upstream(bool, Thread *) { #ifdef SIMPLE_STRUCT_POINTERS return (CycleData *)this; #else @@ -171,7 +209,7 @@ write() { // current stage. //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerTrivialImpl:: -elevate_read(const CycleData *) { +elevate_read(const CycleData *, Thread *) { #ifdef SIMPLE_STRUCT_POINTERS return (CycleData *)this; #else @@ -188,7 +226,7 @@ elevate_read(const CycleData *) { // write_upstream(). //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerTrivialImpl:: -elevate_read_upstream(const CycleData *, bool) { +elevate_read_upstream(const CycleData *, bool, Thread *) { #ifdef SIMPLE_STRUCT_POINTERS return (CycleData *)this; #else @@ -236,7 +274,7 @@ get_num_stages() { // release_read(). //////////////////////////////////////////////////////////////////// INLINE const CycleData *PipelineCyclerTrivialImpl:: -read_stage(int) const { +read_stage(int, Thread *) const { #ifdef SIMPLE_STRUCT_POINTERS return (const CycleData *)this; #else @@ -254,44 +292,6 @@ INLINE void PipelineCyclerTrivialImpl:: release_read_stage(int, const CycleData *) const { } -//////////////////////////////////////////////////////////////////// -// Function: PipelineCyclerTrivialImpl::write_upstream -// Access: Public -// Description: This special variant on write() will automatically -// propagate changes back to upstream pipeline stages. -// If force_to_0 is false, then it propagates back only -// as long as the CycleData pointers are equivalent, -// guaranteeing that it does not modify upstream data -// (other than the modification that will be performed -// by the code that returns this pointer). This is -// particularly appropriate for minor updates, where it -// doesn't matter much if the update is lost, such as -// storing a cached value. -// -// If force_to_0 is trivial, then the CycleData pointer for -// the current pipeline stage is propagated all the way -// back up to stage 0; after this call, there will be -// only one CycleData pointer that is duplicated in all -// stages between stage 0 and the current stage. This -// may undo some recent changes that were made -// independently at pipeline stage 0 (or any other -// upstream stage). However, it guarantees that the -// change that is to be applied at this pipeline stage -// will stick. This is slightly dangerous because of -// the risk of losing upstream changes; generally, this -// should only be done when you are confident that there -// are no upstream changes to be lost (for instance, for -// an object that has been recently created). -//////////////////////////////////////////////////////////////////// -CycleData *PipelineCyclerTrivialImpl:: -write_upstream(bool) { -#ifdef SIMPLE_STRUCT_POINTERS - return (CycleData *)this; -#else - return _data; -#endif // SIMPLE_STRUCT_POINTERS -} - //////////////////////////////////////////////////////////////////// // Function: PipelineCyclerTrivialImpl::write_stage // Access: Public @@ -303,7 +303,7 @@ write_upstream(bool) { // release_write_stage(). //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerTrivialImpl:: -write_stage(int) { +write_stage(int, Thread *) { #ifdef SIMPLE_STRUCT_POINTERS return (CycleData *)this; #else @@ -322,7 +322,7 @@ write_stage(int) { // release_write_stage(). //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerTrivialImpl:: -write_stage_upstream(int, bool) { +write_stage_upstream(int, bool, Thread *) { #ifdef SIMPLE_STRUCT_POINTERS return (CycleData *)this; #else @@ -340,7 +340,7 @@ write_stage_upstream(int, bool) { // current stage. //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerTrivialImpl:: -elevate_read_stage(int, const CycleData *) { +elevate_read_stage(int, const CycleData *, Thread *) { #ifdef SIMPLE_STRUCT_POINTERS return (CycleData *)this; #else @@ -358,7 +358,7 @@ elevate_read_stage(int, const CycleData *) { // current stage. //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerTrivialImpl:: -elevate_read_stage_upstream(int, const CycleData *, bool) { +elevate_read_stage_upstream(int, const CycleData *, bool, Thread *) { #ifdef SIMPLE_STRUCT_POINTERS return (CycleData *)this; #else diff --git a/panda/src/pipeline/pipelineCyclerTrivialImpl.h b/panda/src/pipeline/pipelineCyclerTrivialImpl.h index 79bca718e8..6690428f9e 100644 --- a/panda/src/pipeline/pipelineCyclerTrivialImpl.h +++ b/panda/src/pipeline/pipelineCyclerTrivialImpl.h @@ -23,6 +23,7 @@ #ifndef DO_PIPELINING +#include "thread.h" #include "cycleData.h" class Pipeline; @@ -56,29 +57,32 @@ private: public: INLINE ~PipelineCyclerTrivialImpl(); - INLINE void lock(); + INLINE void lock(Thread *current_thread = NULL); INLINE void release(); - INLINE const CycleData *read() const; + INLINE const CycleData *read(Thread *current_thread) const; INLINE void increment_read(const CycleData *pointer) const; INLINE void release_read(const CycleData *pointer) const; - INLINE CycleData *write(); - INLINE CycleData *elevate_read(const CycleData *pointer); - INLINE CycleData *elevate_read_upstream(const CycleData *pointer, bool force_to_0); + INLINE CycleData *write(Thread *current_thread); + INLINE CycleData *write_upstream(bool force_to_0, Thread *current_thread); + INLINE CycleData *elevate_read(const CycleData *pointer, Thread *current_thread); + INLINE CycleData *elevate_read_upstream(const CycleData *pointer, bool force_to_0, + Thread *current_thread); INLINE void increment_write(CycleData *pointer) const; INLINE void release_write(CycleData *pointer); INLINE int get_num_stages(); - INLINE const CycleData *read_stage(int n) const; - INLINE void release_read_stage(int n, const CycleData *pointer) const; - INLINE CycleData *write_upstream(bool force_to_0); - INLINE CycleData *write_stage(int n); - INLINE CycleData *write_stage_upstream(int n, bool force_to_0); - INLINE CycleData *elevate_read_stage(int n, const CycleData *pointer); - INLINE CycleData *elevate_read_stage_upstream(int n, const CycleData *pointer, - bool force_to_0); - INLINE void release_write_stage(int n, CycleData *pointer); + INLINE const CycleData *read_stage(int pipeline_stage, Thread *current_thread) const; + INLINE void release_read_stage(int pipeline_stage, const CycleData *pointer) const; + INLINE CycleData *write_stage(int pipeline_stage, Thread *current_thread); + INLINE CycleData *write_stage_upstream(int pipeline_stage, bool force_to_0, + Thread *current_thread); + INLINE CycleData *elevate_read_stage(int pipeline_stage, const CycleData *pointer, + Thread *current_thread); + INLINE CycleData *elevate_read_stage_upstream(int pipeline_stage, const CycleData *pointer, + bool force_to_0, Thread *current_thread); + INLINE void release_write_stage(int pipeline_stage, CycleData *pointer); INLINE TypeHandle get_parent_type() const; diff --git a/panda/src/pipeline/pipelineCyclerTrueImpl.I b/panda/src/pipeline/pipelineCyclerTrueImpl.I index 869cf0a232..d62a06c568 100644 --- a/panda/src/pipeline/pipelineCyclerTrueImpl.I +++ b/panda/src/pipeline/pipelineCyclerTrueImpl.I @@ -30,6 +30,19 @@ lock() { _lock.lock(); } +//////////////////////////////////////////////////////////////////// +// Function: PipelineCyclerTrueImpl::lock +// Access: Public +// Description: Grabs an overall lock on the cycler. Release it with +// a call to release(). This lock should be held while +// walking the list of stages. +//////////////////////////////////////////////////////////////////// +INLINE void PipelineCyclerTrueImpl:: +lock(Thread *current_thread) { + TAU_PROFILE("void PipelineCyclerTrueImpl::lock(Thread *)", " ", TAU_USER); + _lock.lock(current_thread); +} + //////////////////////////////////////////////////////////////////// // Function: PipelineCyclerTrueImpl::release // Access: Public @@ -54,11 +67,11 @@ release() { // data when this function is called. //////////////////////////////////////////////////////////////////// INLINE const CycleData *PipelineCyclerTrueImpl:: -read() const { - TAU_PROFILE("const CycleData *PipelineCyclerTrueImpl::read()", " ", TAU_USER); - int pipeline_stage = Thread::get_current_pipeline_stage(); +read(Thread *current_thread) const { + TAU_PROFILE("const CycleData *PipelineCyclerTrueImpl::read(Thread *)", " ", TAU_USER); + int pipeline_stage = current_thread->get_pipeline_stage(); nassertr(pipeline_stage >= 0 && pipeline_stage < _num_stages, NULL); - _lock.lock(); + _lock.lock(current_thread); return _data[pipeline_stage]; } @@ -77,7 +90,7 @@ increment_read(const CycleData *pointer) const { nassertv(pipeline_stage >= 0 && pipeline_stage < _num_stages); nassertv(_data[pipeline_stage] == pointer); #endif - _lock.lock(); + _lock.elevate_lock(); } //////////////////////////////////////////////////////////////////// @@ -114,10 +127,45 @@ release_read(const CycleData *pointer) const { // stage (but see elevate_read). //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerTrueImpl:: -write() { - TAU_PROFILE("CycleData *PipelineCyclerTrueImpl::write()", " ", TAU_USER); - int pipeline_stage = Thread::get_current_pipeline_stage(); - return write_stage(pipeline_stage); +write(Thread *current_thread) { + TAU_PROFILE("CycleData *PipelineCyclerTrueImpl::write(Thread *)", " ", TAU_USER); + return write_stage(current_thread->get_pipeline_stage(), current_thread); +} + +//////////////////////////////////////////////////////////////////// +// Function: PipelineCyclerTrueImpl::write_upstream +// Access: Public +// Description: This special variant on write() will automatically +// propagate changes back to upstream pipeline stages. +// If force_to_0 is false, then it propagates back only +// as long as the CycleData pointers are equivalent, +// guaranteeing that it does not modify upstream data +// (other than the modification that will be performed +// by the code that returns this pointer). This is +// particularly appropriate for minor updates, where it +// doesn't matter much if the update is lost, such as +// storing a cached value. +// +// If force_to_0 is true, then the CycleData pointer for +// the current pipeline stage is propagated all the way +// back up to stage 0; after this call, there will be +// only one CycleData pointer that is duplicated in all +// stages between stage 0 and the current stage. This +// may undo some recent changes that were made +// independently at pipeline stage 0 (or any other +// upstream stage). However, it guarantees that the +// change that is to be applied at this pipeline stage +// will stick. This is slightly dangerous because of +// the risk of losing upstream changes; generally, this +// should only be done when you are confident that there +// are no upstream changes to be lost (for instance, for +// an object that has been recently created). +//////////////////////////////////////////////////////////////////// +INLINE CycleData *PipelineCyclerTrueImpl:: +write_upstream(bool force_to_0, Thread *current_thread) { + TAU_PROFILE("CycleData *PipelineCyclerTrueImpl::write_upstream(bool, Thread *)", " ", TAU_USER); + return write_stage_upstream(current_thread->get_pipeline_stage(), force_to_0, + current_thread); } //////////////////////////////////////////////////////////////////// @@ -130,14 +178,14 @@ write() { // current stage. //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerTrueImpl:: -elevate_read(const CycleData *pointer) { +elevate_read(const CycleData *pointer, Thread *current_thread) { TAU_PROFILE("CycleData *PipelineCyclerTrueImpl::elevate_read(const CycleData *)", " ", TAU_USER); #ifdef _DEBUG - int pipeline_stage = Thread::get_current_pipeline_stage(); + int pipeline_stage = current_thread->get_pipeline_stage(); nassertr(pipeline_stage >= 0 && pipeline_stage < _num_stages, NULL); nassertr(_data[pipeline_stage] == pointer, NULL); #endif - CycleData *new_pointer = write(); + CycleData *new_pointer = write(current_thread); _lock.release(); return new_pointer; } @@ -151,14 +199,14 @@ elevate_read(const CycleData *pointer) { // write_upstream(). //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerTrueImpl:: -elevate_read_upstream(const CycleData *pointer, bool force_to_0) { +elevate_read_upstream(const CycleData *pointer, bool force_to_0, Thread *current_thread) { TAU_PROFILE("CycleData *PipelineCyclerTrueImpl::elevate_read_upstream(const CycleData *, bool)", " ", TAU_USER); #ifdef _DEBUG - int pipeline_stage = Thread::get_current_pipeline_stage(); + int pipeline_stage = current_thread->get_pipeline_stage(); nassertr(pipeline_stage >= 0 && pipeline_stage < _num_stages, NULL); nassertr(_data[pipeline_stage] == pointer, NULL); #endif - CycleData *new_pointer = write_upstream(force_to_0); + CycleData *new_pointer = write_upstream(force_to_0, current_thread); _lock.release(); return new_pointer; } @@ -178,7 +226,7 @@ increment_write(CycleData *pointer) const { nassertv(pipeline_stage >= 0 && pipeline_stage < _num_stages); nassertv(_data[pipeline_stage] == pointer); #endif - _lock.lock(); + _lock.elevate_lock(); } //////////////////////////////////////////////////////////////////// @@ -220,11 +268,11 @@ get_num_stages() { // data when this function is called. //////////////////////////////////////////////////////////////////// INLINE const CycleData *PipelineCyclerTrueImpl:: -read_stage(int n) const { +read_stage(int pipeline_stage, Thread *current_thread) const { TAU_PROFILE("const CycleData *PipelineCyclerTrueImpl::read_stage(int)", " ", TAU_USER); - nassertr(n >= 0 && n < _num_stages, NULL); - _lock.lock(); - return _data[n]; + nassertr(pipeline_stage >= 0 && pipeline_stage < _num_stages, NULL); + _lock.lock(current_thread); + return _data[pipeline_stage]; } //////////////////////////////////////////////////////////////////// @@ -234,50 +282,15 @@ read_stage(int n) const { // read_stage(). //////////////////////////////////////////////////////////////////// INLINE void PipelineCyclerTrueImpl:: -release_read_stage(int n, const CycleData *pointer) const { +release_read_stage(int pipeline_stage, const CycleData *pointer) const { TAU_PROFILE("void PipelineCyclerTrueImpl::release_read_stage(int, const CycleData *)", " ", TAU_USER); #ifdef _DEBUG - nassertv(n >= 0 && n < _num_stages); - nassertv(_data[n] == pointer); + nassertv(pipeline_stage >= 0 && pipeline_stage < _num_stages); + nassertv(_data[pipeline_stage] == pointer); #endif _lock.release(); } -//////////////////////////////////////////////////////////////////// -// Function: PipelineCyclerTrueImpl::write_upstream -// Access: Public -// Description: This special variant on write() will automatically -// propagate changes back to upstream pipeline stages. -// If force_to_0 is false, then it propagates back only -// as long as the CycleData pointers are equivalent, -// guaranteeing that it does not modify upstream data -// (other than the modification that will be performed -// by the code that returns this pointer). This is -// particularly appropriate for minor updates, where it -// doesn't matter much if the update is lost, such as -// storing a cached value. -// -// If force_to_0 is true, then the CycleData pointer for -// the current pipeline stage is propagated all the way -// back up to stage 0; after this call, there will be -// only one CycleData pointer that is duplicated in all -// stages between stage 0 and the current stage. This -// may undo some recent changes that were made -// independently at pipeline stage 0 (or any other -// upstream stage). However, it guarantees that the -// change that is to be applied at this pipeline stage -// will stick. This is slightly dangerous because of -// the risk of losing upstream changes; generally, this -// should only be done when you are confident that there -// are no upstream changes to be lost (for instance, for -// an object that has been recently created). -//////////////////////////////////////////////////////////////////// -INLINE CycleData *PipelineCyclerTrueImpl:: -write_upstream(bool force_to_0) { - int pipeline_stage = Thread::get_current_pipeline_stage(); - return write_stage_upstream(pipeline_stage, force_to_0); -} - //////////////////////////////////////////////////////////////////// // Function: PipelineCyclerTrueImpl::elevate_read_stage // Access: Public @@ -288,13 +301,14 @@ write_upstream(bool force_to_0) { // indicated stage. //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerTrueImpl:: -elevate_read_stage(int n, const CycleData *pointer) { +elevate_read_stage(int pipeline_stage, const CycleData *pointer, + Thread *current_thread) { TAU_PROFILE("CycleData *PipelineCyclerTrueImpl::elevate_read_stage(int, const CycleData *)", " ", TAU_USER); #ifdef _DEBUG - nassertr(n >= 0 && n < _num_stages, NULL); - nassertr(_data[n] == pointer, NULL); + nassertr(pipeline_stage >= 0 && pipeline_stage < _num_stages, NULL); + nassertr(_data[pipeline_stage] == pointer, NULL); #endif - CycleData *new_pointer = write_stage(n); + CycleData *new_pointer = write_stage(pipeline_stage, current_thread); _lock.release(); return new_pointer; } @@ -309,13 +323,15 @@ elevate_read_stage(int n, const CycleData *pointer) { // indicated stage. //////////////////////////////////////////////////////////////////// INLINE CycleData *PipelineCyclerTrueImpl:: -elevate_read_stage_upstream(int n, const CycleData *pointer, bool force_to_0) { +elevate_read_stage_upstream(int pipeline_stage, const CycleData *pointer, + bool force_to_0, Thread *current_thread) { TAU_PROFILE("CycleData *PipelineCyclerTrueImpl::elevate_read_stage(int, const CycleData *)", " ", TAU_USER); #ifdef _DEBUG - nassertr(n >= 0 && n < _num_stages, NULL); - nassertr(_data[n] == pointer, NULL); + nassertr(pipeline_stage >= 0 && pipeline_stage < _num_stages, NULL); + nassertr(_data[pipeline_stage] == pointer, NULL); #endif - CycleData *new_pointer = write_stage_upstream(n, force_to_0); + CycleData *new_pointer = + write_stage_upstream(pipeline_stage, force_to_0, current_thread); _lock.release(); return new_pointer; } @@ -327,11 +343,11 @@ elevate_read_stage_upstream(int n, const CycleData *pointer, bool force_to_0) { // write_stage(). //////////////////////////////////////////////////////////////////// INLINE void PipelineCyclerTrueImpl:: -release_write_stage(int n, CycleData *pointer) { +release_write_stage(int pipeline_stage, CycleData *pointer) { TAU_PROFILE("void PipelineCyclerTrueImpl::release_write_stage(int, const CycleData *)", " ", TAU_USER); #ifdef _DEBUG - nassertv(n >= 0 && n < _num_stages); - nassertv(_data[n] == pointer); + nassertv(pipeline_stage >= 0 && pipeline_stage < _num_stages); + nassertv(_data[pipeline_stage] == pointer); #endif _lock.release(); } diff --git a/panda/src/pipeline/pipelineCyclerTrueImpl.cxx b/panda/src/pipeline/pipelineCyclerTrueImpl.cxx index b2e68c59ee..31a2c427ff 100644 --- a/panda/src/pipeline/pipelineCyclerTrueImpl.cxx +++ b/panda/src/pipeline/pipelineCyclerTrueImpl.cxx @@ -140,8 +140,8 @@ PipelineCyclerTrueImpl:: // release_write_stage(). //////////////////////////////////////////////////////////////////// CycleData *PipelineCyclerTrueImpl:: -write_stage(int pipeline_stage) { - _lock.lock(); +write_stage(int pipeline_stage, Thread *current_thread) { + _lock.lock(current_thread); #ifndef NDEBUG nassertd(pipeline_stage >= 0 && pipeline_stage < _num_stages) { @@ -174,8 +174,8 @@ write_stage(int pipeline_stage) { // pipeline stages. See write_upstream(). //////////////////////////////////////////////////////////////////// CycleData *PipelineCyclerTrueImpl:: -write_stage_upstream(int pipeline_stage, bool force_to_0) { - _lock.lock(); +write_stage_upstream(int pipeline_stage, bool force_to_0, Thread *current_thread) { + _lock.lock(current_thread); #ifndef NDEBUG nassertd(pipeline_stage >= 0 && pipeline_stage < _num_stages) { diff --git a/panda/src/pipeline/pipelineCyclerTrueImpl.h b/panda/src/pipeline/pipelineCyclerTrueImpl.h index 8ff84596f9..764227d3a0 100644 --- a/panda/src/pipeline/pipelineCyclerTrueImpl.h +++ b/panda/src/pipeline/pipelineCyclerTrueImpl.h @@ -58,27 +58,31 @@ public: ~PipelineCyclerTrueImpl(); INLINE void lock(); + INLINE void lock(Thread *current_thread); INLINE void release(); - INLINE const CycleData *read() const; + INLINE const CycleData *read(Thread *current_thread) const; INLINE void increment_read(const CycleData *pointer) const; INLINE void release_read(const CycleData *pointer) const; - INLINE CycleData *write(); - INLINE CycleData *elevate_read(const CycleData *pointer); - INLINE CycleData *elevate_read_upstream(const CycleData *pointer, bool force_to_0); + INLINE CycleData *write(Thread *current_thread); + INLINE CycleData *write_upstream(bool force_to_0, Thread *current_thread); + INLINE CycleData *elevate_read(const CycleData *pointer, Thread *current_thread); + INLINE CycleData *elevate_read_upstream(const CycleData *pointer, bool force_to_0, Thread *current_thread); INLINE void increment_write(CycleData *pointer) const; INLINE void release_write(CycleData *pointer); INLINE int get_num_stages(); - INLINE const CycleData *read_stage(int n) const; - INLINE void release_read_stage(int n, const CycleData *pointer) const; - INLINE CycleData *write_upstream(bool force_to_0); - CycleData *write_stage(int pipeline_stage); - CycleData *write_stage_upstream(int pipeline_stage, bool force_to_0); - INLINE CycleData *elevate_read_stage(int n, const CycleData *pointer); - INLINE CycleData *elevate_read_stage_upstream(int n, const CycleData *pointer, bool force_to_0); - INLINE void release_write_stage(int n, CycleData *pointer); + INLINE const CycleData *read_stage(int pipeline_stage, Thread *current_thread) const; + INLINE void release_read_stage(int pipeline_stage, const CycleData *pointer) const; + CycleData *write_stage(int pipeline_stage, Thread *current_thread); + CycleData *write_stage_upstream(int pipeline_stage, bool force_to_0, + Thread *current_thread); + INLINE CycleData *elevate_read_stage(int pipeline_stage, const CycleData *pointer, + Thread *current_thread); + INLINE CycleData *elevate_read_stage_upstream(int pipeline_stage, const CycleData *pointer, + bool force_to_0, Thread *current_thread); + INLINE void release_write_stage(int pipeline_stage, CycleData *pointer); INLINE TypeHandle get_parent_type() const; diff --git a/panda/src/pipeline/reMutexDirect.I b/panda/src/pipeline/reMutexDirect.I index bd5f66ff68..31ec7e47f4 100755 --- a/panda/src/pipeline/reMutexDirect.I +++ b/panda/src/pipeline/reMutexDirect.I @@ -25,7 +25,7 @@ INLINE ReMutexDirect:: ReMutexDirect() #ifndef HAVE_REMUTEXIMPL - : _cvar(_global_lock) + : _cvar_impl(_lock_impl) #endif { #ifndef HAVE_REMUTEXIMPL @@ -51,7 +51,7 @@ INLINE ReMutexDirect:: INLINE ReMutexDirect:: ReMutexDirect(const ReMutexDirect ©) #ifndef HAVE_REMUTEXIMPL - : _cvar(_global_lock) + : _cvar_impl(_lock_impl) #endif { nassertv(false); @@ -92,6 +92,48 @@ lock() const { #endif // HAVE_REMUTEXIMPL } +//////////////////////////////////////////////////////////////////// +// Function: ReMutexDirect::lock +// Access: Public +// Description: This variant on lock() accepts the current thread as +// a parameter, if it is already known, as an +// optimization. +//////////////////////////////////////////////////////////////////// +INLINE void ReMutexDirect:: +lock(Thread *current_thread) const { + TAU_PROFILE("void ReMutexDirect::lock(Thread *)", " ", TAU_USER); +#ifdef HAVE_REMUTEXIMPL + ((ReMutexDirect *)this)->_impl.lock(); +#else + ((ReMutexDirect *)this)->do_lock(current_thread); +#endif // HAVE_REMUTEXIMPL +} + +//////////////////////////////////////////////////////////////////// +// Function: ReMutexDirect::elevate_lock +// Access: Public +// Description: This method increments the lock count, assuming the +// calling thread already holds the lock. After this +// call, release() will need to be called one additional +// time to release the lock. +// +// This method really performs the same function as +// lock(), but it offers a potential (slight) +// performance benefit when the calling thread knows +// that it already holds the lock. It is an error to +// call this when the calling thread does not hold the +// lock. +//////////////////////////////////////////////////////////////////// +INLINE void ReMutexDirect:: +elevate_lock() const { + TAU_PROFILE("void ReMutexDirect::elevate_lock()", " ", TAU_USER); +#ifdef HAVE_REMUTEXIMPL + ((ReMutexDirect *)this)->_impl.lock(); +#else + ((ReMutexDirect *)this)->do_elevate_lock(); +#endif // HAVE_REMUTEXIMPL +} + //////////////////////////////////////////////////////////////////// // Function: ReMutexDirect::release // Access: Public @@ -126,3 +168,20 @@ INLINE bool ReMutexDirect:: debug_is_locked() const { return true; } + +#ifndef HAVE_REMUTEXIMPL +//////////////////////////////////////////////////////////////////// +// Function: ReMutexDirect::do_lock +// Access: Private +// Description: The private implementation of lock(), for the case in +// which the underlying lock system does not provide a +// reentrant mutex (and therefore we have to build this +// functionality on top of the existing non-reentrant +// mutex). +//////////////////////////////////////////////////////////////////// +INLINE void ReMutexDirect:: +do_lock() { + do_lock(Thread::get_current_thread()); +} +#endif + diff --git a/panda/src/pipeline/reMutexDirect.cxx b/panda/src/pipeline/reMutexDirect.cxx index f44e0d234e..315b1ef634 100755 --- a/panda/src/pipeline/reMutexDirect.cxx +++ b/panda/src/pipeline/reMutexDirect.cxx @@ -19,10 +19,6 @@ #include "reMutexDirect.h" #include "thread.h" -#ifndef HAVE_REMUTEXIMPL -MutexImpl ReMutexDirect::_global_lock; -#endif // !HAVE_REMUTEXIMPL - //////////////////////////////////////////////////////////////////// // Function: ReMutexDirect::output // Access: Public @@ -45,36 +41,72 @@ output(ostream &out) const { // mutex). //////////////////////////////////////////////////////////////////// void ReMutexDirect:: -do_lock() { - _global_lock.lock(); +do_lock(Thread *current_thread) { + _lock_impl.lock(); if (_locking_thread == (Thread *)NULL) { // The mutex is not already locked by anyone. Lock it. - _locking_thread = Thread::get_current_thread(); + _locking_thread = current_thread; ++_lock_count; nassertd(_lock_count == 1) { } - } else if (_locking_thread == Thread::get_current_thread()) { + } else if (_locking_thread == current_thread) { // The mutex is already locked by this thread. Increment the lock // count. ++_lock_count; nassertd(_lock_count > 0) { } - + } else { // The mutex is locked by some other thread. Go to sleep on the // condition variable until it's unlocked. while (_locking_thread != (Thread *)NULL) { - _cvar.wait(); + _cvar_impl.wait(); } - _locking_thread = Thread::get_current_thread(); + _locking_thread = current_thread; ++_lock_count; nassertd(_lock_count == 1) { } } - _global_lock.release(); + _lock_impl.release(); +} +#endif // !HAVE_REMUTEXIMPL + +#ifndef HAVE_REMUTEXIMPL +//////////////////////////////////////////////////////////////////// +// Function: ReMutexDirect::do_elevate_lock +// Access: Private +// Description: The private implementation of lock(), for the case in +// which the underlying lock system does not provide a +// reentrant mutex (and therefore we have to build this +// functionality on top of the existing non-reentrant +// mutex). +//////////////////////////////////////////////////////////////////// +void ReMutexDirect:: +do_elevate_lock() { + _lock_impl.lock(); + +#ifdef _DEBUG + nassertd(_locking_thread == Thread::get_current_thread()) { + _lock_impl.release(); + return; + } +#elif !defined(NDEBUG) + nassertd(_locking_thread != (Thread *)NULL) { + _lock_impl.release(); + return; + } +#endif // NDEBUG + + // We know the mutex is already locked by this thread. Increment + // the lock count. + ++_lock_count; + nassertd(_lock_count > 0) { + } + + _lock_impl.release(); } #endif // !HAVE_REMUTEXIMPL @@ -90,16 +122,18 @@ do_lock() { //////////////////////////////////////////////////////////////////// void ReMutexDirect:: do_release() { - _global_lock.lock(); + _lock_impl.lock(); +#ifdef _DEBUG if (_locking_thread != Thread::get_current_thread()) { ostringstream ostr; ostr << *_locking_thread << " attempted to release " << *this << " which it does not own"; nassert_raise(ostr.str()); - _global_lock.release(); + _lock_impl.release(); return; } +#endif // _DEBUG nassertd(_lock_count > 0) { } @@ -108,8 +142,8 @@ do_release() { if (_lock_count == 0) { // That was the last lock held by this thread. Release the lock. _locking_thread = (Thread *)NULL; - _cvar.signal(); + _cvar_impl.signal(); } - _global_lock.release(); + _lock_impl.release(); } #endif // !HAVE_REMUTEXIMPL diff --git a/panda/src/pipeline/reMutexDirect.h b/panda/src/pipeline/reMutexDirect.h index 74da24b57f..811ccbbc69 100644 --- a/panda/src/pipeline/reMutexDirect.h +++ b/panda/src/pipeline/reMutexDirect.h @@ -41,6 +41,8 @@ private: public: INLINE void lock() const; + INLINE void lock(Thread *current_thread) const; + INLINE void elevate_lock() const; INLINE void release() const; INLINE bool debug_is_locked() const; @@ -53,14 +55,16 @@ private: #else // If we don't have a reentrant mutex, we have to hand-roll one. - void do_lock(); + INLINE void do_lock(); + void do_lock(Thread *current_thread); + void do_elevate_lock(); void do_release(); Thread *_locking_thread; int _lock_count; - ConditionVarImpl _cvar; - static MutexImpl _global_lock; + MutexImpl _lock_impl; + ConditionVarImpl _cvar_impl; #endif // HAVE_REMUTEXIMPL }; diff --git a/panda/src/pipeline/reMutexHolder.I b/panda/src/pipeline/reMutexHolder.I index 49f592ed46..c88df90195 100644 --- a/panda/src/pipeline/reMutexHolder.I +++ b/panda/src/pipeline/reMutexHolder.I @@ -30,6 +30,21 @@ ReMutexHolder(const ReMutex &mutex) { #endif } +//////////////////////////////////////////////////////////////////// +// Function: ReMutexHolder::Constructor +// Access: Public +// Description: This variant on the constructor accepts the current +// thread as a parameter, if it is already known, as an +// optimization. +//////////////////////////////////////////////////////////////////// +INLINE ReMutexHolder:: +ReMutexHolder(const ReMutex &mutex, Thread *current_thread) { +#if defined(HAVE_THREADS) || !defined(NDEBUG) + _mutex = &mutex; + _mutex->lock(current_thread); +#endif +} + //////////////////////////////////////////////////////////////////// // Function: ReMutexHolder::Constructor // Access: Public diff --git a/panda/src/pipeline/reMutexHolder.h b/panda/src/pipeline/reMutexHolder.h index da488908e4..73ee094db4 100644 --- a/panda/src/pipeline/reMutexHolder.h +++ b/panda/src/pipeline/reMutexHolder.h @@ -22,6 +22,8 @@ #include "pandabase.h" #include "reMutex.h" +class Thread; + //////////////////////////////////////////////////////////////////// // Class : ReMutexHolder // Description : Similar to MutexHolder, but for a reentrant mutex. @@ -29,6 +31,7 @@ class EXPCL_PANDA ReMutexHolder { public: INLINE ReMutexHolder(const ReMutex &mutex); + INLINE ReMutexHolder(const ReMutex &mutex, Thread *current_thread); INLINE ReMutexHolder(ReMutex *&mutex); INLINE ~ReMutexHolder(); private: diff --git a/panda/src/putil/bamReader.cxx b/panda/src/putil/bamReader.cxx index f674ab665d..a533b204f7 100644 --- a/panda/src/putil/bamReader.cxx +++ b/panda/src/putil/bamReader.cxx @@ -600,7 +600,7 @@ void BamReader:: read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler) { PipelineCyclerBase *old_cycler = _reading_cycler; _reading_cycler = &cycler; - CycleData *cdata = cycler.write(); + CycleData *cdata = cycler.write(Thread::get_current_thread()); cdata->fillin(scan, this); cycler.release_write(cdata); _reading_cycler = old_cycler; @@ -617,7 +617,7 @@ read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler, void *extra_data) { PipelineCyclerBase *old_cycler = _reading_cycler; _reading_cycler = &cycler; - CycleData *cdata = cycler.write(); + CycleData *cdata = cycler.write(Thread::get_current_thread()); cdata->fillin(scan, this, extra_data); cycler.release_write(cdata); _reading_cycler = old_cycler; @@ -1114,7 +1114,7 @@ resolve_cycler_pointers(PipelineCyclerBase *cycler, if (is_complete) { // Okay, here's the complete list of pointers for you! - CycleData *cdata = cycler->write(); + CycleData *cdata = cycler->write(Thread::get_current_thread()); int num_completed = cdata->complete_pointers(&references[0], this); cycler->release_write(cdata); if (num_completed != (int)references.size()) { diff --git a/panda/src/putil/bamWriter.cxx b/panda/src/putil/bamWriter.cxx index 7fbed5a125..3a798f9943 100644 --- a/panda/src/putil/bamWriter.cxx +++ b/panda/src/putil/bamWriter.cxx @@ -282,7 +282,7 @@ write_pointer(Datagram &packet, const TypedWritable *object) { //////////////////////////////////////////////////////////////////// void BamWriter:: write_cdata(Datagram &packet, const PipelineCyclerBase &cycler) { - const CycleData *cdata = cycler.read(); + const CycleData *cdata = cycler.read(Thread::get_current_thread()); cdata->write_datagram(this, packet); cycler.release_read(cdata); } @@ -296,7 +296,7 @@ write_cdata(Datagram &packet, const PipelineCyclerBase &cycler) { void BamWriter:: write_cdata(Datagram &packet, const PipelineCyclerBase &cycler, void *extra_data) { - const CycleData *cdata = cycler.read(); + const CycleData *cdata = cycler.read(Thread::get_current_thread()); cdata->write_datagram(this, packet, extra_data); cycler.release_read(cdata); }