15#include <vsg/core/Allocator.h>
45 class VSG_DECLSPEC IntrusiveAllocator :
public Allocator
48 explicit IntrusiveAllocator(
size_t in_defaultAlignment = 8);
49 explicit IntrusiveAllocator(std::unique_ptr<Allocator> in_nestedAllocator,
size_t in_defaultAlignment = 8);
51 ~IntrusiveAllocator();
53 void report(std::ostream& out)
const override;
55 void*
allocate(std::size_t size, AllocatorAffinity allocatorAffinity = ALLOCATOR_AFFINITY_OBJECTS)
override;
59 bool validate()
const;
65 void setBlockSize(AllocatorAffinity allocatorAffinity,
size_t blockSize)
override;
68 struct VSG_DECLSPEC MemoryBlock
70 MemoryBlock(
const std::string& in_name,
size_t in_blockSize,
size_t in_alignment);
71 virtual ~MemoryBlock();
75 void* allocate(std::size_t size);
76 bool deallocate(
void* ptr, std::size_t size);
78 void report(std::ostream& out)
const;
89 unsigned int previous : 15;
90 unsigned int next : 15;
91 unsigned int status : 2;
95 using Offset =
decltype(previous);
96 using Status =
decltype(status);
97 using Index =
decltype(index);
99 explicit Element(Index in_index) :
100 index(
static_cast<Offset
>(in_index)) {}
102 Element(Offset in_previous, Offset in_next, Status in_status) :
103 previous(
static_cast<Offset
>(in_previous)),
104 next(
static_cast<Offset
>(in_next)),
108 Element(
const Element&) =
default;
109 Element& operator=(
const Element&) =
default;
114 Element::Index count = 0;
115 Element::Index head = 0;
121 size_t alignment = 8;
122 size_t blockAlignment = 16;
123 size_t blockSize = 0;
124 size_t maximumAllocationSize = 0;
125 Element::Index elementAlignment = 1;
126 Element::Index firstSlot = 1;
127 Element::Index capacity = 0;
129 std::vector<FreeList> freeLists;
131 bool validate()
const;
133 bool freeSlotsAvaible(
size_t size)
const;
135 inline bool within(
const void* ptr)
const {
return memory <= ptr && ptr < memoryEnd; }
142 struct VSG_DECLSPEC SlotTester
144 SlotTester(
Element* in_mem,
size_t in_head) :
145 mem(in_mem), head(in_head){};
159 std::list<Entry> elements;
161 void slot(
size_t position,
const std::string& name);
163 void report(std::ostream& out);
166 static inline size_t computeMaxiumAllocationSize(
size_t blockSize,
size_t alignment)
168 return std::min(blockSize - alignment,
size_t((1 << 15) - 2) *
sizeof(
Element));
172 class VSG_DECLSPEC MemoryBlocks
175 MemoryBlocks(IntrusiveAllocator* in_parent,
const std::string& in_name,
size_t in_blockSize,
size_t in_alignment);
176 virtual ~MemoryBlocks();
178 IntrusiveAllocator* parent =
nullptr;
180 size_t alignment = 8;
181 size_t blockSize = 0;
182 size_t maximumAllocationSize = 0;
183 std::vector<std::shared_ptr<MemoryBlock>> memoryBlocks;
184 std::shared_ptr<MemoryBlock> memoryBlockWithSpace;
186 void* allocate(std::size_t size);
187 void report(std::ostream& out)
const;
188 bool validate()
const;
190 size_t deleteEmptyMemoryBlocks();
191 size_t totalAvailableSize()
const;
192 size_t totalReservedSize()
const;
193 size_t totalMemorySize()
const;
196 std::vector<std::unique_ptr<MemoryBlocks>> allocatorMemoryBlocks;
197 std::map<void*, std::shared_ptr<MemoryBlock>> memoryBlocks;
198 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:82
Definition IntrusiveAllocator.h:113
Definition IntrusiveAllocator.h:151