ALib C++ Library
Library Version: 2412 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
poolallocator.t.hpp
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This implementation file is part of module \alib_monomem of the \aliblong.
4/// It may be used to instantiate custom versions of \alib{monomem;TPoolAllocator}, working with
5/// different alignments or a different \ref alib_contmono_chaining "chained" allocator.
6///
7/// @see Manual section \ref alib_manual_appendix_t_hpp_files about the nature of ".t.hpp"-files.
8///
9/// \emoji :copyright: 2013-2024 A-Worx GmbH, Germany.
10/// Published under \ref mainpage_license "Boost Software License".
11//==================================================================================================
12#include "alib/lang/owner.hpp"
14
15#if !DOXYGEN
16
17namespace alib::monomem {
18
19// ============================= Construction/Destruction/Deletion =============================
20template<typename TAllocator, size_t TAlignment>
22: allocMember(pAllocator)
24,lang::DbgCriticalSections("PoolAllocator")
25#endif
26ALIB_DBG(,DbgName(pAllocator.DbgName))
27{
28 #if ALIB_CPP_STANDARD < 20 && defined(_WIN32) // otherwise statically asserted in header
29 ALIB_ASSERT_ERROR(lang::BitCount(TAlignment) == 1, "MONOMEM",
30 "The fixed alignment of the pool allocator is not a power of 2. "
31 "Adjust template parameter TAlignment." )
32 #endif
33
34 // allocate and initialize hook array
35 hooks= allocMember::AI().template AllocArray<void*>(qtyHooks() );
36 std::memset( hooks, 0, sizeof( void*[qtyHooks()] ) );
37 #if ALIB_DEBUG_ALLOCATIONS
38 dbgOpenAllocations= allocMember::AI().template AllocArray<int>(qtyHooks() );
39 std::memset( dbgOpenAllocations, 0, sizeof( int[qtyHooks()] ) );
40 #endif
41 #if ALIB_DEBUG_MONOMEM
42 dbgStatAllocCounter= allocMember::AI().template AllocArray<uinteger>(qtyHooks() );
43 std::memset( dbgStatAllocCounter, 0, sizeof( uinteger[qtyHooks()] ) );
44 #endif
45}
46
47template<typename TAllocator, size_t TAlignment>
48TPoolAllocator<TAllocator,TAlignment>::~TPoolAllocator ()
49{
50 if ( hooks == nullptr )
51 return;
52
53 deletePool();
54 allocMember::AI().template FreeArray<void*>(hooks, qtyHooks());
55 ALIB_DBG( hooks= nullptr; )
56
59 for (short i = 0; i < qtyHooks(); ++i)
60 {
61 if ( dbgOpenAllocations[i] > 0)
62 ALIB_WARNING( "MONOMEM", NString256() <<
63 "PoolAllocator '"<<DbgName<<"' destructor: There are still "
64 << dbgOpenAllocations[i] << " objects of size "
65 << GetAllocationSize(i) << " not freed. "
66 "This indicates a potential memory leak." )
67 }
68 allocMember::AI().template FreeArray<int>(dbgOpenAllocations, qtyHooks() );
70 #endif
71 #if ALIB_DEBUG_MONOMEM
72 allocMember::AI().template DeleteArray<uinteger>(dbgStatAllocCounter, qtyHooks() );
73 #endif
74
75}
76
77
78template<typename TAllocator, size_t TAlignment>
79void TPoolAllocator<TAllocator,TAlignment>::deletePool()
80{
81 for (int idx = 0; idx < qtyHooks(); ++idx)
82 {
83 size_t allocSize= lang::DbgAlloc::extSize( size_t(1) << (idx + minimumHookIndex()) );
85 void* elem= hooks[idx];
86 while( elem )
87 {
88 void* next= *reinterpret_cast<void**>( elem );
89 allocMember::GetAllocator().free( elem, allocSize );
90 elem= next;
91 }
93 }
94}
95
96
97// ======================================= Allocation ========================================
98template<typename TAllocator, size_t TAlignment>
99void* TPoolAllocator<TAllocator,TAlignment>::reallocate( void* mem, size_t oldSize, size_t& newSize, size_t pAlignment )
100{
101 short oldSizeIdx;
102 short newSizeIdx;
103
104 {ALIB_DCS
105
106 ALIB_ASSERT_ERROR(pAlignment <= TAlignment, "MONOMEM",
107 "The requested alignment is higher than what was specified with "
108 "template parameter TAlignment." )
109 (void) pAlignment;
110
111 oldSizeIdx= hookIndex(oldSize);
112 newSizeIdx= hookIndex(newSize);
113 if( newSizeIdx == oldSizeIdx )
114 return mem;
115
116 newSize= GetAllocationSize(newSizeIdx);
117 }
118
119 auto newMem= AllocateByAllocationInfo( newSizeIdx );
120 std::memcpy( newMem, mem, oldSize );
121 #if ALIB_DEBUG_ALLOCATIONS
122 dbgLastRequestedSize= oldSize;
123 #endif
124 FreeByAllocationInfo( oldSizeIdx, mem );
125 return newMem;
126}
127
128template<typename TAllocator, size_t TAlignment>
129void* TPoolAllocator<TAllocator,TAlignment>::AllocateByAllocationInfo(int allocInfo)
131 #if ALIB_DEBUG_ALLOCATIONS
132 // if not set, then this method had been called directly from outside and we store
133 // the hook index instead of the true requested size.
134 if( dbgLastRequestedSize == 0 )
135 dbgLastRequestedSize= size_t(allocInfo);
136 #endif
137
139 #if ALIB_DEBUG_ALLOCATIONS
140 ++dbgOpenAllocations[allocInfo];
141 #endif
142 #if ALIB_DEBUG_MONOMEM
143 ++dbgStatAllocCounter[allocInfo];
144 #endif
145
146
147 void** hook= &hooks[allocInfo];
149
150 // found a recyclable?
151 if( *hook )
152 {
153 void* mem= *hook;
154 *hook= *reinterpret_cast<void**>(mem);
155
156 #if ALIB_DEBUG_ALLOCATIONS
157 lang::DbgAlloc::annotate( mem, dbgLastRequestedSize, MAGIC );
158 dbgLastRequestedSize= 0;
159 #endif
160 return mem;
161 }
162
163 // create a new object, as no recyclable is available
164 size_t allocSize= lang::DbgAlloc::extSize( size_t(1) << (allocInfo + minimumHookIndex()) );
165 auto* mem= allocMember::AI().Alloc( allocSize, TAlignment );
166
167 #if ALIB_DEBUG_ALLOCATIONS
168 lang::DbgAlloc::annotate( mem, dbgLastRequestedSize, MAGIC );
169 dbgLastRequestedSize= 0;
170 #endif
171
172 return mem;
173}
174
175// ========================================= Other ===========================================
176
177template<typename TAllocator, size_t TAlignment>
178integer TPoolAllocator<TAllocator,TAlignment>::TPoolAllocator::GetPoolSize(size_t size)
179{
180 integer result= 0;
182 void* node= hooks[hookIndex(size)];
184 while( node )
185 {
186 node= *reinterpret_cast<void**>(node);
187 ++result;
188 }
189 return result;
190}
191
192} // namespace [alib::monomem]
193
194#endif // !DOXYGEN
195
#define ALIB_WARNING(...)
Definition alib.hpp:1268
#define ALIB_DCS
#define ALIB_WARNINGS_RESTORE
Definition alib.hpp:849
#define ALIB_ASSERT_ERROR(cond,...)
Definition alib.hpp:1271
#define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE
Definition alib.hpp:760
#define ALIB_DBG(...)
Definition alib.hpp:390
#define ALIB_DEBUG_ALLOCATIONS
Definition prepro.md:40
#define ALIB_DEBUG_CRITICAL_SECTIONS
Definition prepro.md:44
platform_specific integer
Definition integers.hpp:43
NLocalString< 256 > NString256
Type alias name for TLocalString<nchar,256>.