preserve current_thread instead of pipeline_stage in PipelineReader objects

This commit is contained in:
David Rose 2006-04-20 18:38:41 +00:00
parent 6c31d661f6
commit ce3afa5f53
39 changed files with 941 additions and 579 deletions

View File

@ -467,15 +467,17 @@ CData(const Geom::CData &copy) :
// 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;
}
////////////////////////////////////////////////////////////////////

View File

@ -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);

View File

@ -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 &copy);
INLINE void operator = (const GeomPipelineReader &copy);
@ -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;
};

View File

@ -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 &copy) :
_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;
}
////////////////////////////////////////////////////////////////////

View File

@ -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

View File

@ -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 &copy);
INLINE void operator = (const GeomPrimitivePipelineReader &copy);
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;
};

View File

@ -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 &copy) :
////////////////////////////////////////////////////////////////////
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
}
////////////////////////////////////////////////////////////////////

View File

@ -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 &copy);
INLINE void operator = (const GeomVertexArrayDataPipelineReader &copy);
@ -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 &copy);
INLINE void operator = (const GeomVertexArrayDataPipelineWriter &copy);

View File

@ -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 &copy) :
////////////////////////////////////////////////////////////////////
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
}
////////////////////////////////////////////////////////////////////

View File

@ -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;

View File

@ -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 &copy);
INLINE void operator = (const GeomVertexDataPipelineReader &copy);
@ -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 &copy);
INLINE void operator = (const GeomVertexDataPipelineWriter &copy);

View File

@ -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();

View File

@ -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();

View File

