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);
159 if (index >= Tmax_size) {
160 usererror(
"failed loading savegame: %s index " PRINTF_SIZE
" out of range (" PRINTF_SIZE
")", this->name, index, Tmax_size);
163 if (index >= this->size) this->ResizeFor(index);
165 if (this->data[index] != NULL) {
166 usererror(
"failed loading savegame: %s index " PRINTF_SIZE
" already in use", this->name, index);
169 return this->AllocateItem(size, index);
180 assert(index < this->size);
181 assert(this->data[index] != NULL);
183 AllocCache *ac = (AllocCache *)this->data[index];
184 ac->next = this->alloc_cache;
185 this->alloc_cache = ac;
187 free(this->data[index]);
189 this->data[index] = NULL;
190 this->first_free =
min(this->first_free, index);
192 if (!this->cleaning) Titem::PostDestructor(index);
198 this->cleaning =
true;
199 for (
size_t i = 0; i < this->first_unused; i++) {
202 assert(this->items == 0);
204 this->first_unused = this->first_free = this->size = 0;
206 this->cleaning =
false;
209 while (this->alloc_cache != NULL) {
210 AllocCache *ac = this->alloc_cache;
211 this->alloc_cache = ac->next;
217 #undef DEFINE_POOL_METHOD
224 #define INSTANTIATE_POOL_METHODS(name) \
225 template void * name ## Pool::GetNew(size_t size); \
226 template void * name ## Pool::GetNew(size_t size, size_t index); \
227 template void name ## Pool::FreeItem(size_t index); \
228 template void name ## Pool::CleanPool();