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. */
12 #ifndef DYN_ARENA_ALLOC_HPP
13 #define DYN_ARENA_ALLOC_HPP
18 * Custom arena allocator for uniform-size allocations of a variable size.
19 * The allocation and chunk sizes may only be changed when the arena is empty.
21 class DynUniformArenaAllocator
{
22 std::vector
<void *> used_blocks
;
24 void *current_block
= nullptr;
25 void *last_freed
= nullptr;
26 size_t next_position
= 0;
29 size_t items_per_chunk
= 0;
33 current_block
= malloc(item_size
* items_per_chunk
);
34 assert(current_block
!= nullptr);
36 used_blocks
.push_back(current_block
);
40 DynUniformArenaAllocator() = default;
41 DynUniformArenaAllocator(const DynUniformArenaAllocator
&other
) = delete;
42 DynUniformArenaAllocator
& operator=(const DynUniformArenaAllocator
&other
) = delete;
44 ~DynUniformArenaAllocator()
51 current_block
= nullptr;
54 for (void *block
: used_blocks
) {
68 assert(item_size
!= 0);
70 void *ptr
= last_freed
;
71 last_freed
= *reinterpret_cast<void**>(ptr
);
74 if (current_block
== nullptr || next_position
== items_per_chunk
) {
77 void *out
= reinterpret_cast<char *>(current_block
) + (item_size
* next_position
);
83 void Free(void *ptr
) {
85 assert(current_block
!= nullptr);
87 *reinterpret_cast<void**>(ptr
) = last_freed
;
91 void SetParameters(size_t item_size
, size_t items_per_chunk
)
93 if (item_size
< sizeof(void *)) item_size
= sizeof(void *);
94 if (this->item_size
== item_size
&& this->items_per_chunk
== items_per_chunk
) return;
96 assert(current_block
== nullptr);
97 this->item_size
= item_size
;
98 this->items_per_chunk
= items_per_chunk
;
102 #endif /* DYN_ARENA_ALLOC_HPP */