Panda3D
Loading...
Searching...
No Matches
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
29class VertexDataBook;
30class 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 */
37class EXPCL_PANDA_GOBJ VertexDataPage : public SimpleAllocator, public SimpleLruPage {
38private:
39 VertexDataPage(size_t book_size);
40 VertexDataPage(VertexDataBook *book, size_t page_size, size_t block_size);
41 virtual ~VertexDataPage();
42
43PUBLISHED:
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
80public:
81 INLINE unsigned char *get_page_data(bool force);
82 INLINE bool operator < (const VertexDataPage &other) const;
83
84protected:
85 virtual SimpleAllocatorBlock *make_block(size_t start, size_t size);
86 virtual void changed_contiguous();
87 virtual void evict_lru();
88
89private:
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
216public:
217 static TypeHandle get_class_type() {
218 return _type_handle;
219 }
220 static void init_type() {
221 register_type(_type_handle, "VertexDataPage");
222 }
223
224private:
225 static TypeHandle _type_handle;
226
227 friend class PageThread;
228 friend class VertexDataBook;
229};
230
231inline 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
This class implements a condition variable; see ConditionVar for a brief introduction to this class.
A condition variable, usually used to communicate information about changing state to a thread that i...
A standard mutex, or mutual exclusion lock.
Definition pmutex.h:40
A lightweight class that represents a single element that may be timed and/or counted via stats.
A base class for all things that want to be reference-counted.
A single block as returned from SimpleAllocator::alloc().
An implementation of a very simple block allocator.
SimpleAllocatorBlock * get_first_block() const
Returns a pointer to the first allocated block, or NULL if there are no allocated blocks.
SimpleAllocatorBlock * alloc(size_t size, size_t alignment=1)
Allocates a new block.
One atomic piece that may be managed by a SimpleLru chain.
Definition simpleLru.h:65
virtual void evict_lru()
Evicts the page from the LRU.
An implementation of a very simple LRU algorithm.
Definition simpleLru.h:28
A thread; that is, a lightweight process.
Definition thread.h:46
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
A block of bytes that stores the actual raw vertex data referenced by a GeomVertexArrayData object.
A collection of VertexDataPages, which can be used to allocate new VertexDataBlock objects.
A block of bytes that holds one or more VertexDataBlocks.
A block of bytes on the save file.
A temporary file to hold the vertex data that has been evicted from memory and written to disk.
This is our own Panda specialization on the default STL deque.
Definition pdeque.h:36
This is our own Panda specialization on the default STL vector.
Definition pvector.h:42
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.