Panda3D
|
00001 // Filename: pipelineCyclerTrueImpl.h 00002 // Created by: drose (31Jan06) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #ifndef PIPELINECYCLERTRUEIMPL_H 00016 #define PIPELINECYCLERTRUEIMPL_H 00017 00018 #include "pandabase.h" 00019 #include "selectThreadImpl.h" // for THREADED_PIPELINE definition 00020 00021 #ifdef THREADED_PIPELINE 00022 00023 #include "pipelineCyclerLinks.h" 00024 #include "cycleData.h" 00025 #include "pointerTo.h" 00026 #include "nodePointerTo.h" 00027 #include "thread.h" 00028 #include "reMutex.h" 00029 #include "reMutexHolder.h" 00030 00031 class Pipeline; 00032 00033 //////////////////////////////////////////////////////////////////// 00034 // Class : PipelineCyclerTrueImpl 00035 // Description : This is the true, threaded implementation of 00036 // PipelineCyclerBase. It is only compiled when 00037 // threading is available and DO_PIPELINING is defined. 00038 // 00039 // This implementation is designed to do the actual work 00040 // of cycling the data through a pipeline, and returning 00041 // the actual CycleData appropriate to the current 00042 // thread's pipeline stage. 00043 // 00044 // This is defined as a struct instead of a class, 00045 // mainly to be consistent with 00046 // PipelineCyclerTrivialImpl. 00047 //////////////////////////////////////////////////////////////////// 00048 struct EXPCL_PANDA_PIPELINE PipelineCyclerTrueImpl : public PipelineCyclerLinks { 00049 private: 00050 PipelineCyclerTrueImpl(); 00051 public: 00052 PipelineCyclerTrueImpl(CycleData *initial_data, Pipeline *pipeline = NULL); 00053 PipelineCyclerTrueImpl(const PipelineCyclerTrueImpl ©); 00054 void operator = (const PipelineCyclerTrueImpl ©); 00055 ~PipelineCyclerTrueImpl(); 00056 00057 INLINE void acquire(); 00058 INLINE void acquire(Thread *current_thread); 00059 INLINE void release(); 00060 00061 INLINE const CycleData *read_unlocked(Thread *current_thread) const; 00062 00063 INLINE const CycleData *read(Thread *current_thread) const; 00064 INLINE void increment_read(const CycleData *pointer) const; 00065 INLINE void release_read(const CycleData *pointer) const; 00066 00067 INLINE CycleData *write(Thread *current_thread); 00068 INLINE CycleData *write_upstream(bool force_to_0, Thread *current_thread); 00069 INLINE CycleData *elevate_read(const CycleData *pointer, Thread *current_thread); 00070 INLINE CycleData *elevate_read_upstream(const CycleData *pointer, bool force_to_0, Thread *current_thread); 00071 INLINE void increment_write(CycleData *pointer) const; 00072 INLINE void release_write(CycleData *pointer); 00073 00074 INLINE int get_num_stages(); 00075 INLINE const CycleData *read_stage_unlocked(int pipeline_stage) const; 00076 INLINE const CycleData *read_stage(int pipeline_stage, Thread *current_thread) const; 00077 INLINE void release_read_stage(int pipeline_stage, const CycleData *pointer) const; 00078 CycleData *write_stage(int pipeline_stage, Thread *current_thread); 00079 CycleData *write_stage_upstream(int pipeline_stage, bool force_to_0, 00080 Thread *current_thread); 00081 INLINE CycleData *elevate_read_stage(int pipeline_stage, const CycleData *pointer, 00082 Thread *current_thread); 00083 INLINE CycleData *elevate_read_stage_upstream(int pipeline_stage, const CycleData *pointer, 00084 bool force_to_0, Thread *current_thread); 00085 INLINE void release_write_stage(int pipeline_stage, CycleData *pointer); 00086 00087 INLINE TypeHandle get_parent_type() const; 00088 00089 INLINE CycleData *cheat() const; 00090 INLINE int get_read_count() const; 00091 INLINE int get_write_count() const; 00092 00093 public: 00094 // We redefine the ReMutex class, solely so we can define the 00095 // output() operator. This is only useful for debugging, but does 00096 // no harm in the production case. 00097 class CyclerMutex : public ReMutex { 00098 public: 00099 INLINE CyclerMutex(PipelineCyclerTrueImpl *cycler); 00100 00101 #ifdef DEBUG_THREADS 00102 virtual void output(ostream &out) const; 00103 PipelineCyclerTrueImpl *_cycler; 00104 #endif // DEBUG_THREADS 00105 }; 00106 00107 private: 00108 PT(CycleData) cycle(); 00109 INLINE PT(CycleData) cycle_2(); 00110 INLINE PT(CycleData) cycle_3(); 00111 void set_num_stages(int num_stages); 00112 00113 private: 00114 Pipeline *_pipeline; 00115 00116 // An array of PT(CycleData) objects representing the different 00117 // copies of the cycled data, one for each stage. 00118 class CycleDataNode : public MemoryBase { 00119 public: 00120 INLINE CycleDataNode(); 00121 INLINE CycleDataNode(const CycleDataNode ©); 00122 INLINE ~CycleDataNode(); 00123 INLINE void operator = (const CycleDataNode ©); 00124 00125 NPT(CycleData) _cdata; 00126 int _writes_outstanding; 00127 }; 00128 CycleDataNode *_data; 00129 int _num_stages; 00130 bool _dirty; 00131 00132 CyclerMutex _lock; 00133 00134 friend class Pipeline; 00135 }; 00136 00137 #include "pipelineCyclerTrueImpl.I" 00138 00139 #endif // THREADED_PIPELINE 00140 00141 #endif 00142