Panda3D
vertexDataPage.h
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file vertexDataPage.h
10  * @author drose
11  * @date 2007-06-04
12  */
13 
14 #ifndef VERTEXDATAPAGE_H
15 #define VERTEXDATAPAGE_H
16 
17 #include "pandabase.h"
18 #include "simpleLru.h"
19 #include "simpleAllocator.h"
20 #include "pStatCollector.h"
21 #include "vertexDataSaveFile.h"
22 #include "pmutex.h"
23 #include "conditionVar.h"
24 #include "conditionVarFull.h"
25 #include "thread.h"
26 #include "mutexHolder.h"
27 #include "pdeque.h"
28 
29 class VertexDataBook;
30 class VertexDataBlock;
31 
32 /**
33  * A block of bytes that holds one or more VertexDataBlocks. The entire page
34  * may be paged out, in the form of in-memory compression or to an on-disk
35  * cache file, if necessary.
36  */
37 class EXPCL_PANDA_GOBJ VertexDataPage : public SimpleAllocator, public SimpleLruPage {
38 private:
39  VertexDataPage(size_t book_size);
40  VertexDataPage(VertexDataBook *book, size_t page_size, size_t block_size);
41  virtual ~VertexDataPage();
42 
43 PUBLISHED:
44  // These are used to indicate the current residency state of the page, which
45  // may or may not have been temporarily evicted to satisfy memory
46  // requirements.
47  enum RamClass {
48  RC_resident,
49  RC_compressed,
50  RC_disk,
51 
52  RC_end_of_list, // list marker; do not use
53  };
54 
55  INLINE RamClass get_ram_class() const;
56  INLINE RamClass get_pending_ram_class() const;
57  INLINE void request_resident();
58 
59  INLINE VertexDataBlock *alloc(size_t size);
60  INLINE VertexDataBlock *get_first_block() const;
61 
62  INLINE VertexDataBook *get_book() const;
63 
64  INLINE static SimpleLru *get_global_lru(RamClass rclass);
65  INLINE static SimpleLru *get_pending_lru();
66  INLINE static VertexDataSaveFile *get_save_file();
67  MAKE_PROPERTY(save_file, get_save_file);
68 
69  INLINE bool save_to_disk();
70 
71  INLINE static int get_num_threads();
72  INLINE static int get_num_pending_reads();
73  INLINE static int get_num_pending_writes();
74  static void stop_threads();
75  static void flush_threads();
76 
77  virtual void output(std::ostream &out) const;
78  virtual void write(std::ostream &out, int indent_level) const;
79 
80 public:
81  INLINE unsigned char *get_page_data(bool force);
82  INLINE bool operator < (const VertexDataPage &other) const;
83 
84 protected:
85  virtual SimpleAllocatorBlock *make_block(size_t start, size_t size);
86  virtual void changed_contiguous();
87  virtual void evict_lru();
88 
89 private:
90  class PageThread;
91 
92  VertexDataBlock *do_alloc(size_t size);
93 
94  void make_resident_now();
95  void make_resident();
96  void make_compressed();
97  void make_disk();
98 
99  bool do_save_to_disk();
100  void do_restore_from_disk();
101 
102  void adjust_book_size();
103 
104  void request_ram_class(RamClass ram_class);
105  INLINE void set_ram_class(RamClass ram_class);
106  static void make_save_file();
107 
108  INLINE size_t round_up(size_t page_size) const;
109  unsigned char *alloc_page_data(size_t page_size) const;
110  void free_page_data(unsigned char *page_data, size_t page_size) const;
111 
113 
114  class PageThreadManager;
115  class EXPCL_PANDA_GOBJ PageThread : public Thread {
116  public:
117  PageThread(PageThreadManager *manager, const std::string &name);
118 
119  protected:
120  virtual void thread_main();
121 
122  private:
123  PageThreadManager *_manager;
124  VertexDataPage *_working_page;
125 
126  // Signaled when _working_page is set to NULL after finishing a task.
127  ConditionVar _working_cvar;
128  friend class PageThreadManager;
129  };
130  typedef pvector<PT(PageThread) > PageThreads;
131 
132  class EXPCL_PANDA_GOBJ PageThreadManager : public ReferenceCount {
133  public:
134  PageThreadManager(int num_threads);
135  void add_page(VertexDataPage *page, RamClass ram_class);
136  void remove_page(VertexDataPage *page);
137  int get_num_threads() const;
138  int get_num_pending_reads() const;
139  int get_num_pending_writes() const;
140  void start_threads(int num_threads);
141  void stop_threads();
142 
143  private:
144  PendingPages _pending_writes;
145  PendingPages _pending_reads;
146  bool _shutdown;
147 
148  // Signaled when anything new is added to either of the above queues, or
149  // when _shutdown is set true. This wakes up any pending thread.
150  ConditionVarFull _pending_cvar;
151 
152  PageThreads _threads;
153  friend class PageThread;
154  };
155 
156  static PT(PageThreadManager) _thread_mgr;
157  static Mutex &_tlock; // Protects _thread_mgr and all of its members.
158 
159  unsigned char *_page_data;
160  size_t _size, _allocated_size, _uncompressed_size;
161  RamClass _ram_class;
162  PT(VertexDataSaveBlock) _saved_block;
163  size_t _book_size;
164  size_t _block_size;
165 
166  // Mutex _lock; Inherited from SimpleAllocator. Protects above members.
167  RamClass _pending_ram_class; // Protected by _tlock.
168 
169  VertexDataBook *_book; // never changes.
170 
171  enum { deflate_page_size = 1024, inflate_page_size = 1024 };
172 
173  // We build up a temporary linked list of these while deflating
174  // (compressing) the vertex data in-memory.
175  class EXPCL_PANDA_GOBJ DeflatePage {
176  public:
177  DeflatePage() {
178  _used_size = 0;
179  _next = nullptr;
180  }
181  ALLOC_DELETED_CHAIN(DeflatePage);
182 
183  unsigned char _buffer[deflate_page_size];
184  size_t _used_size;
185  DeflatePage *_next;
186 
187  public:
188  static TypeHandle get_class_type() {
189  return _type_handle;
190  }
191  static void init_type() {
192  register_type(_type_handle, "VertexDataPage::DeflatePage");
193  }
194 
195  private:
196  static TypeHandle _type_handle;
197  };
198 
199  static SimpleLru _resident_lru;
200  static SimpleLru _compressed_lru;
201  static SimpleLru _disk_lru;
202  static SimpleLru _pending_lru;
203  static SimpleLru *_global_lru[RC_end_of_list];
204 
205  static VertexDataSaveFile *_save_file;
206 
207  static Mutex _unused_mutex;
208 
209  static PStatCollector _vdata_compress_pcollector;
210  static PStatCollector _vdata_decompress_pcollector;
211  static PStatCollector _vdata_save_pcollector;
212  static PStatCollector _vdata_restore_pcollector;
213  static PStatCollector _thread_wait_pcollector;
214  static PStatCollector _alloc_pages_pcollector;
215 
216 public:
217  static TypeHandle get_class_type() {
218  return _type_handle;
219  }
220  static void init_type() {
221  register_type(_type_handle, "VertexDataPage");
222  }
223 
224 private:
225  static TypeHandle _type_handle;
226 
227  friend class PageThread;
228  friend class VertexDataBook;
229 };
230 
231 inline std::ostream &operator << (std::ostream &out, const VertexDataPage &page) {
232  page.output(out);
233  return out;
234 }
235 
236 #include "vertexDataPage.I"
237 
238 #endif
pvector
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:42
SimpleAllocator
An implementation of a very simple block allocator.
Definition: simpleAllocator.h:29
conditionVarFull.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pandabase.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
VertexDataBook
A collection of VertexDataPages, which can be used to allocate new VertexDataBlock objects.
Definition: vertexDataBook.h:30
ReferenceCount
A base class for all things that want to be reference-counted.
Definition: referenceCount.h:38
SimpleLruPage::evict_lru
virtual void evict_lru()
Evicts the page from the LRU.
Definition: simpleLru.cxx:229
register_type
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...
Definition: register_type.I:22
ConditionVarFull
This class implements a condition variable; see ConditionVar for a brief introduction to this class.
Definition: conditionVarFull.h:44
simpleLru.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
VertexDataBlock
A block of bytes that stores the actual raw vertex data referenced by a GeomVertexArrayData object.
Definition: vertexDataBlock.h:29
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
vertexDataPage.I
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
VertexDataPage
A block of bytes that holds one or more VertexDataBlocks.
Definition: vertexDataPage.h:37
pdeque< VertexDataPage * >
PStatCollector
A lightweight class that represents a single element that may be timed and/or counted via stats.
Definition: pStatCollector.h:43
Mutex
A standard mutex, or mutual exclusion lock.
Definition: pmutex.h:38
vertexDataSaveFile.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pmutex.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
SimpleAllocatorBlock
A single block as returned from SimpleAllocator::alloc().
Definition: simpleAllocator.h:90
conditionVar.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
VertexDataSaveBlock
A block of bytes on the save file.
Definition: vertexDataSaveFile.h:73
ConditionVar
A condition variable, usually used to communicate information about changing state to a thread that i...
Definition: conditionVar.h:41
mutexHolder.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
VertexDataSaveFile
A temporary file to hold the vertex data that has been evicted from memory and written to disk.
Definition: vertexDataSaveFile.h:36
SimpleAllocator::get_first_block
SimpleAllocatorBlock * get_first_block() const
Returns a pointer to the first allocated block, or NULL if there are no allocated blocks.
Definition: simpleAllocator.I:96
SimpleLruPage
One atomic piece that may be managed by a SimpleLru chain.
Definition: simpleLru.h:65
SimpleLru
An implementation of a very simple LRU algorithm.
Definition: simpleLru.h:28
Thread
A thread; that is, a lightweight process.
Definition: thread.h:46
thread.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
SimpleAllocator::alloc
SimpleAllocatorBlock * alloc(size_t size, size_t alignment=1)
Allocates a new block.
Definition: simpleAllocator.I:35
simpleAllocator.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pdeque.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pStatCollector.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.