@ -27,10 +27,12 @@
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataReader<CycleDataType>::
CycleDataReader(const PipelineCycler<CycleDataType> &cycler) :
_cycler(&cycler)
CycleDataReader(const PipelineCycler<CycleDataType> &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<class CycleDataType>
INLINE CycleDataReader<CycleDataType>::
CycleDataReader(const CycleDataReader<CycleDataType> &copy) :
_cycler(copy._cycler),
_current_thread(copy._current_thread),
_pointer(copy._pointer)
{
nassertv(_pointer != (const CycleDataType *)NULL);
@ -58,6 +61,7 @@ template<class CycleDataType>
INLINE void CycleDataReader<CycleDataType>::
operator = (const CycleDataReader<CycleDataType> &copy) {
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<class CycleDataType>
INLINE Thread *CycleDataReader<CycleDataType>::
get_current_thread() const {
return _current_thread;
}
#else // !DO_PIPELINING
// This is the trivial, do-nothing implementation.
@ -134,8 +150,8 @@ take_pointer() {
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataReader<CycleDataType>::
CycleDataReader(const PipelineCycler<CycleDataType> &cycler) {
_pointer = cycler.read();
CycleDataReader(const PipelineCycler<CycleDataType> &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<class CycleDataType>
INLINE Thread *CycleDataReader<CycleDataType>::
get_current_thread() const {
return Thread::get_current_thread();
}
#endif // DO_PIPELINING

View File

@ -23,6 +23,7 @@
#include "cycleData.h"
#include "pipelineCycler.h"
#include "thread.h"
////////////////////////////////////////////////////////////////////
// Class : CycleDataReader
@ -39,7 +40,8 @@
template<class CycleDataType>
class CycleDataReader {
public:
INLINE CycleDataReader(const PipelineCycler<CycleDataType> &cycler);
INLINE CycleDataReader(const PipelineCycler<CycleDataType> &cycler,
Thread *current_thread = Thread::get_current_thread());
INLINE CycleDataReader(const CycleDataReader<CycleDataType> &copy);
INLINE void operator = (const CycleDataReader<CycleDataType> &copy);
@ -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<CycleDataType> *_cycler;
Thread *_current_thread;
const CycleDataType *_pointer;
CycleDataType *_write_pointer;
#else // !DO_PIPELINING

View File

@ -29,11 +29,12 @@
template<class CycleDataType>
INLINE CycleDataStageReader<CycleDataType>::
CycleDataStageReader(const PipelineCycler<CycleDataType> &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<class CycleDataType>
INLINE CycleDataStageReader<CycleDataType>::
CycleDataStageReader(const CycleDataStageReader<CycleDataType> &copy) :
_cycler(copy._cycler),
_current_thread(copy._current_thread),
_pointer(copy._pointer),
_stage(copy._stage)
{
@ -62,6 +64,7 @@ template<class CycleDataType>
INLINE void CycleDataStageReader<CycleDataType>::
operator = (const CycleDataStageReader<CycleDataType> &copy) {
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<class CycleDataType>
INLINE Thread *CycleDataStageReader<CycleDataType>::
get_current_thread() const {
return _current_thread;
}
#else // !DO_PIPELINING
// This is the trivial, do-nothing implementation.
@ -139,8 +154,9 @@ take_pointer() {
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataStageReader<CycleDataType>::
CycleDataStageReader(const PipelineCycler<CycleDataType> &cycler, int) {
_pointer = cycler.read();
CycleDataStageReader(const PipelineCycler<CycleDataType> &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<class CycleDataType>
INLINE Thread *CycleDataStageReader<CycleDataType>::
get_current_thread() const {
return Thread::get_current_thread();
}
#endif // DO_PIPELINING

View File

@ -33,7 +33,8 @@
template<class CycleDataType>
class CycleDataStageReader {
public:
INLINE CycleDataStageReader(const PipelineCycler<CycleDataType> &cycler, int stage);
INLINE CycleDataStageReader(const PipelineCycler<CycleDataType> &cycler,
int stage, Thread *current_thread = Thread::get_current_thread());
INLINE CycleDataStageReader(const CycleDataStageReader<CycleDataType> &copy);
INLINE void operator = (const CycleDataStageReader<CycleDataType> &copy);
@ -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<CycleDataType> *_cycler;
Thread *_current_thread;
const CycleDataType *_pointer;
int _stage;
#else // !DO_PIPELINING

View File

@ -27,11 +27,13 @@
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataStageWriter<CycleDataType>::
CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage) :
CycleDataStageWriter(PipelineCycler<CycleDataType> &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<CycleDataType> &cycler, int stage) :
template<class CycleDataType>
INLINE CycleDataStageWriter<CycleDataType>::
CycleDataStageWriter(PipelineCycler<CycleDataType> &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<class CycleDataType>
INLINE CycleDataStageWriter<CycleDataType>::
CycleDataStageWriter(const CycleDataStageWriter<CycleDataType> &copy) :
_cycler(copy._cycler),
_current_thread(copy._current_thread),
_pointer(copy._pointer),
_stage(copy._stage)
{
@ -76,6 +80,7 @@ template<class CycleDataType>
INLINE void CycleDataStageWriter<CycleDataType>::
operator = (const CycleDataStageWriter<CycleDataType> &copy) {
nassertv(_pointer == (CycleDataType *)NULL);
nassertv(_current_thread == copy._current_thread);
_cycler = copy._cycler;
_pointer = copy._pointer;
@ -97,9 +102,11 @@ INLINE CycleDataStageWriter<CycleDataType>::
CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage,
CycleDataStageReader<CycleDataType> &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<CycleDataType> &cycler, int stage,
CycleDataStageReader<CycleDataType> &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<class CycleDataType>
INLINE Thread *CycleDataStageWriter<CycleDataType>::
get_current_thread() const {
return _current_thread;
}
#else // !DO_PIPELINING
// This is the trivial, do-nothing implementation.
@ -183,8 +203,8 @@ operator CycleDataType * () {
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataStageWriter<CycleDataType>::
CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int) {
_pointer = cycler.write();
CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int, Thread *) {
_pointer = cycler.cheat();
}
////////////////////////////////////////////////////////////////////
@ -194,8 +214,8 @@ CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int) {
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataStageWriter<CycleDataType>::
CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int, bool) {
_pointer = cycler.write();
CycleDataStageWriter(PipelineCycler<CycleDataType> &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<class CycleDataType>
INLINE Thread *CycleDataStageWriter<CycleDataType>::
get_current_thread() const {
return Thread::get_current_thread();
}
#endif // DO_PIPELINING

View File

@ -37,9 +37,11 @@
template<class CycleDataType>
class CycleDataStageWriter {
public:
INLINE CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage);
INLINE CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage,
bool force_to_0);
Thread *current_thread = Thread::get_current_thread());
INLINE CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage,
bool force_to_0, Thread *current_thread = Thread::get_current_thread());
INLINE CycleDataStageWriter(const CycleDataStageWriter<CycleDataType> &copy);
INLINE void operator = (const CycleDataStageWriter<CycleDataType> &copy);
@ -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<CycleDataType> *_cycler;
Thread *_current_thread;
CycleDataType *_pointer;
int _stage;
#else // !DO_PIPELINING

View File

@ -27,10 +27,11 @@
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataWriter<CycleDataType>::
CycleDataWriter(PipelineCycler<CycleDataType> &cycler) :
_cycler(&cycler)
CycleDataWriter(PipelineCycler<CycleDataType> &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<CycleDataType> &cycler) :
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataWriter<CycleDataType>::
CycleDataWriter(PipelineCycler<CycleDataType> &cycler, bool force_to_0) :
_cycler(&cycler)
CycleDataWriter(PipelineCycler<CycleDataType> &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<class CycleDataType>
INLINE CycleDataWriter<CycleDataType>::
CycleDataWriter(const CycleDataWriter<CycleDataType> &copy) :
_cycler(copy._cycler),
_current_thread(copy._current_thread),
_pointer(copy._pointer)
{
nassertv(_pointer != (CycleDataType *)NULL);
@ -78,6 +82,7 @@ template<class CycleDataType>
INLINE void CycleDataWriter<CycleDataType>::
operator = (const CycleDataWriter<CycleDataType> &copy) {
nassertv(_pointer == (CycleDataType *)NULL);
nassertv(_current_thread == copy._current_thread);
_cycler = copy._cycler;
_pointer = copy._pointer;
@ -97,9 +102,10 @@ template<class CycleDataType>
INLINE CycleDataWriter<CycleDataType>::
CycleDataWriter(PipelineCycler<CycleDataType> &cycler,
CycleDataReader<CycleDataType> &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<CycleDataType>::
CycleDataWriter(PipelineCycler<CycleDataType> &cycler,
CycleDataReader<CycleDataType> &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<class CycleDataType>
INLINE Thread *CycleDataWriter<CycleDataType>::
get_current_thread() const {
return _current_thread;
}
#else // !DO_PIPELINING
// This is the trivial, do-nothing implementation.
@ -183,25 +203,19 @@ operator CycleDataType * () {
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataWriter<CycleDataType>::
CycleDataWriter(PipelineCycler<CycleDataType> &cycler) {
_pointer = cycler.write();
CycleDataWriter(PipelineCycler<CycleDataType> &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<class CycleDataType>
INLINE CycleDataWriter<CycleDataType>::
CycleDataWriter(PipelineCycler<CycleDataType> &cycler, bool) {
_pointer = cycler.write();
CycleDataWriter(PipelineCycler<CycleDataType> &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<class CycleDataType>
INLINE Thread *CycleDataWriter<CycleDataType>::
get_current_thread() const {
return Thread::get_current_thread();
}
#endif // DO_PIPELINING

View File

@ -24,6 +24,7 @@
#include "cycleData.h"
#include "pipelineCycler.h"
#include "cycleDataReader.h"
#include "thread.h"
////////////////////////////////////////////////////////////////////
// Class : CycleDataWriter
@ -40,8 +41,10 @@
template<class CycleDataType>
class CycleDataWriter {
public:
INLINE CycleDataWriter(PipelineCycler<CycleDataType> &cycler);
INLINE CycleDataWriter(PipelineCycler<CycleDataType> &cycler, bool force_to_0);
INLINE CycleDataWriter(PipelineCycler<CycleDataType> &cycler,
Thread *current_thread = Thread::get_current_thread());
INLINE CycleDataWriter(PipelineCycler<CycleDataType> &cycler, bool force_to_0,
Thread *current_thread = Thread::get_current_thread());
INLINE CycleDataWriter(const CycleDataWriter<CycleDataType> &copy);
INLINE void operator = (const CycleDataWriter<CycleDataType> &copy);
@ -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<CycleDataType> *_cycler;
Thread *_current_thread;
CycleDataType *_pointer;
#else // !DO_PIPELINING
// This is all we need for the trivial, do-nothing implementation.

View File

@ -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

View File

@ -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;

View File

@ -63,19 +63,8 @@ operator = (const PipelineCycler<CycleDataType> &copy) {
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE const CycleDataType *PipelineCycler<CycleDataType>::
read() const {
return (const CycleDataType *)PipelineCyclerBase::read();
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::read (dummy or true)
// Access: Public
// Description: See PipelineCyclerBase::read_stage().
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE const CycleDataType *PipelineCycler<CycleDataType>::
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<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
write() {
return (CycleDataType *)PipelineCyclerBase::write();
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::elevate_read (dummy or true)
// Access: Public
// Description: See PipelineCyclerBase::elevate_read().
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
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<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
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<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
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<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
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<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
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<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
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<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
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<class CycleDataType>
INLINE const CycleDataType *PipelineCycler<CycleDataType>::
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<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
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<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
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<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
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<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
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<CycleDataType> &copy) {
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE const CycleDataType *PipelineCycler<CycleDataType>::
read() const {
return &_typed_data;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::read_stage (trivial)
// Access: Public
// Description: See PipelineCyclerBase::read_stage().
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE const CycleDataType *PipelineCycler<CycleDataType>::
read_stage(int) const {
read(Thread *) const {
return &_typed_data;
}
@ -252,51 +245,7 @@ read_stage(int) const {
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
write() {
return &_typed_data;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::elevate_read (trivial)
// Access: Public
// Description: See PipelineCyclerBase::elevate_read().
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
elevate_read(const CycleDataType *) {
return &_typed_data;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::elevate_read_upstream (trivial)
// Access: Public
// Description: See PipelineCyclerBase::elevate_read_upstream().
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
elevate_read_upstream(const CycleDataType *, bool) {
return &_typed_data;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::elevate_read_stage (trivial)
// Access: Public
// Description: See PipelineCyclerBase::elevate_read_stage().
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
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<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
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<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
write_upstream(bool) {
write_upstream(bool, Thread *) {
return &_typed_data;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::elevate_read (trivial)
// Access: Public
// Description: See PipelineCyclerBase::elevate_read().
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
elevate_read(const CycleDataType *, Thread *) {
return &_typed_data;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::elevate_read_upstream (trivial)
// Access: Public
// Description: See PipelineCyclerBase::elevate_read_upstream().
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
elevate_read_upstream(const CycleDataType *, bool, Thread *) {
return &_typed_data;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::read_stage (trivial)
// Access: Public
// Description: See PipelineCyclerBase::read_stage().
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE const CycleDataType *PipelineCycler<CycleDataType>::
read_stage(int, Thread *) const {
return &_typed_data;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::elevate_read_stage (trivial)
// Access: Public
// Description: See PipelineCyclerBase::elevate_read_stage().
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
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<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
elevate_read_stage_upstream(int, const CycleDataType *, bool, Thread *) {
return &_typed_data;
}
@ -318,7 +322,7 @@ write_upstream(bool) {
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
write_stage(int) {
write_stage(int, Thread *) {
return &_typed_data;
}
@ -329,7 +333,7 @@ write_stage(int) {
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
write_stage_upstream(int, bool) {
write_stage_upstream(int, bool, Thread *) {
return &_typed_data;
}

View File

@ -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<CycleDataType> &copy);
INLINE void operator = (const PipelineCycler<CycleDataType> &copy);
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;

View File

@ -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--;
}

View File

@ -52,29 +52,29 @@ public:
INLINE void operator = (const PipelineCyclerDummyImpl &copy);
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;

View File

@ -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

View File

@ -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;

View File

@ -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();
}

View File

@ -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) {

View File

@ -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;

View File

@ -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 &copy)
#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

View File

@ -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

View File

@ -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
};

View File

@ -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

View File

@ -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:

View File

@ -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()) {

View File

@ -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);
}