CookMem 1.4.0
A C++ memory context / allocator
Loading...
Searching...
No Matches
arena.h
1/*
2 * Copyright (c) 2018-2026 Heng Yuan
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#ifndef COOK_MEM_ARENA_H
17#define COOK_MEM_ARENA_H
18
19#include <cstddef>
20#include <cstdint>
21
22#include "config.h"
23#include "rbtree.h"
24
25namespace cookmem
26{
27
34{
35public:
36 virtual ~MemArena() {}
37
46 virtual void*
47 getSegment (std::size_t& size) = 0;
48
58 virtual bool
59 freeSegment (void* ptr, std::size_t size) = 0;
60
66 virtual void
67 releaseAll () = 0;
68};
69
79{
80public:
93 FixedArena (void* ptr, std::size_t size)
94 : m_used (false)
95 {
96 const std::size_t mask = ALLOCATION_ALIGNMENT - 1;
97 std::size_t remain = reinterpret_cast<std::uintptr_t> (ptr) & mask;
98 if (remain)
99 {
100 std::size_t inc = ALLOCATION_ALIGNMENT - remain;
101 m_page = static_cast<char*> (ptr) + inc;
102 // A buffer smaller than the bytes skipped has no usable space.
103 size = (size > inc) ? size - inc : 0;
104 }
105 else
106 {
107 m_page = ptr;
108 }
109 size &= ~mask;
110 m_size = size;
111 }
112
121 void*
122 getSegment (std::size_t& size)
123 {
124 if (m_used || size > m_size)
125 {
126 return NULL;
127 }
128 m_used = true;
129 size = m_size;
130 return m_page;
131 }
132
142 bool
143 freeSegment (void* ptr, std::size_t size)
144 {
145 if (!m_used || ptr != m_page || size != m_size)
146 {
147 return true;
148 }
149 m_used = false;
150 return false;
151 }
152
157 void
159 {
160 }
161
162private:
163 void* m_page;
164 std::size_t m_size;
165 bool m_used;
166};
167
182template<class Arena, class TreeType = PtrRBTree>
184{
185public:
188public:
196 : m_arena (arena),
197 m_tree ()
198 {
199 }
200
205 {
206 releaseAll ();
207 }
208
209 CachedArena (const CachedArena&) = delete;
210 CachedArena& operator= (const CachedArena&) = delete;
211
223 void*
224 getSegment (std::size_t& size)
225 {
226 void* seg = m_tree.remove(size);
227 if (seg)
228 {
229 return seg;
230 }
231 return m_arena.getSegment(size);
232 }
233
246 bool
247 freeSegment (void* ptr, std::size_t size)
248 {
249 m_tree.add (ptr, size);
250 return false;
251 }
252
257 void
259 {
260 for (;;)
261 {
262 std::size_t size = 0;
263 void* seg = m_tree.remove (size);
264 if (seg == nullptr)
265 {
266 break;
267 }
268 m_arena.freeSegment (seg, size);
269 }
270 }
271
272private:
273 Arena& m_arena;
274 PtrTreeType m_tree;
275};
276
277
278} // namespace cookmem
279
280#endif // COOK_MEM_ARENA_H
Definition arena.h:184
void * getSegment(std::size_t &size)
Definition arena.h:224
TreeType PtrTreeType
Definition arena.h:187
CachedArena(Arena &arena)
Definition arena.h:195
bool freeSegment(void *ptr, std::size_t size)
Definition arena.h:247
void releaseAll()
Definition arena.h:258
~CachedArena()
Definition arena.h:204
Definition arena.h:79
void releaseAll()
Definition arena.h:158
FixedArena(void *ptr, std::size_t size)
Definition arena.h:93
void * getSegment(std::size_t &size)
Definition arena.h:122
bool freeSegment(void *ptr, std::size_t size)
Definition arena.h:143
Definition arena.h:34
virtual bool freeSegment(void *ptr, std::size_t size)=0
virtual void releaseAll()=0
virtual void * getSegment(std::size_t &size)=0
Definition allocator.h:39
Definition allocator.h:29
const std::size_t ALLOCATION_ALIGNMENT
Definition config.h:36