Panda3D
 All Classes Functions Variables Enumerations
vertexDataPage.h
00001 // Filename: vertexDataPage.h
00002 // Created by:  drose (04Jun07)
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 VERTEXDATAPAGE_H
00016 #define VERTEXDATAPAGE_H
00017 
00018 #include "pandabase.h"
00019 #include "simpleLru.h"
00020 #include "simpleAllocator.h"
00021 #include "pStatCollector.h"
00022 #include "vertexDataSaveFile.h"
00023 #include "pmutex.h"
00024 #include "conditionVar.h"
00025 #include "conditionVarFull.h"
00026 #include "thread.h"
00027 #include "mutexHolder.h"
00028 #include "pdeque.h"
00029 
00030 class VertexDataBook;
00031 class VertexDataBlock;
00032 
00033 ////////////////////////////////////////////////////////////////////
00034 //       Class : VertexDataPage
00035 // Description : A block of bytes that holds one or more
00036 //               VertexDataBlocks.  The entire page may be paged out,
00037 //               in the form of in-memory compression or to an on-disk
00038 //               cache file, if necessary.
00039 ////////////////////////////////////////////////////////////////////
00040 class EXPCL_PANDA_GOBJ VertexDataPage : public SimpleAllocator, public SimpleLruPage {
00041 private:
00042   VertexDataPage(size_t book_size);
00043   VertexDataPage(VertexDataBook *book, size_t page_size, size_t block_size);
00044   virtual ~VertexDataPage();
00045 
00046 PUBLISHED:
00047   // These are used to indicate the current residency state of the
00048   // page, which may or may not have been temporarily evicted to
00049   // satisfy memory requirements.
00050   enum RamClass {
00051     RC_resident,
00052     RC_compressed,
00053     RC_disk,
00054 
00055     RC_end_of_list,  // list marker; do not use
00056   };
00057 
00058   INLINE RamClass get_ram_class() const;
00059   INLINE RamClass get_pending_ram_class() const;
00060   INLINE void request_resident();
00061 
00062   INLINE VertexDataBlock *alloc(size_t size);
00063   INLINE VertexDataBlock *get_first_block() const;
00064 
00065   INLINE VertexDataBook *get_book() const;
00066 
00067   INLINE static SimpleLru *get_global_lru(RamClass rclass);
00068   INLINE static SimpleLru *get_pending_lru();
00069   INLINE static VertexDataSaveFile *get_save_file();
00070 
00071   INLINE bool save_to_disk();
00072 
00073   INLINE static int get_num_threads();
00074   INLINE static int get_num_pending_reads();
00075   INLINE static int get_num_pending_writes();
00076   static void stop_threads();
00077   static void flush_threads();
00078 
00079   virtual void output(ostream &out) const;
00080   virtual void write(ostream &out, int indent_level) const;
00081 
00082 public:
00083   INLINE unsigned char *get_page_data(bool force);
00084   INLINE bool operator < (const VertexDataPage &other) const;
00085 
00086 protected:
00087   virtual SimpleAllocatorBlock *make_block(size_t start, size_t size);
00088   virtual void changed_contiguous();
00089   virtual void evict_lru();
00090 
00091 private:
00092   class PageThread;
00093 
00094   VertexDataBlock *do_alloc(size_t size);
00095 
00096   void make_resident_now();
00097   void make_resident();
00098   void make_compressed();
00099   void make_disk();
00100 
00101   bool do_save_to_disk();
00102   void do_restore_from_disk();
00103 
00104   void adjust_book_size();
00105 
00106   void request_ram_class(RamClass ram_class);
00107   INLINE void set_ram_class(RamClass ram_class);
00108   static void make_save_file();
00109 
00110   INLINE size_t round_up(size_t page_size) const;
00111   unsigned char *alloc_page_data(size_t page_size) const;
00112   void free_page_data(unsigned char *page_data, size_t page_size) const;
00113 
00114   typedef pdeque<VertexDataPage *> PendingPages;
00115 
00116   class PageThreadManager;
00117   class PageThread : public Thread {
00118   public:
00119     PageThread(PageThreadManager *manager, const string &name);
00120 
00121   protected:
00122     virtual void thread_main();
00123 
00124   private:
00125     PageThreadManager *_manager;
00126     VertexDataPage *_working_page;
00127     
00128     // Signaled when _working_page is set to NULL after finishing a
00129     // task.
00130     ConditionVar _working_cvar;
00131     friend class PageThreadManager;
00132   };
00133   typedef pvector<PT(PageThread) > PageThreads;
00134 
00135   class PageThreadManager : public ReferenceCount {
00136   public:
00137     PageThreadManager(int num_threads);
00138     void add_page(VertexDataPage *page, RamClass ram_class);
00139     void remove_page(VertexDataPage *page);
00140     int get_num_threads() const;
00141     int get_num_pending_reads() const;
00142     int get_num_pending_writes() const;
00143     void start_threads(int num_threads);
00144     void stop_threads();
00145 
00146   private:
00147     PendingPages _pending_writes;
00148     PendingPages _pending_reads;
00149     bool _shutdown;
00150 
00151     // Signaled when anything new is added to either of the above
00152     // queues, or when _shutdown is set true.  This wakes up any
00153     // pending thread.
00154     ConditionVarFull _pending_cvar;
00155 
00156     PageThreads _threads;
00157     friend class PageThread;
00158   };
00159 
00160   static PT(PageThreadManager) _thread_mgr;
00161   static Mutex &_tlock;  // Protects _thread_mgr and all of its members.
00162 
00163   unsigned char *_page_data;
00164   size_t _size, _allocated_size, _uncompressed_size;
00165   RamClass _ram_class;
00166   PT(VertexDataSaveBlock) _saved_block;
00167   size_t _book_size;
00168   size_t _block_size;
00169 
00170   //Mutex _lock;  // Inherited from SimpleAllocator.  Protects above members.
00171   RamClass _pending_ram_class;  // Protected by _tlock.
00172 
00173   VertexDataBook *_book;  // never changes.
00174 
00175   enum { deflate_page_size = 1024, inflate_page_size = 1024 };
00176 
00177   // We build up a temporary linked list of these while deflating
00178   // (compressing) the vertex data in-memory.
00179   class DeflatePage {
00180   public:
00181     DeflatePage() {
00182       _used_size = 0;
00183       _next = NULL;
00184     }
00185     ALLOC_DELETED_CHAIN(DeflatePage);
00186 
00187     unsigned char _buffer[deflate_page_size];
00188     size_t _used_size;
00189     DeflatePage *_next;
00190     
00191   public:
00192     static TypeHandle get_class_type() {
00193       return _type_handle;
00194     }
00195     static void init_type() {
00196       register_type(_type_handle, "VertexDataPage::DeflatePage");
00197     }
00198     
00199   private:
00200     static TypeHandle _type_handle;
00201   };
00202 
00203   static SimpleLru _resident_lru;
00204   static SimpleLru _compressed_lru;
00205   static SimpleLru _disk_lru;
00206   static SimpleLru _pending_lru;
00207   static SimpleLru *_global_lru[RC_end_of_list];
00208 
00209   static VertexDataSaveFile *_save_file;
00210 
00211   static Mutex _unused_mutex;
00212 
00213   static PStatCollector _vdata_compress_pcollector;
00214   static PStatCollector _vdata_decompress_pcollector;
00215   static PStatCollector _vdata_save_pcollector;
00216   static PStatCollector _vdata_restore_pcollector;
00217   static PStatCollector _thread_wait_pcollector;
00218   static PStatCollector _alloc_pages_pcollector;
00219 
00220 public:
00221   static TypeHandle get_class_type() {
00222     return _type_handle;
00223   }
00224   static void init_type() {
00225     register_type(_type_handle, "VertexDataPage");
00226   }
00227 
00228 private:
00229   static TypeHandle _type_handle;
00230 
00231   friend class PageThread;
00232   friend class VertexDataBook;
00233 };
00234 
00235 inline ostream &operator << (ostream &out, const VertexDataPage &page) {
00236   page.output(out);
00237   return out;
00238 }
00239 
00240 #include "vertexDataPage.I"
00241 
00242 #endif
 All Classes Functions Variables Enumerations