Panda3D
 All Classes Functions Variables Enumerations
pipelineCyclerTrueImpl.h
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 &copy);
00054   void operator = (const PipelineCyclerTrueImpl &copy);
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 &copy);
00122     INLINE ~CycleDataNode();
00123     INLINE void operator = (const CycleDataNode &copy);
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 
 All Classes Functions Variables Enumerations