ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
poolallocator.inl
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_monomem of the \aliblong.
4///
5/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8ALIB_EXPORT namespace alib { namespace monomem {
9
10#if !defined(ALIB_MONOMEM_POOLALLOCATOR_DEFAULT_ALIGNMENT)
11# define ALIB_MONOMEM_POOLALLOCATOR_DEFAULT_ALIGNMENT alignof(uint64_t)
12#endif
13
14//==================================================================================================
15/// \par Important Note
16/// Please consult the \ref alib_contmono_intro "Programmer's Manual" of \alib module
17/// \alib_monomem_nl for an introduction into the rather complex topic of monotonous and
18/// pool allocation and how to use this class.
19///
20/// This class implements the interface prototyped with \alib{lang;Allocator}.
21/// Whenever an object is freed with this allocator, the memory is stored in a stack for later
22/// re-use. This means, with allocations, first it is checked if a previously freed object of
23/// fitting size is available, and only if not, new memory is allocated.
24/// To implement this in a performant way (preferably with compile-time calculations), the following
25/// approach was taken:
26/// - The size of every allocation request is increased to the next higher power of 2 bound.
27/// For example, if a memory piece of 42 bytes is requested, a piece of size 64 bytes is returned.
28/// - For each allocation size, a simple stack (single directed linked list) is used to dispose and
29/// recycle memory.
30/// - The minimum allocation size is <c>sizeof(void*)</c>, because for the recycling mechanism
31/// a pointer needs to be stored in the freed pool memory, when it is added to the internal
32/// "recycling stack".
33/// - This results in only 61 different allocation sizes (on a 64-bit machine).
34/// - A fixed alignment for all objects is used. This is also the maximum alignment allowed to pass
35/// to methods #allocate and #reallocate. Its value is defined by template parameter
36/// \p{TAlignment}, which defaults to what is given with the compiler-symbol
37/// \ref ALIB_MONOMEM_POOLALLOCATOR_DEFAULT_ALIGNMENT, which in turn defaults to
38/// <c>alignof(uint64_t)</c>.
39/// - This approach results in only 61 different allocation sizes (on a 64-bit machine).
40///
41/// The consequences of this strategy are straight forward:
42/// - Using this allocator type requires disposing (free) every allocated piece of memory (which is
43/// in contrast to \b MonoAllocator).
44/// - This type is well suited for allocation scenarios, which release each object within
45/// a certain period of time, just to allocate new ones shortly afterward. A good use
46/// case example is given with module \alib_threadmodel: Here, request objects are
47/// pushed into priority queues, which are disposed after the request got processed. The objects
48/// are rather small and of different sizes. In complex server scenarios, it can become quickly
49/// millions of messages per second which are created and disposed.
50/// - A statistical average of 25% memory allocation overhead (waste) is taken into account with
51/// the use of this class.
52///
53/// Chapter \ref alib_contmono_intro_recycling of the joint Programmer's Manual of modules
54/// \alib_containers_nl and \alib_monomem_nl provides an in-depth discussion of what is called
55/// "recycling" in this context. Several strategies are proposed with container types provided by
56/// module \alib_containers_nl. From this perspective, this allocator could be seen as a
57/// "recycling proxy" in front of a \b MonoAllocator (or a different,
58/// \ref alib_contmono_chaining "chained" allocator).
59///
60/// @see
61/// - The \ref alib_contmono_intro "Programmer's Manual" of module \alib_monomem_nl.
62/// - The "standard" type definition of this template type \alib{MonoAllocator},
63/// which uses an \alib{lang;HeapAllocator} as the
64/// \ref alib_contmono_chaining "chained allocator".
65///
66/// @tparam TAllocator The underlying allocator to use.<br>
67/// With type definition \alib{PoolAllocator},this is bound to type
68/// \alib{MonoAllocator}.<br>
69/// With type definition \alib{PoolAllocatorHA},this is bound to type
70/// \alib{lang;HeapAllocator}.<br>
71/// For general information see chapter \ref alib_contmono_chaining
72/// of the Programmer's Manual.
73/// @tparam TAlignment The fixed alignment to use. Corresponding method parameters are ignored.<br>
74/// Defaults to the compiler-symbol
75/// \ref ALIB_MONOMEM_POOLALLOCATOR_DEFAULT_ALIGNMENT, which in turn defaults
76/// to <c>alignof(uint64_t)</c>.<br>
77/// It is statically asserted that this value is not higher than
78/// field \alib{lang::Allocator;MAX_ALIGNMENT} of the given chained
79/// \p{TAllocator} and not smaller than <c>alignof(void*)</c>.<br>
80/// See Chapter \ref alib_contmono_further_alignment of the Programmer's Manual
81/// of this module.
82//==================================================================================================
83template<typename TAllocator, size_t TAlignment= ALIB_MONOMEM_POOLALLOCATOR_DEFAULT_ALIGNMENT>
84class TPoolAllocator : public lang::AllocatorMember<TAllocator>
85#if ALIB_DEBUG_CRITICAL_SECTIONS
87#endif
88{
89 static_assert( TAlignment >= alignof(void*),
90 "The (fixed) alignment of the pool allocator has to be at least as high as alignof(void*). "
91 "Adjust template parameter TAlignment." );
92
93 static_assert( TAlignment <= TAllocator::MAX_ALIGNMENT,
94 "The (fixed) alignment of the pool allocator cannot be greater than the MAX_ALIGNMENT of "
95 "its chained allocator. Adjust template parameter TAlignment." );
96
97 #if !defined(_WIN32) // not a constexpr under windows
98 static_assert(lang::BitCount(TAlignment) == 1,
99 "The fixed alignment of the pool allocator is not a power of 2. "
100 "Adjust template parameter TAlignment." );
101 #endif
102
103 /// A magic byte, used with the compiler-symbol \ref ALIB_DEBUG_ALLOCATIONS to mark
104 /// memory and detect out-of-bounds writes.
105 /// @see Method \alib{lang;Allocator::dbgCheckMemory}.
106 static constexpr unsigned char MAGIC= 0xA3;
107
108 /// A magic byte written when memory is freed.
109 /// @see Field #CLEAR.
110 static constexpr unsigned char CLEAR= 0xF3;
111
112 protected:
113
114 using allocMember= lang::AllocatorMember<TAllocator>; ///< A shortcut to a base type.
115
116 // ========================================= Fields ========================================
117 /// Array of hooks. Each hook points to previously disposed memory of the same size.
118 /// Its length is determined with \c constexpr #qtyHooks and it is allocated with construction
119 /// in \p{allocator}.
120 void** hooks = nullptr;
121
122 #if ALIB_DEBUG
123 public:
124 /// A name for this object.
125 /// The constructors grab this name from the chained allocator, which most often is an
126 /// already named \b MonoAllocator. Thus, no constructor argument is available
127 /// (in contrast to class \alib{monomem;TMonoAllocator;MonoAllocator}).
128 /// This name may be changed after construction by the using code as appropriate.
129 const char* DbgName;
130 protected:
131 #endif
132
133 #if ALIB_DEBUG_MEMORY
134 /// The overall number of allocations for each size.
136 #endif
137
138 #if ALIB_DEBUG_ALLOCATIONS
139 /// The current number of allocations that have not been freed.
140 int* dbgOpenAllocations = nullptr;
141
142 /// This member is used with \ref ALIB_DEBUG_ALLOCATIONS to pass the requested size from
143 /// interface methods to the implementation. While this approach is not thread-safe, it
144 /// avoids adding some method parameter, which would exist only in debug versions.
145 /// It was intentionally implemented like this, to cause testing errors in case that
146 /// multithreaded access was not locked against racing conditions properly by the user.
148 #endif
149
150 // ==================================== Internal Methods ===================================
151 /// To be able to store allocated memory in the recycling stacks, any allocated memory is at
152 /// least of size <c>sizeof(void*)</c>. Hence sizes \c 1 and \c 2 (with 64-bit systems
153 /// also \c 4) will never be allocated and no hook is available for these sizes.
154 /// @return \c 3 on 64-bit systems, \c 2 on 32-bit systems.
155 static constexpr short minimumHookIndex() { return sizeof(size_t) == 4 ? 2 : 3; }
156
157
158 /// The number of hooks needed. Evaluates to \c 61 on a common 64-bit platform and \c 29 on a
159 /// @return \c 61 on 64-bit systems, \c 29 on 32-bit systems.
160 static constexpr short qtyHooks() { return short(bitsof(size_t)) - minimumHookIndex(); }
161
162 /// Calculates the index of the hook in field #hooks. This corresponds to the number
163 /// of the most significant bit in the next higher power of 2 value minus #minimumHookIndex.
164 /// @param requestedObjectSize The object size requested by the user.
165 /// @return The index of the recycler hook in #hooks.
166 static constexpr
167 short hookIndex(size_t requestedObjectSize)
168 {
169 if( requestedObjectSize < sizeof(void*) )
170 return 0;
171 int msb= lang::MSB(requestedObjectSize);
172 return short( ((requestedObjectSize & lang::LowerMask<size_t>(msb-1) ) == 0 ? msb -1: msb )
173 - minimumHookIndex() );
174 }
175
176 /// Templated version of #hookIndex(size_t).
177 /// @tparam TRequestedObjectSize The object size requested by the user, hence excluding the
178 /// internal pointer.
179 /// @return The index of the recycler hook in #hooks.
180 template<size_t TRequestedObjectSize>
181 static constexpr
182 short hookIndex()
183 {
184 if( TRequestedObjectSize < sizeof(void*) )
185 return 0;
186 constexpr int msb = lang::MSB(TRequestedObjectSize);
187 return short( ((TRequestedObjectSize & lang::LowerMask<msb-1, size_t>() ) == 0 ? msb-1 : msb)
188 - minimumHookIndex() );
189 }
190
191 /// Frees all recycled pool objects.
193
194 public:
195 /// The type of the allocator that this allocator uses underneath to allocate the buffers,
196 /// given with template parameter \p{TAllocator}.<br>
197 /// The instance can be accessed with inherited methods
198 /// \alib{lang::AllocatorMember;GetAllocator} and \alib{lang::AllocatorMember;AI}.
199 using ChainedAllocator = TAllocator;
200
201 /// Evaluates to the value of template parameter \p{TAlignment}.
202 /// @see Field \alib{lang;Allocator::MIN_ALIGNMENT}.
203 static constexpr size_t MIN_ALIGNMENT = TAlignment;
204
205 /// Evaluates to the value of template parameter \p{TAlignment}.
206 /// @see Field \alib{lang;Allocator::MAX_ALIGNMENT}.
207 static constexpr size_t MAX_ALIGNMENT = TAlignment;
208
209 // ===================================== Construction =====================================
210 /// Constructs this type.
211 /// @param pAllocator The allocator to use for allocating pool objects.
213 TPoolAllocator ( TAllocator& pAllocator );
214
215 /// Constructs this type without a given allocator. This constructor is applicable only
216 /// if \p{TAllocator} is default-constructible (e.g., \alib{lang;HeapAllocator}).
217 /// @tparam TRequires Defaulted template parameter. Must not be specified.
218 template<typename TRequires= allocMember>
219 requires std::default_initializable<TRequires>
221 #if ALIB_DEBUG_CRITICAL_SECTIONS
222 :lang::DbgCriticalSections("PoolAllocator")
223 #endif
224 {
225 #if defined(_WIN32) // otherwise statically asserted in header
226 ALIB_ASSERT_ERROR(lang::BitCount(TAlignment) == 1, "MONOMEM",
227 "The fixed alignment {} of the pool allocator is not a power of 2. "
228 "Adjust template parameter TAlignment.", TAlignment )
229 #endif
230
232
233 // allocate and initialize hook array
234 hooks= allocMember::AI().template AllocArray<void*>(qtyHooks() );
235 std::memset( hooks, 0, sizeof( void*[qtyHooks()] ) );
236 #if ALIB_DEBUG_ALLOCATIONS
237 dbgOpenAllocations= allocMember::AI().template AllocArray<int>(qtyHooks() );
238 std::memset( dbgOpenAllocations, 0, sizeof( int[qtyHooks()] ) );
239 #endif
240 #if ALIB_DEBUG_MEMORY
241 dbgStatAllocCounter= allocMember::AI().template AllocArray<uinteger>(qtyHooks() );
242 std::memset( dbgStatAllocCounter, 0, sizeof( uinteger[qtyHooks()] ) );
243 #endif
244 }
245
246 /// Destructs this type.
249
250 // #############################################################################################
251 /// @name lang::Allocator Implementation
252 // #############################################################################################
253 /// Allocates or re-uses a previously freed piece of memory of equal \p{size}.
254 /// Any given \p{size} is rounded up to the next higher power of 2 before comparison and
255 /// returned via in/output parameter \p{size}.
256 /// @param[in,out] size The size of memory the block to allocate in bytes. This will be rounded up
257 /// to the next higher power of 2 when the function returns.
258 /// Any additional size might be used by the caller.
259 /// @param pAlignment The (minimum) alignment of the memory block to allocate in bytes.
260 /// This is ignored with this allocator. Instead, it uses what is specified
261 /// by template parameter \p{TAlignment}.
262 /// See Chapter \ref alib_contmono_further_alignment of the Programmer's
263 /// Manual of this module.
264 /// @return Pointer to the allocated memory.
265 void* allocate( size_t& size, size_t pAlignment )
266 {
267 ALIB_ASSERT_ERROR(pAlignment <= TAlignment, "MONOMEM",
268 "The requested alignment is higher than what was specified with "
269 "template parameter TAlignment: {} >= {}", pAlignment, TAlignment )
270 (void) pAlignment;
271
272 #if ALIB_DEBUG_ALLOCATIONS
274 #endif
275
277 }
278
279 /// Shrinks or grows a piece of memory. If a new allocation was performed the existing
280 /// data is copied. Any given \p{oldSize} and \p{newSize} is rounded up to the next higher
281 /// power of 2 before comparison. Note, that parameter \p{newSize} is provided as a reference.
282 /// @param mem The memory to reallocate.
283 /// @param oldSize The current size of \p{mem}.
284 /// @param[in,out] newSize The size of memory the block to allocate in bytes. This will be rounded
285 /// up to the next higher power of 2 when the function returns. Any
286 /// additional size might be used by the caller.
287 /// @param pAlignment The (minimum) alignment of the memory to allocate in bytes.
288 /// This is ignored with this allocator. Instead, it uses what is
289 /// specified by template parameter \p{TAlignment}.
290 /// See Chapter \ref alib_contmono_further_alignment of the Programmer's
291 /// Manual of this module.
292 /// @return Pointer to the re-allocated memory.
293 void* reallocate( void* mem, size_t oldSize, size_t& newSize, size_t pAlignment );
294
295 /// Disposes the given memory. The fragment is stored for later reuse with method #allocate
296 /// of memory sizes of the same power of 2 range.
297 ///
298 /// @param mem The memory to dispose.
299 /// @param size The size of the given \p{mem}.
300 void free(void* mem, size_t size)
301 {
302 #if ALIB_DEBUG_ALLOCATIONS
304 #endif
305 FreeByAllocationInfo( hookIndex(size), mem );
306 }
307
308 /// For an explanation, see \alib{lang;Allocator::dbgAcknowledgeIncreasedAllocSize}.
309 /// @tparam TSize The type of parameter \p{allocSize}. (Deduced by the compiler.)
310 /// @param mem The address of the allocated object.
311 /// @param allocSize The true allocation size returned by the method #allocate .
312 template<typename TSize>
313 void dbgAcknowledgeIncreasedAllocSize( void* mem, TSize allocSize ) const
314 { lang::DbgAlloc::annotate(mem, allocSize, MAGIC); }
315
316 #if DOXYGEN
317 /// See the description of this method with prototype \alib{lang;Allocator::allowsMemSplit}.<br>
318 /// (Note: This method is static. For technical reasons this cannot be reflected in this
319 /// documentation)
320 /// @return \c false.
321 constexpr bool allowsMemSplit() noexcept;
322 #else
323 static constexpr bool allowsMemSplit() noexcept { return false; }
324 #endif
325
326 /// Returns a temporary object (which is usually optimized out together with a call to this
327 /// operator) providing high-level convenience methods for allocation.
328 /// @see Class \alib{lang::AllocatorInterface}
329 /// @return A temporary high-level interface into the allocator.
332
333 // #############################################################################################
334 /// @name Specific Interface (Static Methods)
335 // #############################################################################################
336 /// Returns the number of relevant bits of the allocation information value returned by
337 /// overloaded methods #GetAllocInformation. In other words, the value returned by these
338 /// methods is between \c 0 and the power of 2 of the value returned by this method.
339 /// @return \c 5 on 32-bit systems and \c 6 on 64 bit systems.
340 /// #GetAllocInformation.
341 static constexpr
342 int AllocationInformationBitCount() { return bitsof(void*) == 32 ? 5 : 6; }
343
344 /// This static \c constexpr method returns information that this allocator needs for allocation
345 /// and freeing of objects. In the case that the original allocation type is not known on
346 /// deletion (e.g., if virtual destructors are used), then this piece of information has to be
347 /// collected with this function (probably on construction) and provided to
348 /// #FreeByAllocationInfo via custom mechanics.
349 ///
350 /// \note
351 /// Two options are quite obvious to implement:
352 /// 1. The information is stored within the object and passed on destruction.
353 /// 2. The information is retrieved from a virtual function, which is implemented using this
354 /// \c constexpr type.
355 /// \note
356 /// While the second version has a small impact on code size and execution speed
357 /// (because the virtual function has to be called with deletion), the first version
358 /// increases the footprint of the object. So both approaches have their advantages and
359 /// disadvantages.<br><br>
360 /// \note
361 /// A third option is explained in a step-by-step sample in chapter
362 /// \ref alib_contmono_poolallocator_metatrick of the Programmer's Manual of this module.
363 ///
364 /// Technically, the returned value is the exponent base 2 of the next higher power of 2
365 /// value, minus the minimum supported exponent. This directly gives an index into field
366 /// #hooks.
367 /// @tparam T The object type that allocation information is to be retrieved for.
368 /// @return Allocation information.
369 template<typename T>
370 static constexpr short GetAllocInformation() { return hookIndex<sizeof(T)>(); }
371
372 /// Same as the templated #GetAllocInformation<T>() version, but accepts method parameter
373 /// \p{size} instead of a template parameter.
374 /// Thus, this version is only potentially \c constexpr.
375 ///
376 /// @tparam TIntegral The type that parameter \p{size} is provided with. If not integral,
377 /// this method is not chosen by the compiler.
378 /// @param size The size of the object to be allocated or disposed in a probalble next step.
379 /// @return Allocation information. See #GetAllocInformation<T>().
380 template<typename TIntegral>
381 requires std::integral<TIntegral>
382 static constexpr short GetAllocInformation(TIntegral size) { return hookIndex(size_t(size)); }
383
384 /// Returns the allocation size for a value returned by #GetAllocInformation.
385 ///
386 /// @param allocInfo The alloc information received with #GetAllocInformation.
387 /// @return The next higher power of 2 in respect to the size passed as parameter to
388 /// #GetAllocInformation.
389 static constexpr size_t GetAllocationSize(short allocInfo)
390 { return size_t(1)<<(allocInfo + minimumHookIndex()); }
391
392 // #############################################################################################
393 /// @name Specific Interface
394 // #############################################################################################
395 /// Allocates or recycles previously freed memory suitable to emplace an instance with the
396 /// given allocation information.
397 /// \note This method is to be used in combination with template method #GetAllocInformation
398 /// in situations, where the type information of the allocation is not available
399 /// or has to be transferred to a non-templated library function or similar.
400 /// @param allocInfo The allocation information received with #GetAllocInformation.
401 /// @return A pointer to the allocated memory.
403 void* AllocateByAllocationInfo(int allocInfo);
404
405
406 /// Disposes an object (or piece of memory) which has been allocated using
407 /// #AllocateByAllocationInfo.
408 /// If the compiler-symbol \ref ALIB_DEBUG_ALLOCATIONS is set, the method will overwrite the freed
409 /// memory with character <c>0xD3</c>.
410 /// @param allocInfo The allocation information received with #GetAllocInformation.
411 /// @param mem The object to dispose.
412 void FreeByAllocationInfo(int allocInfo, void* mem )
413 {ALIB_DCS
414 #if ALIB_DEBUG_ALLOCATIONS
415 // if not set, then this method had been called directly from outside and we expect
416 // that the hook index is stored instead of the true requested size.
417 if( dbgLastRequestedSize == 0 )
418 dbgLastRequestedSize= (size_t(1) << (allocInfo + minimumHookIndex()));
421 lang::DbgAlloc::clearMem( mem, size_t(1) << (allocInfo + minimumHookIndex()), MAGIC );
422 --dbgOpenAllocations[allocInfo];
423 #endif
424
425 *reinterpret_cast<void**>(mem)= hooks[allocInfo];
426 hooks[allocInfo]= mem;
427 }
428
429 /// Deletes all current pool objects with the #ChainedAllocator.
430 /// The state of this class equals the state after construction.
431 void Reset()
432 {
433 deletePool();
434 std::memset( hooks, 0, sizeof( void*[qtyHooks()] ) );
435 #if ALIB_DEBUG_ALLOCATIONS
436 std::memset( dbgOpenAllocations, 0, sizeof( int[qtyHooks()] ) );
437 #endif
438 #if ALIB_DEBUG_MEMORY
439 std::memset( dbgStatAllocCounter, 0, sizeof( uinteger[qtyHooks()] ) );
440 #endif
441
442 }
443
444 /// Returns the number of available pool objects, hence those that had been allocated,
445 /// freed, and not been reused with a next allocation again.
446 /// @param size The size of the object requested, as given with #allocate and #free.
447 /// @return The number of pool objects of the given size.
449 integer GetPoolSize(size_t size);
450
451 /// If the compiler-symbol \ref ALIB_DEBUG_ALLOCATIONS is not set, this method is empty and will
452 /// be optimized out. Otherwise, this will raise an \alib assertion if the piece of allocated
453 /// memory is corrupted or its allocation size is not rightfully given by the using code.
454 /// @see Chapter \ref alib_contmono_further_debug of the Programmer's Manual.
455 ///
456 /// @tparam TSize The type of parameter \p{size}. (Deduced by the compiler.)
457 /// @param mem The address of the allocated object.
458 /// @param size The requested allocation size of the object.
459 template<typename TSize>
460 void dbgCheckMemory( void* mem, TSize size )
461 { lang::DbgAlloc::checkMem( mem, size, MAGIC, ALIB_REL_DBG(nullptr, DbgName)); }
462
463 #if ALIB_DEBUG_ALLOCATIONS
464 /// Returns the number of objects of the given \p{size} currently allocated (and not freed).<br>
465 /// Only functional if the compiler-symbol \ref ALIB_DEBUG_ALLOCATIONS is set.
466 /// Otherwise, this is a <c>static constexpr</c> function that returns \c 0.
467 /// @see Overloaded method #DbgCountedOpenAllocations() which returns the overall number.
468 /// @param size The size of the object requested, as given with #allocate and #free.
469 /// @return The number of non-freed allocations.
471 {
472 return dbgOpenAllocations[hookIndex(size)];
473 }
474
475 /// Returns the number of objects currently allocated (and not freed).<br>
476 /// Only functional if the compiler-symbol \ref ALIB_DEBUG_ALLOCATIONS is set.
477 /// Otherwise, this is a <c>static constexpr</c> function that returns \c 0.
478 /// @return The number of non-freed allocations.
480 {
481 int result= 0;
482 for(int i= 0; i < qtyHooks(); ++i)
483 result+= dbgOpenAllocations[i];
484 return result;
485 }
486
487 /// Actively suppresses a warning on destruction in case #DbgCountedOpenAllocations does not
488 /// return \c 0.<br>
489 /// Only functional if the compiler-symbol \ref ALIB_DEBUG_ALLOCATIONS is set.
490 /// Otherwise, this is a <c>static constexpr</c> function that returns \c 0.
491 /// @return The number of non-freed allocations.
493 {
494 int result= DbgCountedOpenAllocations();
495 std::memset( dbgOpenAllocations, 0, sizeof( int[qtyHooks()] ) );
496 return result;
497 }
498
499 #else
500 static constexpr int DbgCountedOpenAllocations(size_t ) { return 0; }
501 static constexpr int DbgCountedOpenAllocations() { return 0; }
502 static constexpr int DbgSuppressNonFreedObjectsWarning() { return 0; }
503 #endif
504
505 #if ALIB_DEBUG_MEMORY
506 /// Returns the overall number of allocated (and potentially freed) objects of the given
507 /// \p{size}.<br>
508 /// Only functional if the compiler-symbol \ref ALIB_DEBUG_MEMORY is set.
509 /// Otherwise, this is a <c>static constexpr</c> function that returns \c 0.
510 /// @see Overloaded method #DbgStatAllocCounter() which returns the overall number.
511 /// @param size The size of the object requested, as given with #allocate and #free.
512 /// @return The number of non-freed allocations.
514 {
515 return dbgStatAllocCounter[hookIndex(size)];
516 }
517
518 /// Returns the overall number of objects currently allocated (and not freed).<br>
519 /// Only functional if the compiler-symbol \ref ALIB_DEBUG_MEMORY is set.
520 /// Otherwise, this is a <c>static constexpr</c> function that returns \c 0.
521 /// @return The number of non-freed allocations.
523 {
524 uinteger result= 0;
525 for(int i= 0; i < qtyHooks(); ++i)
526 result+= dbgStatAllocCounter[i];
527 return result;
528 }
529
530 #else
531 static constexpr uinteger DbgStatAllocCounter(size_t) { return 0; }
532 static constexpr uinteger DbgStatAllocCounter() { return 0; }
533 #endif
534}; // class TPoolAllocator
535
536
537#if !DOXYGEN
540#endif
541
542} // namespace alib[::monomem]
543
544/// Type alias in namespace \b alib.
545/// This alias fixes template parameter \p{TAllocator} (which defines the
546/// \ref alib_contmono_chaining "chained allocator") to type alias #alib::MonoAllocator, which
547/// in turn defines its chained allocator to type \alib{lang;HeapAllocator}.
549
550/// Type alias in namespace \b alib.
551/// This alias fixes template parameter \p{TAllocator} (which defines the
552/// \ref alib_contmono_chaining "chained allocator") to type \alib{lang;HeapAllocator}.
554
555/// Type alias in namespace \b alib to denote the use of a
556/// \alib{PoolAllocator} with type \alib{lang::StdContainerAllocator}.
557template<typename T>
559
560} // namespace [alib]
561
562
void FreeByAllocationInfo(int allocInfo, void *mem)
static constexpr short qtyHooks()
uinteger DbgStatAllocCounter(size_t size)
void dbgAcknowledgeIncreasedAllocSize(void *mem, TSize allocSize) const
void dbgCheckMemory(void *mem, TSize size)
static constexpr size_t GetAllocationSize(short allocInfo)
void deletePool()
Frees all recycled pool objects.
static constexpr short hookIndex()
static constexpr int AllocationInformationBitCount()
int DbgCountedOpenAllocations(size_t size)
void * allocate(size_t &size, size_t pAlignment)
lang::AllocatorMember< TAllocator > allocMember
A shortcut to a base type.
constexpr bool allowsMemSplit() noexcept
static constexpr short hookIndex(size_t requestedObjectSize)
static constexpr short GetAllocInformation(TIntegral size)
ALIB_DLL TPoolAllocator(TAllocator &pAllocator)
void * reallocate(void *mem, size_t oldSize, size_t &newSize, size_t pAlignment)
void free(void *mem, size_t size)
ALIB_DLL void * AllocateByAllocationInfo(int allocInfo)
lang::AllocatorInterface< TPoolAllocator > operator()()
static constexpr short minimumHookIndex()
ALIB_DLL integer GetPoolSize(size_t size)
ALIB_DLL ~TPoolAllocator()
Destructs this type.
static constexpr short GetAllocInformation()
#define bitsof(type)
Definition alib.inl:1418
#define ALIB_DLL
Definition alib.inl:496
#define ALIB_DCS
Definition alib.inl:1375
#define ALIB_EXPORT
Definition alib.inl:488
#define ALIB_DBG(...)
Definition alib.inl:836
#define ALIB_ASSERT_ERROR(cond, domain,...)
Definition alib.inl:1049
#define ALIB_REL_DBG(releaseCode,...)
Definition alib.inl:838
constexpr int MSB(TIntegral value)
Definition bits.inl:325
constexpr TIntegral LowerMask()
Definition bits.inl:53
constexpr int BitCount(TIntegral value)
Definition bits.inl:222
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
monomem::TPoolAllocator< MonoAllocator > PoolAllocator
lang::StdContainerAllocator< T, PoolAllocator > SCAPool
monomem::TPoolAllocator< lang::HeapAllocator > PoolAllocatorHA
lang::uinteger uinteger
Type alias in namespace alib.
Definition integers.inl:152
AllocatorInterface< TAllocator > AI() const noexcept
MonoAllocator & GetAllocator() const noexcept
static constexpr void clearMem(T *mem, size_t size, unsigned char magic)
static constexpr void annotate(T *mem, size_t size, unsigned char magic)
static void checkMem(void *mem, const TSize size, unsigned char magic, const char *name)