ALib C++ Library
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
poolallocator.t.inl
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_inl_files about the nature of ".t.inl"-files.
8///
9/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
10/// Published under \ref mainpage_license "Boost Software License".
11//==================================================================================================
12#if !DOXYGEN
13
14namespace alib::monomem {
15
16//================================ Construction/Destruction/Deletion ===============================
17template<typename TAllocator, size_t TAlignment>
19: allocMember(pAllocator)
21,lang::DbgCriticalSections("PoolAllocator")
22#endif
23ALIB_DBG(,DbgName(pAllocator.DbgName))
24{
25 #if defined(_WIN32) // otherwise statically asserted in header
26 ALIB_ASSERT_ERROR(lang::BitCount(TAlignment) == 1, "MONOMEM",
27 "The fixed alignment {} of the pool allocator is not a power of 2. "
28 "Adjust template parameter TAlignment.", TAlignment )
29 #endif
30
31 // allocate and initialize hook array
32 hooks= allocMember::AI().template AllocArray<void*>(qtyHooks() );
33 std::memset( hooks, 0, sizeof( void*[qtyHooks()] ) );
34 #if ALIB_DEBUG_ALLOCATIONS
35 dbgOpenAllocations= allocMember::AI().template AllocArray<int>(qtyHooks() );
36 std::memset( dbgOpenAllocations, 0, sizeof( int[qtyHooks()] ) );
37 #endif
38 #if ALIB_DEBUG_MEMORY
39 dbgStatAllocCounter= allocMember::AI().template AllocArray<uinteger>(qtyHooks() );
40 std::memset( dbgStatAllocCounter, 0, sizeof( uinteger[qtyHooks()] ) );
41 #endif
42}
43
44template<typename TAllocator, size_t TAlignment>
45TPoolAllocator<TAllocator,TAlignment>::~TPoolAllocator () {
46 if ( hooks == nullptr )
47 return;
48
49 deletePool();
50 allocMember::AI().template FreeArray<void*>(hooks, qtyHooks());
51 ALIB_DBG( hooks= nullptr; )
52
54 for (short i = 0; i < qtyHooks(); ++i) {
55 if ( dbgOpenAllocations[i] > 0)
56 ALIB_WARNING( "MONOMEM",
57 "PoolAllocator '{}' destructor: There are still {} objects of size {}"
58 " not freed.\n This indicates a potential memory leak.",
59 DbgName, dbgOpenAllocations[i], GetAllocationSize(i) )
60 }
61 allocMember::AI().template FreeArray<int>(dbgOpenAllocations, qtyHooks() );
62 #endif
63 #if ALIB_DEBUG_MEMORY
64 allocMember::AI().template DeleteArray<uinteger>(dbgStatAllocCounter, qtyHooks() );
65 #endif
66
67}
68
69
70template<typename TAllocator, size_t TAlignment>
71void TPoolAllocator<TAllocator,TAlignment>::deletePool() {
72 for (int idx = 0; idx < qtyHooks(); ++idx) {
73 size_t allocSize= lang::DbgAlloc::extSize( size_t(1) << (idx + minimumHookIndex()) );
74 void* elem= hooks[idx];
75 while( elem ) {
76 void* next= *reinterpret_cast<void**>( elem );
77 allocMember::GetAllocator().free( elem, allocSize );
78 elem= next;
79} } }
80
81
82//============================================ Allocation ==========================================
83template<typename TAllocator, size_t TAlignment>
84void* TPoolAllocator<TAllocator,TAlignment>::reallocate( void* mem,
85 size_t oldSize,
86 size_t& newSize,
87 size_t pAlignment ) {
88 short oldSizeIdx;
89 short newSizeIdx;
90
92
93 ALIB_ASSERT_ERROR(pAlignment <= TAlignment, "MONOMEM",
94 "The requested alignment is higher than what was specified with "
95 "template parameter TAlignment: {} >= {}", pAlignment, TAlignment )
96 (void) pAlignment;
97
98 oldSizeIdx= hookIndex(oldSize);
99 newSizeIdx= hookIndex(newSize);
100 if( newSizeIdx == oldSizeIdx )
101 return mem;
102
103 newSize= GetAllocationSize(newSizeIdx);
104 }
105
106 auto newMem= AllocateByAllocationInfo( newSizeIdx );
107 std::memcpy( newMem, mem, oldSize );
108 #if ALIB_DEBUG_ALLOCATIONS
109 dbgLastRequestedSize= oldSize;
110 #endif
111 FreeByAllocationInfo( oldSizeIdx, mem );
112 return newMem;
113}
114
115template<typename TAllocator, size_t TAlignment>
116void* TPoolAllocator<TAllocator,TAlignment>::AllocateByAllocationInfo(int allocInfo) {ALIB_DCS
117 #if ALIB_DEBUG_ALLOCATIONS
118 // if not set, then this method had been called directly from outside and we store
119 // the hook index instead of the true requested size.
120 if( dbgLastRequestedSize == 0 )
121 dbgLastRequestedSize= size_t(allocInfo);
122 #endif
123
124 #if ALIB_DEBUG_ALLOCATIONS
125 ++dbgOpenAllocations[allocInfo];
126 #endif
127 #if ALIB_DEBUG_MEMORY
128 ++dbgStatAllocCounter[allocInfo];
129 #endif
130
131 void** hook= &hooks[allocInfo];
132
133 // found a recyclable?
134 if( *hook ) {
135 void* mem= *hook;
136 *hook= *reinterpret_cast<void**>(mem);
137
138 #if ALIB_DEBUG_ALLOCATIONS
139 lang::DbgAlloc::annotate( mem, dbgLastRequestedSize, MAGIC );
140 dbgLastRequestedSize= 0;
141 #endif
142 return mem;
143 }
144
145 // create a new object, as no recyclable is available
146 size_t allocSize= lang::DbgAlloc::extSize( size_t(1) << (allocInfo + minimumHookIndex()) );
147 auto* mem= allocMember::AI().Alloc( allocSize, TAlignment );
148
149 #if ALIB_DEBUG_ALLOCATIONS
150 lang::DbgAlloc::annotate( mem, dbgLastRequestedSize, MAGIC );
151 dbgLastRequestedSize= 0;
152 #endif
153
154 return mem;
155}
156
157//============================================== Other =============================================
158
159template<typename TAllocator, size_t TAlignment>
160integer TPoolAllocator<TAllocator,TAlignment>::TPoolAllocator::GetPoolSize(size_t size) {
161 integer result= 0;
162 void* node= hooks[hookIndex(size)];
163 while( node ) {
164 node= *reinterpret_cast<void**>(node);
165 ++result;
166 }
167 return result;
168}
169
170} // namespace [alib::monomem]
171
172#endif // !DOXYGEN
#define ALIB_DCS
Definition alib.inl:1392
#define ALIB_WARNING(domain,...)
Definition alib.inl:1063
#define ALIB_DBG(...)
Definition alib.inl:853
#define ALIB_ASSERT_ERROR(cond, domain,...)
Definition alib.inl:1066
#define ALIB_DEBUG_ALLOCATIONS
Definition prepro.dox.md:39
#define ALIB_DEBUG_CRITICAL_SECTIONS
Definition prepro.dox.md:43
platform_specific integer
Definition integers.inl:32