Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
allocation-cluster.cpp
Go to the documentation of this file.
1/*
2 AllocationCluster - allocating and owning a pile of objects
3
4 Copyright (C)
5 2008, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12* *****************************************************************/
13
14
34#include "lib/format-string.hpp"
35#include "lib/util-quant.hpp"
36#include "lib/util.hpp"
37
38
39using util::unConst;
40using util::isPow2;
41using util::isnil;
42using util::_Fmt;
43using std::byte;
44
45
46namespace lib {
47 namespace {// Internals...
48
57 {
62 template<class X>
63 void
64 dispose (X* elm)
65 {
66 REQUIRE (elm);
67 elm->~X();
68 }
69 };
70
71 }//(End)configuration and internals
72
73
74
75
76
92 {
93
95
105
106 static_assert (sizeof(Destructors) == sizeof(void*));
107 static_assert (sizeof(Extents) == sizeof(void*));
108
110 {
113 }; //Note: storage.pos and extents.head_ reside at the same location
114
116
117 StorageManager() = delete;
118
119 public:
120 static StorageManager&
122 {
123 return reinterpret_cast<StorageManager&> (clu);
124 }
125
126 void
128 {
131 }
132
133 void
135 {
138 }
139
140 void
142 {
144 }
145
146
147 bool
148 empty() const
149 {
150 return nullptr == view_.storage.pos;
151 }
152
153 size_t
155 {
156 return empty()? 0
158 .size();
159 }
160
161 size_t
163 {
164 ENSURE (max_size() >= view_.storage.rest);
165 return max_size() - view_.storage.rest;
166 }
167
168
169 private:
170 Extent*
172 {
173 REQUIRE (not empty());
174 void* pos = static_cast<byte*>(view_.storage.pos)
176 - EXTENT_SIZ;
177 return static_cast<Extent*> (pos);
178 }
179
180 void
182 {
183 if (empty()) return;
184 // relocate the pos-pointer to the start of the block
186 view_.storage.rest = 0;
187 }
188
189 void
196 };
197
198
199
200
201
208 : storage_{}
209 {
210 TRACE (memory, "new AllocationCluster");
211 }
212
213
221 try
222 {
223 TRACE (memory, "shutting down AllocationCluster");
225 }
226 ERROR_LOG_AND_IGNORE (progress, "discarding AllocationCluster")
227
228
229
231
232
233
240 void
242 {
243 ENSURE (allocRequest <= max_size());
245 }
246
247
248 void
253
254
255
262 void
263 AllocationCluster::__enforce_limits (size_t allocSiz, size_t align)
264 {
265 REQUIRE (allocSiz);
266 REQUIRE (align);
267 REQUIRE (isPow2 (align));
268
269 if (allocSiz > max_size())
270 throw err::Fatal{_Fmt{"AllocationCluster: desired allocation of %d bytes "
271 "exceeds the fixed extent size of %d"} % allocSiz % max_size()
272 ,LERR_(CAPACITY)};
273
274 if (align > max_size())
275 throw err::Fatal{_Fmt{"AllocationCluster: data requires alignment at %d bytes, "
276 "which is beyond the fixed extent size of %d"} % align % max_size()
277 ,LERR_(CAPACITY)};
278 }
279
280
281
282 /* === diagnostics helpers === */
283
284 size_t
286 {
287 return StorageManager::access (unConst(*this)).determineExtentCnt();
288 }
289
295 size_t
297 {
298 size_t extents = numExtents();
299 if (not extents) return 0;
300 size_t bytes = StorageManager::access (unConst(*this)).calcAllocInCurrentBlock();
301 return (extents - 1) * max_size() + bytes;
302 }
303
304
305} // namespace lib
Memory management for the low-level model (render nodes network).
An overlay view for the AllocationCluster to add functionality for adding / clearing extents and regi...
lib::LinkedElements< Destructor, PolicyInvokeDtor > Destructors
static StorageManager & access(AllocationCluster &clu)
A pile of objects sharing common allocation and lifecycle.
~AllocationCluster() noexcept
The shutdown of an AllocationCluster walks all extents and invokes all registered deleter functions a...
void expandStorage(size_t)
Expand the alloted storage pool by a block, suitable to accommodate at least the indicated request.
void __enforce_limits(size_t, size_t)
Allocation cluster uses a comparatively small tile size for its extents, which turns out to be a freq...
static constexpr size_t EXTENT_SIZ
hard wired size of storage extents
AllocationCluster()
Prepare a new clustered allocation to be expanded by extents of size EXTENT_SIZ, yet discarded all at...
void registerDestructor(Destructor &)
static constexpr size_t max_size()
Maximum individual allocation size that can be handled.
TY & push(TY &elm) noexcept
accept the given element and prepend it to the list of elements; depending on the allocation policy,...
TY & emplace(ARGS &&...args)
prepend object of type TY, forwarding ctor args
Derived specific exceptions within Lumiera's exception hierarchy.
Definition error.hpp:193
Any copy and copy construction prohibited.
Definition nocopy.hpp:38
A front-end for using printf-style formatting.
#define ERROR_LOG_AND_IGNORE(_FLAG_, _OP_DESCR_)
convenience shortcut for a sequence of catch blocks just logging and consuming an error.
Definition error.hpp:267
#define LERR_(_NAME_)
Definition error.hpp:45
Front-end for printf-style string template interpolation.
Intrusive single linked list with optional ownership.
Implementation namespace for support and library code.
auto & asLinkedElements(N *const &anchor)
transiently reinterpret an element pointer as const LinkedElements, allowing to count,...
constexpr bool isPow2(N n)
OBJ * unConst(const OBJ *)
shortcut to save some typing when having to define const and non-const variants of member functions
Definition util.hpp:358
bool isnil(lib::time::Duration const &dur)
void dispose(X *elm)
while this policy doesn't take ownership, it ensures the destructor is invoked
Policy for LinkedElements: never create or destroy any elements, only allow to add already existing n...
Utilities for quantisation (grid alignment) and comparisons.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...