23 #define DEFINE_POOL_METHOD(type) \ 24 template <class Titem, typename Tindex, size_t Tgrowth_step, size_t Tmax_size, PoolType Tpool_type, bool Tcache, bool Tzero> \ 25 type Pool<Titem, Tindex, Tgrowth_step, Tmax_size, Tpool_type, Tcache, Tzero> 54 assert(index >= this->size);
55 assert(index < Tmax_size);
57 size_t new_size =
min(Tmax_size,
Align(index + 1, Tgrowth_step));
59 this->data =
ReallocT(this->data, new_size);
60 MemSetT(this->data + this->size, 0, new_size - this->size);
62 this->size = new_size;
71 size_t index = this->first_free;
73 for (; index < this->first_unused; index++) {
74 if (this->data[index] == NULL)
return index;
77 if (index < this->size) {
81 assert(index == this->size);
82 assert(this->first_unused == this->size);
84 if (index < Tmax_size) {
85 this->ResizeFor(index);
89 assert(this->items == Tmax_size);
103 assert(this->data[index] == NULL);
105 this->first_unused =
max(this->first_unused, index + 1);
109 if (Tcache && this->alloc_cache != NULL) {
110 assert(
sizeof(Titem) == size);
111 item = (Titem *)this->alloc_cache;
112 this->alloc_cache = this->alloc_cache->next;
116 memset((
void *)item, 0,
sizeof(Titem));
119 item = (Titem *)CallocT<byte>(size);
121 item = (Titem *)MallocT<byte>(size);
123 this->data[index] = item;
124 item->index = (Tindex)(uint)index;
136 size_t index = this->FindFirstFree();
139 assert(this->checked != 0);
142 if (index == NO_FREE_ITEM) {
143 error(
"%s: no more free items", this->name);
146 this->first_free = index + 1;
147 return this->AllocateItem(size, index);
161 if (index >= Tmax_size) {
162 SlErrorCorruptFmt(
"%s index " PRINTF_SIZE
" out of range (" PRINTF_SIZE
")", this->name, index, Tmax_size);
165 if (index >= this->size) this->ResizeFor(index);
167 if (this->data[index] != NULL) {
171 return this->AllocateItem(size, index);
182 assert(index < this->size);
183 assert(this->data[index] != NULL);
185 AllocCache *ac = (AllocCache *)this->data[index];
186 ac->next = this->alloc_cache;
187 this->alloc_cache = ac;
189 free(this->data[index]);
191 this->data[index] = NULL;
192 this->first_free =
min(this->first_free, index);
194 if (!this->cleaning) Titem::PostDestructor(index);
200 this->cleaning =
true;
201 for (
size_t i = 0; i < this->first_unused; i++) {
204 assert(this->items == 0);
206 this->first_unused = this->first_free = this->size = 0;
208 this->cleaning =
false;
211 while (this->alloc_cache != NULL) {
212 AllocCache *ac = this->alloc_cache;
213 this->alloc_cache = ac->next;
219 #undef DEFINE_POOL_METHOD 226 #define INSTANTIATE_POOL_METHODS(name) \ 227 template void * name ## Pool::GetNew(size_t size); \ 228 template void * name ## Pool::GetNew(size_t size, size_t index); \ 229 template void name ## Pool::FreeItem(size_t index); \ 230 template void name ## Pool::CleanPool(); Base class for base of all pools.
void NORETURN SlErrorCorruptFmt(const char *format,...)
Issue an SlErrorCorrupt with a format string.
static T max(const T a, const T b)
Returns the maximum of two values.
Defintion of Pool, structure used to access PoolItems, and PoolItem, base structure for Vehicle...
static T Align(const T x, uint n)
Return the smallest multiple of n equal or greater than x.
Functions related to the allocation of memory.
static T * ReallocT(T *t_ptr, size_t num_elements)
Simplified reallocation function that allocates the specified number of elements of the given type...
static T min(const T a, const T b)
Returns the minimum of two values.
Base class for all pools.
void CDECL error(const char *s,...)
Error handling for fatal non-user errors.
#define DEFINE_POOL_METHOD(type)
Helper for defining the method's signature.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Functions related to memory operations.
static void MemSetT(T *ptr, byte value, size_t num=1)
Type-safe version of memset().