Panda3D
vertexDataPage.I
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.I
10  * @author drose
11  * @date 2007-06-04
12  */
13 
14 /**
15  * Returns the current ram class of the array. If this is other than
16  * RC_resident, the array data is not resident in memory.
17  */
18 INLINE VertexDataPage::RamClass VertexDataPage::
19 get_ram_class() const {
20  MutexHolder holder(_lock);
21  return _ram_class;
22 }
23 
24 /**
25  * Returns the pending ram class of the array. If this is different from
26  * get_ram_class(), this page has been queued to be processed by the thread.
27  * Eventually the page will be set to this ram class.
28  */
29 INLINE VertexDataPage::RamClass VertexDataPage::
31  MutexHolder holder(_lock);
32  return _pending_ram_class;
33 }
34 
35 /**
36  * Ensures that the page will become resident soon. Future calls to
37  * get_page_data() will eventually return non-NULL.
38  */
39 INLINE void VertexDataPage::
41  MutexHolder holder(_lock);
42  if (_ram_class != RC_resident) {
43  request_ram_class(RC_resident);
44  }
45 }
46 
47 /**
48  * Allocates a new block. Returns NULL if a block of the requested size
49  * cannot be allocated.
50  *
51  * To free the allocated block, call block->free(), or simply delete the block
52  * pointer.
53  */
55 alloc(size_t size) {
56  MutexHolder holder(_lock);
57  return do_alloc(size);
58 }
59 
60 /**
61  * Returns a pointer to the first allocated block, or NULL if there are no
62  * allocated blocks.
63  */
65 get_first_block() const {
66  MutexHolder holder(_lock);
68 }
69 
70 /**
71  * Returns a pointer to the book that owns this page.
72  */
74 get_book() const {
75  return _book;
76 }
77 
78 /**
79  * Returns a pointer to the global LRU object that manages the
80  * VertexDataPage's with the indicated RamClass.
81  */
83 get_global_lru(RamClass rclass) {
84  nassertr(rclass >= 0 && rclass < RC_end_of_list, nullptr);
85  return _global_lru[rclass];
86 }
87 
88 /**
89  * Returns a pointer to the global LRU object that manages the
90  * VertexDataPage's that are pending processing by the thread.
91  */
94  return &_pending_lru;
95 }
96 
97 /**
98  * Returns the global VertexDataSaveFile that will be used to save vertex data
99  * buffers to disk when necessary.
100  */
101 INLINE VertexDataSaveFile *VertexDataPage::
102 get_save_file() {
103  if (_save_file == nullptr) {
104  make_save_file();
105  }
106  return _save_file;
107 }
108 
109 /**
110  * Writes the page to disk, but does not evict it from memory or affect its
111  * LRU status. If it gets evicted later without having been modified, it will
112  * not need to write itself to disk again.
113  */
114 INLINE bool VertexDataPage::
116  MutexHolder holder(_lock);
117  return do_save_to_disk();
118 }
119 
120 /**
121  * Returns the number of threads that have been spawned to service vertex
122  * paging requests, or 0 if no threads have been spawned (which may mean
123  * either that all paging requests will be handled by the main thread, or
124  * simply that no paging requests have yet been issued).
125  */
126 INLINE int VertexDataPage::
128  MutexHolder holder(_tlock);
129  if (_thread_mgr == nullptr) {
130  return 0;
131  }
132  return _thread_mgr->get_num_threads();
133 }
134 
135 /**
136  * Returns the number of read requests that are waiting to be serviced by a
137  * thread.
138  */
139 INLINE int VertexDataPage::
141  MutexHolder holder(_tlock);
142  if (_thread_mgr == nullptr) {
143  return 0;
144  }
145  return _thread_mgr->get_num_pending_reads();
146 }
147 
148 /**
149  * Returns the number of write requests that are waiting to be serviced by a
150  * thread.
151  */
152 INLINE int VertexDataPage::
154  MutexHolder holder(_tlock);
155  if (_thread_mgr == nullptr) {
156  return 0;
157  }
158  return _thread_mgr->get_num_pending_writes();
159 }
160 
161 /**
162  * Returns a pointer to the page's data area, or NULL if the page is not
163  * currently resident. If the page is not currently resident, this will
164  * implicitly request it to become resident soon.
165  *
166  * If force is true, this method will never return NULL, but may block until
167  * the page is available.
168  */
169 INLINE unsigned char *VertexDataPage::
170 get_page_data(bool force) {
171  MutexHolder holder(_lock);
172  if (_ram_class != RC_resident || _pending_ram_class != RC_resident) {
173  if (force) {
174  make_resident_now();
175  } else {
176  request_ram_class(RC_resident);
177  if (_ram_class != RC_resident) {
178  return nullptr;
179  }
180  }
181  }
182 
183  mark_used_lru();
184  nassertr(_size == _uncompressed_size, _page_data);
185  return _page_data;
186 }
187 
188 /**
189  * This comparison method is used to order pages within a book.
190  */
191 INLINE bool VertexDataPage::
192 operator < (const VertexDataPage &other) const {
193  // We sort pages so that the pages with the smallest number of available
194  // contiguous bytes come up first. We store our best estimate of
195  // continguous bytes here.
196  if (_book_size != other._book_size) {
197  return _book_size < other._book_size;
198  }
199 
200  // For pages of equal size, we sort based on pointers, to make it easy to
201  // quickly find a specific page.
202  return this < &other;
203 }
204 
205 /**
206  * Puts the data in a new ram class. Assumes the page lock is already held.
207  */
208 INLINE void VertexDataPage::
209 set_ram_class(RamClass rclass) {
210  _ram_class = rclass;
211  mark_used_lru(_global_lru[rclass]);
212 
213  // Changing the ram class might make our effective available space 0 and
214  // thereby change the placement within the book.
215  adjust_book_size();
216 }
217 
218 /**
219  * Round page_size up to the next multiple of _block_size.
220  */
221 INLINE size_t VertexDataPage::
222 round_up(size_t page_size) const {
223  return ((page_size + _block_size - 1) / _block_size) * _block_size;
224 }
An implementation of a very simple LRU algorithm.
Definition: simpleLru.h:28
A block of bytes that holds one or more VertexDataBlocks.
A temporary file to hold the vertex data that has been evicted from memory and written to disk.
RamClass get_pending_ram_class() const
Returns the pending ram class of the array.
void mark_used_lru() const
To be called when the page is used; this will move it to the tail of the SimpleLru queue it is alread...
Definition: simpleLru.I:152
VertexDataBlock * get_first_block() const
Returns a pointer to the first allocated block, or NULL if there are no allocated blocks.
static int get_num_pending_reads()
Returns the number of read requests that are waiting to be serviced by a thread.
void request_resident()
Ensures that the page will become resident soon.
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
Definition: mutexHolder.h:25
static SimpleLru * get_global_lru(RamClass rclass)
Returns a pointer to the global LRU object that manages the VertexDataPage's with the indicated RamCl...
A block of bytes that stores the actual raw vertex data referenced by a GeomVertexArrayData object.
bool operator<(const VertexDataPage &other) const
This comparison method is used to order pages within a book.
VertexDataBook * get_book() const
Returns a pointer to the book that owns this page.
static SimpleLru * get_pending_lru()
Returns a pointer to the global LRU object that manages the VertexDataPage's that are pending process...
SimpleAllocatorBlock * get_first_block() const
Returns a pointer to the first allocated block, or NULL if there are no allocated blocks.
RamClass get_ram_class() const
Returns the current ram class of the array.
bool save_to_disk()
Writes the page to disk, but does not evict it from memory or affect its LRU status.
A collection of VertexDataPages, which can be used to allocate new VertexDataBlock objects.
static int get_num_pending_writes()
Returns the number of write requests that are waiting to be serviced by a thread.
VertexDataBlock * alloc(size_t size)
Allocates a new block.
unsigned char * get_page_data(bool force)
Returns a pointer to the page's data area, or NULL if the page is not currently resident.
static int get_num_threads()
Returns the number of threads that have been spawned to service vertex paging requests,...