15#include <vsg/core/Allocator.h>
44 class VSG_DECLSPEC IntrusiveAllocator :
public Allocator
47 explicit IntrusiveAllocator(
size_t in_defaultAlignment = 8);
48 explicit IntrusiveAllocator(std::unique_ptr<Allocator> in_nestedAllocator,
size_t in_defaultAlignment = 8);
50 ~IntrusiveAllocator();
52 void report(std::ostream& out)
const override;
54 void*
allocate(std::size_t size, AllocatorAffinity allocatorAffinity = ALLOCATOR_AFFINITY_OBJECTS)
override;
58 bool validate()
const;
64 void setBlockSize(AllocatorAffinity allocatorAffinity,
size_t blockSize)
override;
67 struct VSG_DECLSPEC MemoryBlock
69 MemoryBlock(
const std::string& in_name,
size_t in_blockSize,
size_t in_alignment);
70 virtual ~MemoryBlock();
74 void* allocate(std::size_t size);
75 bool deallocate(
void* ptr, std::size_t size);
77 void report(std::ostream& out)
const;
88 unsigned int previous : 15;
89 unsigned int next : 15;
90 unsigned int status : 2;
94 using Offset =
decltype(previous);
95 using Status =
decltype(status);
96 using Index =
decltype(index);
98 explicit Element(Index in_index) :
99 index(
static_cast<Offset
>(in_index)) {}
101 Element(Offset in_previous, Offset in_next, Status in_status) :
102 previous(
static_cast<Offset
>(in_previous)),
103 next(
static_cast<Offset
>(in_next)),
107 Element(
const Element&) =
default;
112 Element::Index count = 0;
113 Element::Index head = 0;
119 size_t alignment = 8;
120 size_t blockAlignment = 16;
121 size_t blockSize = 0;
122 size_t maximumAllocationSize = 0;
123 Element::Index elementAlignment = 1;
124 Element::Index firstSlot = 1;
125 Element::Index capacity = 0;
127 std::vector<FreeList> freeLists;
129 bool validate()
const;
131 bool freeSlotsAvaible(
size_t size)
const;
133 inline bool within(
const void* ptr)
const {
return memory <= ptr && ptr < memoryEnd; }
140 struct VSG_DECLSPEC SlotTester
142 SlotTester(
Element* in_mem,
size_t in_head) :
143 mem(in_mem), head(in_head){};
157 std::list<Entry> elements;
159 void slot(
size_t position,
const std::string& name);
161 void report(std::ostream& out);
164 static inline size_t computeMaxiumAllocationSize(
size_t blockSize,
size_t alignment)
166 return std::min(blockSize - alignment,
size_t((1 << 15) - 2) *
sizeof(
Element));
170 class VSG_DECLSPEC MemoryBlocks
173 MemoryBlocks(IntrusiveAllocator* in_parent,
const std::string& in_name,
size_t in_blockSize,
size_t in_alignment);
174 virtual ~MemoryBlocks();
176 IntrusiveAllocator* parent =
nullptr;
178 size_t alignment = 8;
179 size_t blockSize = 0;
180 size_t maximumAllocationSize = 0;
181 std::vector<std::shared_ptr<MemoryBlock>> memoryBlocks;
182 std::shared_ptr<MemoryBlock> memoryBlockWithSpace;
184 void* allocate(std::size_t size);
185 void report(std::ostream& out)
const;
186 bool validate()
const;
188 size_t deleteEmptyMemoryBlocks();
189 size_t totalAvailableSize()
const;
190 size_t totalReservedSize()
const;
191 size_t totalMemorySize()
const;
194 std::vector<std::unique_ptr<MemoryBlocks>> allocatorMemoryBlocks;
195 std::map<void*, std::shared_ptr<MemoryBlock>> memoryBlocks;
196 std::map<void*, std::pair<size_t, size_t>> largeAllocations;
size_t totalMemorySize() const override
return the total memory size of allocated MemoryBlocks
size_t totalReservedSize() const override
return the total reserved size of allocated MemoryBlocks
void * allocate(std::size_t size, AllocatorAffinity allocatorAffinity=ALLOCATOR_AFFINITY_OBJECTS) override
allocate from the pool of memory blocks, or allocate from a new memory block
void report(std::ostream &out) const override
report stats about blocks of memory allocated.
bool deallocate(void *ptr, std::size_t size) override
deallocate, returning data to pool.
size_t totalAvailableSize() const override
return the total available size of allocated MemoryBlocks
size_t deleteEmptyMemoryBlocks() override
delete any MemoryBlock that are empty
Definition IntrusiveAllocator.h:81
Definition IntrusiveAllocator.h:111
Definition IntrusiveAllocator.h:149