Grindstone Game Engine v0.2.0
An open source game engine and toolkit.
All Classes Pages
PoolAllocator.hpp
1#pragma once
2
3#include <stdint.h>
4#include <utility>
5#include <functional>
6#include <memory>
7
8#include "../SmartPointers.hpp"
9
10
11namespace Grindstone::Memory::Allocators {
13 public:
14
15 void Clear();
16 void ClearAndZero();
17 void Destroy();
18
19 bool IsEmpty() const;
20 size_t GetUsedCount() const;
21
22 struct FreeLink {
23 FreeLink* next;
24 };
25
26 protected:
27 BasePoolAllocator() = default;
28
29 inline void* AllocateImpl();
30 inline void SetupLinkedList();
31
32 void DeallocateImpl(size_t index);
33 void DeallocateImpl(void* ptr);
34
35 // Total Memory size is used in case we are passed owned memory that is bigger than totalChunkCount * chunkSize
36 size_t totalMemorySize = 0;
37 size_t chunkSize = 0;
38 size_t usedChunkCount = 0;
39 size_t totalChunkCount = 0;
40
41 FreeLink* headFreePtr = nullptr;
42 void* memory = nullptr;
43 bool hasAllocatedOwnMemory = false;
44 std::function<void(void*)> deleteFn;
45 };
46
55 public:
56 GenericPoolAllocator() = default;
58
59 void Initialize(void* ownedMemory, size_t totalSize, size_t sizePerChunk);
60 bool Initialize(size_t sizePerChunk, size_t maxChunkCount);
61 void* Allocate();
62 void Deallocate(size_t index);
63 void Deallocate(void* ptr);
64
65 };
66
74 template <typename T>
76 public:
77 PoolAllocator() = default;
78
79 bool Initialize(void* ownedMemory, size_t totalSize) {
80 memory = ownedMemory;
81 totalMemorySize = totalSize;
82 chunkSize = sizeof(T);
83 usedChunkCount = 0;
84 totalChunkCount = totalSize / chunkSize;
85 hasAllocatedOwnMemory = false;
86
87 deleteFn = [this](void* ptr) -> void {
88 DeallocateImpl(ptr);
89 };
90
91 SetupLinkedList();
92 }
93
94 bool Initialize(size_t maxChunkCount) {
95 chunkSize = sizeof(T);
96 totalMemorySize = chunkSize * maxChunkCount;
97 usedChunkCount = 0;
98 totalChunkCount = maxChunkCount;
99
100 memory = malloc(totalMemorySize);
101 hasAllocatedOwnMemory = true;
102
103 SetupLinkedList();
104
105 deleteFn = [this](void* ptr) -> void {
106 DeallocateImpl(ptr);
107 };
108
109 return memory != nullptr;
110 }
111
112 template<typename... Args>
113 SharedPtr<T> AllocateShared(Args&&... params) {
114 T* ptr = static_cast<T*>(AllocateImpl());
115 if (ptr != nullptr) {
116 // Call the constructor on the newly allocated memory
117 new (ptr) T(std::forward<Args>(params)...);
118 }
119
120 return SharedPtr<T>(ptr, deleteFn);
121 }
122
123 template<typename... Args>
124 UniquePtr<T> AllocateUnique(Args&&... params) {
125 T* ptr = static_cast<T*>(AllocateImpl());
126 if (ptr != nullptr) {
127 // Call the constructor on the newly allocated memory
128 new (ptr) T(std::forward<Args>(params)...);
129 }
130
131 return UniquePtr<T>(ptr, deleteFn);
132 }
133
134 template<typename... Args>
135 T* AllocateRaw(Args&&... params) {
136 T* ptr = static_cast<T*>(AllocateImpl());
137 if (ptr != nullptr) {
138 // Call the constructor on the newly allocated memory
139 new (ptr) T(std::forward<Args>(params)...);
140 }
141
142 return ptr;
143 }
144
145 T* AllocateWithoutConstructor() {
146 return static_cast<T*>(AllocateImpl());
147 }
148
149 void Deallocate(size_t index) {
150 size_t chunkOffset = index * chunkSize;
151 void* ptr = reinterpret_cast<char*>(memory) + chunkOffset;
152 reinterpret_cast<T*>(ptr)->~T();
153 DeallocateImpl(ptr);
154 }
155
156 void Deallocate(void* ptr) {
157 reinterpret_cast<T*>(ptr)->~T();
158 DeallocateImpl(ptr);
159 }
160
161 void DeallocateWithoutDestructor(size_t index) {
162 size_t chunkOffset = index * chunkSize;
163 void* ptr = reinterpret_cast<char*>(memory) + chunkOffset;
164 DeallocateImpl(ptr);
165 }
166
167 void DeallocateWithoutDestructor(void* ptr) {
168 DeallocateImpl(ptr);
169 }
170 };
171}
A generic pool allocator where all allocations have up to a certain chunk size.
Definition PoolAllocator.hpp:54
A typed pool allocator where all allocations are the size of the type T.
Definition PoolAllocator.hpp:75