17 #include "../error_func.h"
19 #include "../saveload/saveload_error.hpp"
25 #define DEFINE_POOL_METHOD(type) \
26 template <class Titem, typename Tindex, size_t Tgrowth_step, size_t Tmax_size, PoolType Tpool_type, bool Tcache, bool Tzero> \
27 type Pool<Titem, Tindex, Tgrowth_step, Tmax_size, Tpool_type, Tcache, Tzero>
56 assert(index >= this->size);
57 assert(index < Tmax_size);
59 size_t new_size = std::min(Tmax_size,
Align(index + 1, Tgrowth_step));
61 this->data =
ReallocT(this->data, new_size);
62 MemSetT(this->data + this->size, 0, new_size - this->size);
64 this->used_bitmap.resize(
Align(new_size, BITMAP_SIZE) / BITMAP_SIZE);
65 if (this->size % BITMAP_SIZE != 0) {
67 this->used_bitmap[this->size / BITMAP_SIZE] &= ~((~static_cast<BitmapStorage>(0)) << (this->size % BITMAP_SIZE));
69 if (new_size % BITMAP_SIZE != 0) {
71 this->used_bitmap[new_size / BITMAP_SIZE] |= (~static_cast<BitmapStorage>(0)) << (new_size % BITMAP_SIZE);
74 this->size = new_size;
83 for (
auto it = std::next(std::begin(this->used_bitmap), this->first_free / BITMAP_SIZE); it != std::end(this->used_bitmap); ++it) {
84 BitmapStorage available = ~(*it);
85 if (available == 0)
continue;
86 return std::distance(std::begin(this->used_bitmap), it) * BITMAP_SIZE +
FindFirstBit(available);
89 assert(this->first_unused == this->size);
91 if (this->first_unused < Tmax_size) {
92 this->ResizeFor(this->first_unused);
93 return this->first_unused;
96 assert(this->first_unused == Tmax_size);
110 assert(this->data[index] ==
nullptr);
112 this->first_unused = std::max(this->first_unused, index + 1);
116 if (Tcache && this->alloc_cache !=
nullptr) {
117 assert(
sizeof(Titem) == size);
118 item =
reinterpret_cast<Titem *
>(this->alloc_cache);
119 this->alloc_cache = this->alloc_cache->next;
123 memset(
static_cast<void *
>(item), 0,
sizeof(Titem));
126 item =
reinterpret_cast<Titem *
>(CallocT<uint8_t>(size));
128 item =
reinterpret_cast<Titem *
>(MallocT<uint8_t>(size));
130 this->data[index] = item;
131 SetBit(this->used_bitmap[index / BITMAP_SIZE], index % BITMAP_SIZE);
132 item->index = (Tindex)(uint)index;
144 size_t index = this->FindFirstFree();
147 assert(this->checked != 0);
150 if (index == NO_FREE_ITEM) {
151 FatalError(
"{}: no more free items", this->name);
154 this->first_free = index + 1;
155 return this->AllocateItem(size, index);
167 if (index >= Tmax_size) {
168 SlErrorCorruptFmt(
"{} index {} out of range ({})", this->name, index, Tmax_size);
171 if (index >= this->size) this->ResizeFor(index);
173 if (this->data[index] !=
nullptr) {
174 SlErrorCorruptFmt(
"{} index {} already in use", this->name, index);
177 return this->AllocateItem(size, index);
188 assert(index < this->size);
189 assert(this->data[index] !=
nullptr);
191 AllocCache *ac =
reinterpret_cast<AllocCache *
>(this->data[index]);
192 ac->next = this->alloc_cache;
193 this->alloc_cache = ac;
195 free(this->data[index]);
197 this->data[index] =
nullptr;
198 this->first_free = std::min(this->first_free, index);
200 if (!this->cleaning) {
201 ClrBit(this->used_bitmap[index / BITMAP_SIZE], index % BITMAP_SIZE);
202 Titem::PostDestructor(index);
209 this->cleaning =
true;
210 for (
size_t i = 0; i < this->first_unused; i++) {
213 assert(this->items == 0);
215 this->used_bitmap.clear();
216 this->used_bitmap.shrink_to_fit();
217 this->first_unused = this->first_free = this->size = 0;
218 this->data =
nullptr;
219 this->cleaning =
false;
222 while (this->alloc_cache !=
nullptr) {
223 AllocCache *ac = this->alloc_cache;
224 this->alloc_cache = ac->next;
230 #undef DEFINE_POOL_METHOD
237 #define INSTANTIATE_POOL_METHODS(name) \
238 template void * name ## Pool::GetNew(size_t size); \
239 template void * name ## Pool::GetNew(size_t size, size_t index); \
240 template void name ## Pool::FreeItem(size_t index); \
241 template void name ## Pool::CleanPool();
Functions related to the allocation of memory.
T * ReallocT(T *t_ptr, size_t num_elements)
Simplified reallocation function that allocates the specified number of elements of the given type.
Functions related to bit mathematics.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
constexpr uint8_t FindFirstBit(T x)
Search the first set bit in a value.
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
constexpr T Align(const T x, uint n)
Return the smallest multiple of n equal or greater than x.
Functions related to memory operations.
void MemSetT(T *ptr, uint8_t value, size_t num=1)
Type-safe version of memset().
#define DEFINE_POOL_METHOD(type)
Helper for defining the method's signature.
Definition of Pool, structure used to access PoolItems, and PoolItem, base structure for Vehicle,...
void free(const void *ptr)
Version of the standard free that accepts const pointers.
Base class for base of all pools.
Base class for all pools.