EBGeometry
Compact, header-only C++ library for fast evaluation of signed distance functions
Loading...
Searching...
No Matches
EBGeometry_Pool.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 Robert Marskar <robert.marskar@sintef.no>
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
31#ifndef EBGEOMETRY_POOL_HPP
32#define EBGEOMETRY_POOL_HPP
33
34// Std includes
35#include <atomic>
36#include <cstddef>
37#include <cstdint>
38#include <memory>
39#include <type_traits>
40
41// Our includes
42#include "EBGeometry_GPU.hpp"
43#include "EBGeometry_Macros.hpp"
45
46namespace EBGeometry {
47
63{
66 void* m_base = nullptr;
67
69 uint64_t m_id = 0;
70
73 uint64_t m_rootId = 0;
74};
75
76class Pool;
77
99{
101 const PoolControl* m_control = nullptr;
102
104 void* m_base = nullptr;
105
107 bool m_hostAccessible = false;
108
116 [[nodiscard]] EBGEOMETRY_HOST_DEVICE
117 inline void*
118 base() const noexcept
119 {
120#if defined(EBGEOMETRY_DEVICE_COMPILE)
121 EBGEOMETRY_EXPECT(m_control == nullptr);
122
123 return m_base;
124#else
125 if (m_control != nullptr) {
126 return m_control->m_base;
127 }
128
129 // Unset, or a snapshot of memory the host cannot reach (a device-only mirror).
131
132 return m_base;
133#endif
134 }
135
141 [[nodiscard]] EBGEOMETRY_HOST
142 inline bool
143 isAttachedTo(const Pool& a_pool) const noexcept;
144
153 inline void
154 attach(const Pool& a_pool, const char* a_who) noexcept;
155
168 [[nodiscard]] EBGEOMETRY_HOST
169 inline PoolLocation
170 rebasedOnto(const Pool& a_pool, uint64_t a_endByte, const char* a_who) const noexcept;
171};
182class Pool
183{
184public:
196 explicit Pool(MemoryResource& a_resource, size_t a_initialBytes = 0);
197
202 ~Pool() noexcept;
203
207 Pool(const Pool&) = delete;
208
212 Pool&
213 operator=(const Pool&) = delete;
214
220 Pool(Pool&& a_other) noexcept;
221
228 Pool&
229 operator=(Pool&& a_other) noexcept;
230
266 [[nodiscard]] EBGEOMETRY_HOST
267 uint64_t
268 reserve(size_t a_count, size_t a_elemSize, size_t a_alignment);
269
277 void
278 freeze() noexcept;
279
285 [[nodiscard]] EBGEOMETRY_HOST
286 void*
287 base() const noexcept
288 {
289 return (m_control != nullptr) ? m_control->m_base : nullptr;
290 }
291
301 [[nodiscard]] EBGEOMETRY_HOST
302 const PoolControl*
303 control() const noexcept
304 {
305 return m_control.get();
306 }
307
314 [[nodiscard]] EBGEOMETRY_HOST
315 uint64_t
316 id() const noexcept
317 {
318 return (m_control != nullptr) ? m_control->m_id : 0;
319 }
320
330 [[nodiscard]] EBGEOMETRY_HOST
331 uint64_t
332 mirrorOf() const noexcept
333 {
334 return m_mirrorOf;
335 }
336
344 [[nodiscard]] EBGEOMETRY_HOST
345 uint64_t
346 rootId() const noexcept
347 {
348 return (m_control != nullptr) ? m_control->m_rootId : 0;
349 }
350
355 [[nodiscard]] EBGEOMETRY_HOST
356 size_t
357 usedBytes() const noexcept
358 {
359 return m_size;
360 }
361
366 [[nodiscard]] EBGEOMETRY_HOST
367 size_t
368 capacityBytes() const noexcept
369 {
370 return m_capacity;
371 }
372
377 [[nodiscard]] EBGEOMETRY_HOST
378 bool
379 isFrozen() const noexcept
380 {
381 return m_frozen;
382 }
383
388 [[nodiscard]] EBGEOMETRY_HOST
390 resource() const noexcept
391 {
392 return *m_resource;
393 }
394
410 [[nodiscard]] EBGEOMETRY_HOST
411 static Pool
412 mirror(const Pool& a_src, MemoryResource& a_dstResource);
413
414private:
417 static constexpr size_t s_maxBytes = SIZE_MAX & ~(PoolBaseAlign - 1);
418
421 struct MirrorTag
422 {
423 };
424
432 Pool(MemoryResource& a_resource, MirrorTag) : m_resource(&a_resource), m_control(makeControl())
433 {}
434
442 [[nodiscard]] EBGEOMETRY_HOST
443 static std::unique_ptr<PoolControl>
444 makeControl()
445 {
446 static std::atomic<uint64_t> s_nextID{1};
447
448 auto control = std::make_unique<PoolControl>();
449
450 control->m_id = s_nextID.fetch_add(1, std::memory_order_relaxed);
452
453 return control;
454 }
455
457 MemoryResource* m_resource = nullptr;
458
460 std::unique_ptr<PoolControl> m_control;
461
463 size_t m_size = 0;
464
466 size_t m_capacity = 0;
467
469 uint64_t m_mirrorOf = 0;
470
472 bool m_frozen = false;
473
481 void
482 grow(size_t a_need);
483};
484
499{
500public:
505 [[nodiscard]] EBGEOMETRY_HOST_DEVICE
506 inline PoolLocation
507 location() const noexcept
508 {
509 return m_location;
510 }
511
517 [[nodiscard]] EBGEOMETRY_HOST
518 inline bool
519 isAttachedTo(const Pool& a_pool) const noexcept
520 {
521 return m_location.isAttachedTo(a_pool);
522 }
523
524protected:
528 PoolHandle() noexcept = default;
529
535 explicit PoolHandle(const PoolLocation& a_location) noexcept : m_location(a_location)
536 {}
537
543 PoolHandle(const PoolHandle&) noexcept = default;
544
548 PoolHandle(PoolHandle&&) noexcept = default;
549
555 operator=(const PoolHandle&) noexcept = default;
556
562 operator=(PoolHandle&&) noexcept = default;
563
567 ~PoolHandle() noexcept = default;
568
573 [[nodiscard]] EBGEOMETRY_HOST_DEVICE
574 inline void*
575 base() noexcept
576 {
577 return m_location.base();
578 }
579
586 [[nodiscard]] EBGEOMETRY_HOST_DEVICE
587 inline const void*
588 base() const noexcept
589 {
590 return m_location.base();
591 }
592
599 inline void
600 attach(const Pool& a_pool, const char* a_who) noexcept
601 {
602 m_location.attach(a_pool, a_who);
603 }
604
613 [[nodiscard]] EBGEOMETRY_HOST
614 inline PoolLocation
615 rebasedLocation(const Pool& a_pool, uint64_t a_endByte, const char* a_who) const noexcept
616 {
617 return m_location.rebasedOnto(a_pool, a_endByte, a_who);
618 }
619
625 inline void
626 setLocation(const PoolLocation& a_location) noexcept
627 {
628 m_location = a_location;
629 }
630
631private:
635 PoolLocation m_location;
636};
637
642template <class P>
643inline constexpr bool isPoolHandle = std::is_base_of_v<PoolHandle, P>;
644
645} // namespace EBGeometry
646
647#include "EBGeometry_PoolImplem.hpp"
648
649#endif // EBGEOMETRY_POOL_HPP
GPU portability layer: host/device decoration macros and backend detection.
#define EBGEOMETRY_HOST_DEVICE
Mark a function as callable from both host and device code (no-op on host compilers).
Definition EBGeometry_GPU.hpp:80
#define EBGEOMETRY_HOST
Mark a function as callable from host code only (no-op on host compilers).
Definition EBGeometry_GPU.hpp:83
Utility macros for EBGeometry.
#define EBGEOMETRY_EXPECT(cond)
Runtime precondition assertion for EBGeometry.
Definition EBGeometry_Macros.hpp:155
Placement-policy layer for the GPU memory foundation: the abstract MemoryResource and its concrete ho...
Abstract placement policy: allocates and frees raw, correctly-aligned byte blocks.
Definition EBGeometry_MemoryResource.hpp:69
Base of every pool-resident handle: the one PoolLocation its arrays resolve against.
Definition EBGeometry_Pool.hpp:499
PoolHandle(PoolHandle &&) noexcept=default
Move a handle; the same as a copy.
bool isAttachedTo(const Pool &a_pool) const noexcept
Check whether this handle's arrays were reserved from a_pool.
Definition EBGeometry_Pool.hpp:519
PoolLocation location() const noexcept
Where this handle's arrays live.
Definition EBGeometry_Pool.hpp:507
PoolHandle(const PoolHandle &) noexcept=default
Copy a handle, as a derived handle's copy does.
PoolLocation rebasedLocation(const Pool &a_pool, uint64_t a_endByte, const char *a_who) const noexcept
The location of this handle's arrays in another pool of its mirror chain; see PoolLocation::rebasedOn...
Definition EBGeometry_Pool.hpp:615
void attach(const Pool &a_pool, const char *a_who) noexcept
Follow a_pool, as the first reservation does; see PoolLocation::attach().
Definition EBGeometry_Pool.hpp:600
const void * base() const noexcept
The base address this handle's offsets resolve against, for read-only access.
Definition EBGeometry_Pool.hpp:588
PoolHandle() noexcept=default
An unset location; the first reservation attaches it.
void * base() noexcept
The base address this handle's offsets resolve against; see PoolLocation::base().
Definition EBGeometry_Pool.hpp:575
void setLocation(const PoolLocation &a_location) noexcept
Replace the location, for a view or a copy made by a derived handle.
Definition EBGeometry_Pool.hpp:626
Growable bump arena over a MemoryResource.
Definition EBGeometry_Pool.hpp:183
size_t capacityBytes() const noexcept
Bytes currently allocated for the block.
Definition EBGeometry_Pool.hpp:368
void * base() const noexcept
Base address of the block.
Definition EBGeometry_Pool.hpp:287
uint64_t rootId() const noexcept
Identity of the root of this pool's mirror chain.
Definition EBGeometry_Pool.hpp:346
static Pool mirror(const Pool &a_src, MemoryResource &a_dstResource)
Mirror a frozen pool's whole block into another resource.
const PoolControl * control() const noexcept
This pool's stable control block, through which pool-resident objects re-resolve the base on every ac...
Definition EBGeometry_Pool.hpp:303
size_t usedBytes() const noexcept
Bytes currently in use (the bump cursor).
Definition EBGeometry_Pool.hpp:357
bool isFrozen() const noexcept
Whether the pool has been frozen.
Definition EBGeometry_Pool.hpp:379
uint64_t mirrorOf() const noexcept
Identity of the pool this one ultimately mirrors, or zero if it is not a mirror.
Definition EBGeometry_Pool.hpp:332
uint64_t id() const noexcept
Identity of this pool, unique among all pools constructed in this process.
Definition EBGeometry_Pool.hpp:316
~Pool() noexcept
Destructor. Returns the block to the backing resource.
MemoryResource & resource() const noexcept
The backing memory resource.
Definition EBGeometry_Pool.hpp:390
Pool(MemoryResource &a_resource, size_t a_initialBytes=0)
Construct an empty pool over a_resource, optionally pre-reserving a block.
uint64_t reserve(size_t a_count, size_t a_elemSize, size_t a_alignment)
Bump-reserve a_count * a_elemSize bytes aligned to a_alignment.
void freeze() noexcept
Freeze the block: forbid further reserve, stabilize base, enable mirror.
Namespace containing all of EBGeometry's functionality.
Definition EBGeometry_Affine.hpp:26
constexpr size_t PoolBaseAlign
Block-base alignment for every Pool, in bytes.
Definition EBGeometry_MemoryResource.hpp:52
constexpr bool isPoolHandle
Whether P is a pool-resident handle (derives from PoolHandle).
Definition EBGeometry_Pool.hpp:643
Stable, heap-resident handle to a Pool's current base address and identity.
Definition EBGeometry_Pool.hpp:63
uint64_t m_id
Identity of the owning pool; see Pool::id. Never zero for a live pool.
Definition EBGeometry_Pool.hpp:69
void * m_base
Current base address of the owning pool's block. Rewritten whenever a Pool::reserve grows the block.
Definition EBGeometry_Pool.hpp:66
uint64_t m_rootId
Identity of the root of the owning pool's mirror chain: its own identity for a pool that is not a mir...
Definition EBGeometry_Pool.hpp:73
Where a pool-resident descriptor resolves its offsets, and the rules for moving it.
Definition EBGeometry_Pool.hpp:99
PoolLocation rebasedOnto(const Pool &a_pool, uint64_t a_endByte, const char *a_who) const noexcept
The location of the same arrays in another pool of the same mirror chain.
const PoolControl * m_control
Control block of the pool the descriptor follows; null for a snapshot or when unset.
Definition EBGeometry_Pool.hpp:101
bool m_hostAccessible
Whether host code may dereference a snapshot's base (managed or mapped memory).
Definition EBGeometry_Pool.hpp:107
void attach(const Pool &a_pool, const char *a_who) noexcept
Start following a pool, as the descriptor's first reservation from it does.
void * base() const noexcept
The base address the descriptor's offsets resolve against.
Definition EBGeometry_Pool.hpp:118
void * m_base
Base address captured by a snapshot; null otherwise.
Definition EBGeometry_Pool.hpp:104
bool isAttachedTo(const Pool &a_pool) const noexcept
Whether this location follows the given pool.