OpenVDB 10.0.1
Loading...
Searching...
No Matches
HostBuffer.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: MPL-2.0
3
4/*!
5 @file HostBuffer.h
6
7 @date April 20, 2021
8
9 @brief HostBuffer - a buffer that contains a shared or private bump
10 pool to either externally or internally managed host memory.
11
12 @details This HostBuffer can be used in multiple ways, most of which are
13 demonstrated in the examples below. Memory in the pool can
14 be managed or unmanged (e.g. internal or external) and can
15 be shared between multiple buffers or belong to a single buffer.
16
17 Example that uses HostBuffer::create inside io::readGrids to create a
18 full self-managed buffer, i.e. not shared and without padding, per grid in the file.
19 @code
20 auto handles = nanovdb::io::readGrids("file.nvdb");
21 @endcode
22
23 Example that uses HostBuffer::createFull. Assuming you have a raw pointer
24 to a NanoVDB grid of unknown type, this examples shows how to create its
25 GridHandle which can be used to enquire about the grid type and meta data.
26 @code
27 void *data;// pointer to a NanoVDB grid of unknown type
28 uint64_t size;// byte size of NanoVDB grid of unknown type
29 auto buffer = nanovdb::HostBuffer::createFull(size, data);
30 nanovdb::GridHandle<> gridHandle(std::move(buffer));
31 @endcode
32
33 Example that uses HostBuffer::createPool for internally managed host memory.
34 Suppose you want to read multiple grids in multiple files, but reuse the same
35 fixed sized memory buffer to both avoid memory fragmentation as well as
36 exceeding the fixed memory ceiling!
37 @code
38 auto pool = nanovdb::HostBuffer::createPool(1 << 30);// 1 GB memory pool
39 std::vector<std::string>> frames;// vector of grid names
40 for (int i=0; i<frames.size(); ++i) {
41 auto handles = nanovdb::io::readGrids(frames[i], 0, pool);// throws if grids in file exceed 1 GB
42 ...
43 pool.reset();// clears all handles and resets the memory pool for reuse
44 }
45 @endcode
46
47 Example that uses HostBuffer::createPool for externally managed host memory.
48 Note that in this example @c handles are allowed to outlive @c pool since
49 they internally store a shared pointer to the memory pool. However @c data
50 MUST outlive @c handles since the pool does not own its memory in this example.
51 @code
52 const size_t poolSize = 1 << 30;// 1 GB
53 uint8_t *data = static_cast<uint8_t*>(std::malloc(size)+NANOVDB_DATA_ALIGNMENT);// 1 GB pool
54 uint8_t *buffer = nanovdb::alignPtr(data);// 32B aligned buffer
55 //uint8_t *buffer = std::aligned_alloc(NANOVDB_DATA_ALIGNMENT, poolSize);// in C++17
56 auto pool = nanovdb::HostBuffer::createPool(poolSize, buffer);
57 auto handles1 = nanovdb::io::readGrids("file1.nvdb", 0, pool);
58 auto handles2 = nanovdb::io::readGrids("file2.nvdb", 0, pool);
59 ....
60 std::free(data);
61 @endcode
62
63 Example that uses HostBuffer::createPool for externally managed host memory.
64 Note that in this example @c handles are allowed to outlive @c pool since
65 they internally store a shared pointer to the memory pool. However @c array
66 MUST outlive @c handles since the pool does not own its memory in this example.
67 @code
68 const size_t poolSize = 1 << 30;// 1 GB
69 std::unique_ptr<uint8_t[]> array(new uint8_t[size+NANOVDB_DATA_ALIGNMENT]);// scoped pool of 1 GB
70 //std::unique_ptr<uint8_t[]> array(std::aligned_alloc(NANOVDB_DATA_ALIGNMENT, size));// in C++17
71 uint8_t *buffer = nanovdb::alignPtr(array.get());// 32B aligned buffer
72 auto pool = nanovdb::HostBuffer::createPool(poolSize, buffer);
73 auto handles = nanovdb::io::readGrids("file.nvdb", 0, pool);
74 @endcode
75*/
76
77#ifndef NANOVDB_HOSTBUFFER_H_HAS_BEEN_INCLUDED
78#define NANOVDB_HOSTBUFFER_H_HAS_BEEN_INCLUDED
79
80#include "../NanoVDB.h"// for NANOVDB_DATA_ALIGNMENT;
81#include <stdint.h> // for types like int32_t etc
82#include <cstdio> // for fprintf
83#include <cstdlib> // for std::malloc/std::realloc/std::free
84#include <memory>// for std::make_shared
85#include <mutex>// for std::mutex
86#include <unordered_set>//for std::unordered_set
87#include <cassert>// for assert
88#include <sstream>// for std::stringstream
89#include <cstring>// for memcpy
90
91#define checkPtr(ptr, msg) \
92 { \
93 ptrAssert((ptr), (msg), __FILE__, __LINE__); \
94 }
95
96namespace nanovdb {
97
98template<typename BufferT>
100{
101 static const bool hasDeviceDual = false;
102};
103
104// ----------------------------> HostBuffer <--------------------------------------
105
106/// @brief This is a buffer that contains a shared or private pool
107/// to either externally or internally managed host memory.
108///
109/// @note Terminology:
110/// Pool: 0 = buffer.size() < buffer.poolSize()
111/// Buffer: 0 < buffer.size() < buffer.poolSize()
112/// Full: 0 < buffer.size() = buffer.poolSize()
113/// Empty: 0 = buffer.size() = buffer.poolSize()
115{
116 struct Pool;// forward declaration of private pool struct
117 std::shared_ptr<Pool> mPool;
118 uint64_t mSize; // total number of bytes for the NanoVDB grid.
119 uint8_t* mData; // raw buffer for the NanoVDB grid.
120
121#if defined(DEBUG) || defined(_DEBUG)
122 static inline void ptrAssert(void* ptr, const char* msg, const char* file, int line, bool abort = true)
123 {
124 if (ptr == nullptr) {
125 fprintf(stderr, "NULL pointer error: %s %s %d\n", msg, file, line);
126 if (abort)
127 exit(1);
128 }
129 if (uint64_t(ptr) % NANOVDB_DATA_ALIGNMENT) {
130 fprintf(stderr, "Alignment pointer error: %s %s %d\n", msg, file, line);
131 if (abort)
132 exit(1);
133 }
134 }
135#else
136 static inline void ptrAssert(void*, const char*, const char*, int, bool = true)
137 {
138 }
139#endif
140
141public:
142 /// @brief Return a full buffer or an empty buffer
143 HostBuffer(uint64_t bufferSize = 0);
144
145 /// @brief Move copy-constructor
146 HostBuffer(HostBuffer&& other);
147
148 /// @brief Custom descructor
149 ~HostBuffer() { this->clear(); }
150
151 /// @brief Move copy assignment operation
153
154 /// @brief Disallow copy-construction
155 HostBuffer(const HostBuffer&) = delete;
156
157 /// @brief Disallow copy assignment operation
158 HostBuffer& operator=(const HostBuffer&) = delete;
159
160 /// @brief Return a pool buffer which satisfies: buffer.size == 0,
161 /// buffer.poolSize() == poolSize, and buffer.data() == nullptr.
162 /// If data==nullptr, memory for the pool will be allocated.
163 ///
164 /// @throw If poolSize is zero.
165 static HostBuffer createPool(uint64_t poolSize, void *data = nullptr);
166
167 /// @brief Return a full buffer which satisfies: buffer.size == bufferSize,
168 /// buffer.poolSize() == bufferSize, and buffer.data() == data.
169 /// If data==nullptr, memory for the pool will be allocated.
170 ///
171 /// @throw If bufferSize is zero.
172 static HostBuffer createFull(uint64_t bufferSize, void *data = nullptr);
173
174 /// @brief Return a buffer with @c bufferSize bytes managed by
175 /// the specified memory @c pool. If none is provided, i.e.
176 /// @c pool == nullptr or @c pool->poolSize() == 0, one is
177 /// created with size @c bufferSize, i.e. a full buffer is returned.
178 ///
179 /// @throw If the specified @c pool has insufficient memory for
180 /// the requested buffer size.
181 static HostBuffer create(uint64_t bufferSize, const HostBuffer* pool = nullptr);
182
183 /// @brief Initialize as a full buffer with the specified size. If data is NULL
184 /// the memory is internally allocated.
185 void init(uint64_t bufferSize, void *data = nullptr);
186
187 //@{
188 /// @brief Retuns a pointer to the raw memory buffer managed by this allocator.
189 ///
190 /// @warning Note that the pointer can be NULL if the allocator was not initialized!
191 const uint8_t* data() const { return mData; }
192 uint8_t* data() { return mData; }
193 //@}
194
195 //@{
196 /// @brief Returns the size in bytes associated with this buffer.
197 uint64_t bufferSize() const { return mSize; }
198 uint64_t size() const { return this->bufferSize(); }
199 //@}
200
201 /// @brief Returns the size in bytes of the memory pool shared with this instance.
202 uint64_t poolSize() const;
203
204 /// @brief Return true if memory is managed (using std::malloc and std:free) by the
205 /// shared pool in this buffer. Else memory is assumed to be managed externally.
206 bool isManaged() const;
207
208 //@{
209 /// @brief Returns true if this buffer has no memory associated with it
210 bool isEmpty() const { return !mPool || mSize == 0 || mData == nullptr; }
211 bool empty() const { return this->isEmpty(); }
212 //@}
213
214 /// @brief Return true if this is a pool, i.e. an empty buffer with a nonempty
215 /// internal pool, i.e. this->size() == 0 and this->poolSize() != 0
216 bool isPool() const { return mSize == 0 && this->poolSize() > 0; }
217
218 /// @brief Return true if the pool exists, is nonempty but has no more available memory
219 bool isFull() const;
220
221 /// @brief Clear this buffer so it is empty.
222 void clear();
223
224 /// @brief Clears all existing buffers that are registered against the memory pool
225 /// and resets the pool so it can be reused to create new buffers.
226 ///
227 /// @throw If this instance is not empty or contains no pool.
228 ///
229 /// @warning This method is not thread-safe!
230 void reset();
231
232 /// @brief Total number of bytes from the pool currently in use by buffers
233 uint64_t poolUsage() const;
234
235 /// @brief resize the pool size. It will attempt to resize the existing
236 /// memory block, but if that fails a deep copy is performed.
237 /// If @c data is not NULL it will be used as new externally
238 /// managed memory for the pool. All registered buffers are
239 /// updated so GridHandle::grid might return a new address (if
240 /// deep copy was performed).
241 ///
242 /// @note This method can be use to resize the memory pool and even
243 /// change it from internally to externally managed memory or vice versa.
244 ///
245 /// @throw if @c poolSize is less than this->poolUsage() the used memory
246 /// or allocations fail.
247 void resizePool(uint64_t poolSize, void *data = nullptr);
248
249}; // HostBuffer class
250
251// --------------------------> Implementation of HostBuffer::Pool <------------------------------------
252
253// This is private struct of HostBuffer so you can safely ignore the API
255{
256 using HashTableT = std::unordered_set<HostBuffer*>;
257 std::mutex mMutex; // mutex for updating mRegister and mFree
259 uint8_t* mData;
260 uint8_t* mFree;
261 uint64_t mSize;
262 uint64_t mPadding;
264
265 /// @brief External memory ctor
266 Pool(uint64_t size = 0, void* data = nullptr)
267 : mData((uint8_t*)data)
268 , mFree(mData)
269 , mSize(size)
270 , mPadding(0)
271 , mManaged(data == nullptr)
272 {
273 if (mManaged) {
274 mData = static_cast<uint8_t*>(Pool::alloc(mSize));
275 if (mData == nullptr) {
276 throw std::runtime_error("Pool::Pool malloc failed");
277 }
278 }
280 if (!mManaged && mPadding != 0) {
281 throw std::runtime_error("Pool::Pool: external memory buffer is not aligned to " +
282 std::to_string(NANOVDB_DATA_ALIGNMENT) +
283 " bytes.\nHint: use nanovdb::alignPtr or std::aligned_alloc (C++17 only)");
284 }
285 mFree = mData + mPadding;
286 }
287
288 /// @brief Custom destructor
290 {
291 assert(mRegister.empty());
292 if (mManaged) {
293 std::free(mData);
294 }
295 }
296
297 /// @brief Disallow copy-construction
298 Pool(const Pool&) = delete;
299
300 /// @brief Disallow move-construction
301 Pool(const Pool&&) = delete;
302
303 /// @brief Disallow copy assignment operation
304 Pool& operator=(const Pool&) = delete;
305
306 /// @brief Disallow move assignment operation
307 Pool& operator=(const Pool&&) = delete;
308
309 /// @brief Return the total number of bytes used from this Pool by buffers
310 uint64_t usage() const { return static_cast<uint64_t>(mFree - mData) - mPadding; }
311
312 /// @brief Allocate a buffer of the specified size and add it to the register
313 void add(HostBuffer* buffer, uint64_t size)
314 {
315 auto* alignedFree = mFree + alignmentPadding(mFree);
316
317 if (alignedFree + size > mData + mPadding + mSize) {
318 std::stringstream ss;
319 ss << "HostBuffer::Pool: insufficient memory\n"
320 << "\tA buffer requested " << size << " bytes with " << NANOVDB_DATA_ALIGNMENT
321 << "-bytes alignment from a pool with "
322 << mSize << " bytes of which\n\t" << (alignedFree - mData - mPadding)
323 << " bytes are used by " << mRegister.size() << " other buffer(s). "
324 << "Pool is " << (mManaged ? "internally" : "externally") << " managed.\n";
325 //std::cerr << ss.str();
326 throw std::runtime_error(ss.str());
327 }
328 buffer->mSize = size;
329 const std::lock_guard<std::mutex> lock(mMutex);
330 mRegister.insert(buffer);
331 buffer->mData = alignedFree;
332 mFree = alignedFree + size;
333 }
334
335 /// @brief Remove the specified buffer from the register
336 void remove(HostBuffer *buffer)
337 {
338 const std::lock_guard<std::mutex> lock(mMutex);
339 mRegister.erase(buffer);
340 }
341
342 /// @brief Replaces buffer1 with buffer2 in the register
343 void replace(HostBuffer *buffer1, HostBuffer *buffer2)
344 {
345 const std::lock_guard<std::mutex> lock(mMutex);
346 mRegister.erase( buffer1);
347 mRegister.insert(buffer2);
348 }
349
350 /// @brief Reset the register and all its buffers
351 void reset()
352 {
353 for (HostBuffer *buffer : mRegister) {
354 buffer->mPool.reset();
355 buffer->mSize = 0;
356 buffer->mData = nullptr;
357 }
358 mRegister.clear();
359 mFree = mData + mPadding;
360 }
361
362 /// @brief Resize this Pool and update registered buffers as needed. If data is no NULL
363 /// it is used as externally managed memory.
364 void resize(uint64_t size, void *data = nullptr)
365 {
366 const uint64_t memUsage = this->usage();
367
368 const bool managed = (data == nullptr);
369
370 if (!managed && alignmentPadding(data) != 0) {
371 throw std::runtime_error("Pool::resize: external memory buffer is not aligned to " +
372 std::to_string(NANOVDB_DATA_ALIGNMENT) + " bytes");
373 }
374
375 if (memUsage > size) {
376 throw std::runtime_error("Pool::resize: insufficient memory");
377 }
378
379 uint64_t padding = 0;
380 if (mManaged && managed && size != mSize) { // managed -> managed
381 padding = mPadding;
382 data = Pool::realloc(mData, memUsage, size, padding); // performs both copy and free of mData
383 } else if (!mManaged && managed) { // un-managed -> managed
384 data = Pool::alloc(size);
385 padding = alignmentPadding(data);
386 }
387
388 if (data == nullptr) {
389 throw std::runtime_error("Pool::resize: allocation failed");
390 } else if (data != mData) {
391 auto* paddedData = static_cast<uint8_t*>(data) + padding;
392
393 if (!(mManaged && managed)) { // no need to copy if managed -> managed
394 memcpy(paddedData, mData + mPadding, memUsage);
395 }
396
397 for (HostBuffer* buffer : mRegister) { // update registered buffers
398 buffer->mData = paddedData + ptrdiff_t(buffer->mData - (mData + mPadding));
399 }
400 mFree = paddedData + memUsage; // update the free pointer
401 if (mManaged && !managed) {// only free if managed -> un-managed
402 std::free(mData);
403 }
404
405 mData = static_cast<uint8_t*>(data);
406 mPadding = padding;
407 }
408 mSize = size;
409 mManaged = managed;
410 }
411 /// @brief Return true is all the memory in this pool is in use.
412 bool isFull() const
413 {
414 assert(mFree <= mData + mPadding + mSize);
415 return mSize > 0 ? mFree == mData + mPadding + mSize : false;
416 }
417
418private:
419
420 static void* alloc(uint64_t size)
421 {
422//#if (__cplusplus >= 201703L)
423// return std::aligned_alloc(NANOVDB_DATA_ALIGNMENT, size);//C++17 or newer
424//#else
425 // make sure we alloc enough space to align the result
426 return std::malloc(size + NANOVDB_DATA_ALIGNMENT);
427//#endif
428 }
429
430 static void* realloc(void* const origData,
431 uint64_t origSize,
432 uint64_t desiredSize,
433 uint64_t& padding)
434 {
435 // make sure we alloc enough space to align the result
436 void* data = std::realloc(origData, desiredSize + NANOVDB_DATA_ALIGNMENT);
437
438 if (data != nullptr && data != origData) {
439 uint64_t newPadding = alignmentPadding(data);
440 // Number of padding bytes may have changed -- move data if that's the case
441 if (newPadding != padding) {
442 // Realloc should not happen when shrinking down buffer, but let's be safe
443 std::memmove(static_cast<uint8_t*>(data) + newPadding,
444 static_cast<uint8_t*>(data) + padding,
445 Min(origSize, desiredSize));
446 padding = newPadding;
447 }
448 }
449
450 return data;
451 }
452
453};// struct HostBuffer::Pool
454
455// --------------------------> Implementation of HostBuffer <------------------------------------
456
457inline HostBuffer::HostBuffer(uint64_t size) : mPool(nullptr), mSize(size), mData(nullptr)
458{
459 if (size>0) {
460 mPool = std::make_shared<Pool>(size);
461 mData = mPool->mFree;
462 mPool->mRegister.insert(this);
463 mPool->mFree += size;
464 }
465}
466
467inline HostBuffer::HostBuffer(HostBuffer&& other) : mPool(other.mPool), mSize(other.mSize), mData(other.mData)
468{
469 if (mPool && mSize != 0) {
470 mPool->replace(&other, this);
471 }
472 other.mPool.reset();
473 other.mSize = 0;
474 other.mData = nullptr;
475}
476
477inline void HostBuffer::init(uint64_t bufferSize, void *data)
478{
479 if (bufferSize == 0) {
480 throw std::runtime_error("HostBuffer: invalid buffer size");
481 }
482 if (mPool) {
483 mPool.reset();
484 }
485 if (!mPool || mPool->mSize != bufferSize) {
486 mPool = std::make_shared<Pool>(bufferSize, data);
487 }
488 mPool->add(this, bufferSize);
489}
490
492{
493 if (mPool) {
494 mPool->remove(this);
495 }
496 mPool = other.mPool;
497 mSize = other.mSize;
498 mData = other.mData;
499 if (mPool && mSize != 0) {
500 mPool->replace(&other, this);
501 }
502 other.mPool.reset();
503 other.mSize = 0;
504 other.mData = nullptr;
505 return *this;
506}
507
508inline uint64_t HostBuffer::poolSize() const
509{
510 return mPool ? mPool->mSize : 0u;
511}
512
513inline uint64_t HostBuffer::poolUsage() const
514{
515 return mPool ? mPool->usage(): 0u;
516}
517
518inline bool HostBuffer::isManaged() const
519{
520 return mPool ? mPool->mManaged : false;
521}
522
523inline bool HostBuffer::isFull() const
524{
525 return mPool ? mPool->isFull() : false;
526}
527
528inline HostBuffer HostBuffer::createPool(uint64_t poolSize, void *data)
529{
530 if (poolSize == 0) {
531 throw std::runtime_error("HostBuffer: invalid pool size");
532 }
533 HostBuffer buffer;
534 buffer.mPool = std::make_shared<Pool>(poolSize, data);
535 // note the buffer is NOT registered by its pool since it is not using its memory
536 buffer.mSize = 0;
537 buffer.mData = nullptr;
538 return buffer;
539}
540
541inline HostBuffer HostBuffer::createFull(uint64_t bufferSize, void *data)
542{
543 if (bufferSize == 0) {
544 throw std::runtime_error("HostBuffer: invalid buffer size");
545 }
546 HostBuffer buffer;
547 buffer.mPool = std::make_shared<Pool>(bufferSize, data);
548 buffer.mPool->add(&buffer, bufferSize);
549 return buffer;
550}
551
552inline HostBuffer HostBuffer::create(uint64_t bufferSize, const HostBuffer* pool)
553{
554 HostBuffer buffer;
555 if (pool == nullptr || !pool->mPool) {
556 buffer.mPool = std::make_shared<Pool>(bufferSize);
557 } else {
558 buffer.mPool = pool->mPool;
559 }
560 buffer.mPool->add(&buffer, bufferSize);
561 return buffer;
562}
563
564inline void HostBuffer::clear()
565{
566 if (mPool) {// remove self from the buffer register in the pool
567 mPool->remove(this);
568 }
569 mPool.reset();
570 mSize = 0;
571 mData = nullptr;
572}
573
574inline void HostBuffer::reset()
575{
576 if (this->size()>0) {
577 throw std::runtime_error("HostBuffer: only empty buffers can call reset");
578 }
579 if (!mPool) {
580 throw std::runtime_error("HostBuffer: this buffer contains no pool to reset");
581 }
582 mPool->reset();
583}
584
585inline void HostBuffer::resizePool(uint64_t size, void *data)
586{
587 if (!mPool) {
588 throw std::runtime_error("HostBuffer: this buffer contains no pool to resize");
589 }
590 mPool->resize(size, data);
591}
592
593} // namespace nanovdb
594
595#endif // end of NANOVDB_HOSTBUFFER_H_HAS_BEEN_INCLUDED
static void ptrAssert(void *, const char *, const char *, int, bool=true)
Definition: CudaDeviceBuffer.h:44
#define NANOVDB_DATA_ALIGNMENT
Definition: NanoVDB.h:137
This is a buffer that contains a shared or private pool to either externally or internally managed ho...
Definition: HostBuffer.h:115
~HostBuffer()
Custom descructor.
Definition: HostBuffer.h:149
const uint8_t * data() const
Retuns a pointer to the raw memory buffer managed by this allocator.
Definition: HostBuffer.h:191
HostBuffer(const HostBuffer &)=delete
Disallow copy-construction.
HostBuffer(uint64_t bufferSize=0)
Return a full buffer or an empty buffer.
Definition: HostBuffer.h:457
HostBuffer & operator=(HostBuffer &&other)
Move copy assignment operation.
Definition: HostBuffer.h:491
uint64_t bufferSize() const
Returns the size in bytes associated with this buffer.
Definition: HostBuffer.h:197
bool empty() const
Definition: HostBuffer.h:211
static HostBuffer createFull(uint64_t bufferSize, void *data=nullptr)
Return a full buffer which satisfies: buffer.size == bufferSize, buffer.poolSize() == bufferSize,...
Definition: HostBuffer.h:541
uint64_t poolSize() const
Returns the size in bytes of the memory pool shared with this instance.
Definition: HostBuffer.h:508
uint64_t size() const
Definition: HostBuffer.h:198
void init(uint64_t bufferSize, void *data=nullptr)
Initialize as a full buffer with the specified size. If data is NULL the memory is internally allocat...
Definition: HostBuffer.h:477
HostBuffer & operator=(const HostBuffer &)=delete
Disallow copy assignment operation.
uint64_t poolUsage() const
Total number of bytes from the pool currently in use by buffers.
Definition: HostBuffer.h:513
uint8_t * data()
Definition: HostBuffer.h:192
bool isPool() const
Return true if this is a pool, i.e. an empty buffer with a nonempty internal pool,...
Definition: HostBuffer.h:216
bool isManaged() const
Return true if memory is managed (using std::malloc and std:free) by the shared pool in this buffer....
Definition: HostBuffer.h:518
static HostBuffer create(uint64_t bufferSize, const HostBuffer *pool=nullptr)
Return a buffer with bufferSize bytes managed by the specified memory pool. If none is provided,...
Definition: HostBuffer.h:552
void clear()
Clear this buffer so it is empty.
Definition: HostBuffer.h:564
bool isEmpty() const
Returns true if this buffer has no memory associated with it.
Definition: HostBuffer.h:210
void reset()
Clears all existing buffers that are registered against the memory pool and resets the pool so it can...
Definition: HostBuffer.h:574
bool isFull() const
Return true if the pool exists, is nonempty but has no more available memory.
Definition: HostBuffer.h:523
void resizePool(uint64_t poolSize, void *data=nullptr)
resize the pool size. It will attempt to resize the existing memory block, but if that fails a deep c...
Definition: HostBuffer.h:585
static HostBuffer createPool(uint64_t poolSize, void *data=nullptr)
Return a pool buffer which satisfies: buffer.size == 0, buffer.poolSize() == poolSize,...
Definition: HostBuffer.h:528
Definition: NanoVDB.h:208
Type Min(Type a, Type b)
Definition: NanoVDB.h:758
static uint64_t alignmentPadding(const void *p)
return the smallest number of bytes that when added to the specified pointer results in an aligned po...
Definition: NanoVDB.h:510
Definition: HostBuffer.h:100
static const bool hasDeviceDual
Definition: HostBuffer.h:101
Definition: HostBuffer.h:255
std::unordered_set< HostBuffer * > HashTableT
Definition: HostBuffer.h:256
void resize(uint64_t size, void *data=nullptr)
Resize this Pool and update registered buffers as needed. If data is no NULL it is used as externally...
Definition: HostBuffer.h:364
uint64_t usage() const
Return the total number of bytes used from this Pool by buffers.
Definition: HostBuffer.h:310
void replace(HostBuffer *buffer1, HostBuffer *buffer2)
Replaces buffer1 with buffer2 in the register.
Definition: HostBuffer.h:343
Pool(uint64_t size=0, void *data=nullptr)
External memory ctor.
Definition: HostBuffer.h:266
uint64_t mSize
Definition: HostBuffer.h:261
Pool(const Pool &)=delete
Disallow copy-construction.
void add(HostBuffer *buffer, uint64_t size)
Allocate a buffer of the specified size and add it to the register.
Definition: HostBuffer.h:313
void remove(HostBuffer *buffer)
Remove the specified buffer from the register.
Definition: HostBuffer.h:336
uint8_t * mFree
Definition: HostBuffer.h:260
Pool & operator=(const Pool &&)=delete
Disallow move assignment operation.
uint8_t * mData
Definition: HostBuffer.h:259
std::mutex mMutex
Definition: HostBuffer.h:257
Pool(const Pool &&)=delete
Disallow move-construction.
HashTableT mRegister
Definition: HostBuffer.h:258
uint64_t mPadding
Definition: HostBuffer.h:262
Pool & operator=(const Pool &)=delete
Disallow copy assignment operation.
void reset()
Reset the register and all its buffers.
Definition: HostBuffer.h:351
~Pool()
Custom destructor.
Definition: HostBuffer.h:289
bool isFull() const
Return true is all the memory in this pool is in use.
Definition: HostBuffer.h:412
bool mManaged
Definition: HostBuffer.h:263