4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
10 /** @file dyn_arena_alloc.hpp Dynamic chunk-size arena allocator. */
15 * Custom arena allocator for uniform-size allocations of a variable size.
16 * The allocation and chunk sizes may only be changed when the arena is empty.
18 class DynUniformArenaAllocator
{
19 std::vector
<void *> used_blocks
;
21 void *current_block
= nullptr;
22 void *last_freed
= nullptr;
23 size_t next_position
= 0;
26 size_t items_per_chunk
= 0;
30 current_block
= malloc(item_size
* items_per_chunk
);
31 assert(current_block
!= nullptr);
33 used_blocks
.push_back(current_block
);
37 DynUniformArenaAllocator() = default;
38 DynUniformArenaAllocator(const DynUniformArenaAllocator
&other
) = delete;
39 DynUniformArenaAllocator
& operator=(const DynUniformArenaAllocator
&other
) = delete;
41 ~DynUniformArenaAllocator()
48 current_block
= nullptr;
51 for (void *block
: used_blocks
) {
65 assert(item_size
!= 0);
67 void *ptr
= last_freed
;
68 last_freed
= *reinterpret_cast<void**>(ptr
);
71 if (current_block
== nullptr || next_position
== items_per_chunk
) {
74 void *out
= reinterpret_cast<char *>(current_block
) + (item_size
* next_position
);
80 void Free(void *ptr
) {
82 assert(current_block
!= nullptr);
84 *reinterpret_cast<void**>(ptr
) = last_freed
;
88 void SetParameters(size_t item_size
, size_t items_per_chunk
)
90 if (item_size
< sizeof(void *)) item_size
= sizeof(void *);
91 if (this->item_size
== item_size
&& this->items_per_chunk
== items_per_chunk
) return;
93 assert(current_block
== nullptr);
94 this->item_size
= item_size
;
95 this->items_per_chunk
= items_per_chunk
;