ALib C++ Library
Library Version: 2510 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{
47 if ( hooks == nullptr )
48 return;
49
50 deletePool();
51 allocMember::AI().template FreeArray<void*>(hooks, qtyHooks());
52 ALIB_DBG( hooks= nullptr; )
53
55 for (short i = 0; i < qtyHooks(); ++i)
56 {
57 if ( dbgOpenAllocations[i] > 0)
58 ALIB_WARNING( "MONOMEM",
59 "PoolAllocator '{}' destructor: There are still {} objects of size {}"
60 " not freed.\n This indicates a potential memory leak.",
61 DbgName, dbgOpenAllocations[i], GetAllocationSize(i) )
62 }
63 allocMember::AI().template FreeArray<int>(dbgOpenAllocations, qtyHooks() );
64 #endif
65 #if ALIB_DEBUG_MEMORY
66 allocMember::AI().template DeleteArray<uinteger>(dbgStatAllocCounter, qtyHooks() );
67 #endif
68
69}
70
71
72template<typename TAllocator, size_t TAlignment>
73void TPoolAllocator<TAllocator,TAlignment>::deletePool()
74{
75 for (int idx = 0; idx < qtyHooks(); ++idx)
76 {
77 size_t allocSize= lang::DbgAlloc::extSize( size_t(1) << (idx + minimumHookIndex()) );
78 void* elem= hooks[idx];
79 while( elem )
80 {
81 void* next= *reinterpret_cast<void**>( elem );
82 allocMember::GetAllocator().free( elem, allocSize );
83 elem= next;
84 }
85 }
86}
87
88
89// ======================================= Allocation ========================================
90template<typename TAllocator, size_t TAlignment>
91void* TPoolAllocator<TAllocator,TAlignment>::reallocate( void* mem, size_t oldSize, size_t& newSize, size_t pAlignment )
92{
93 short oldSizeIdx;
94 short newSizeIdx;
95
97
98 ALIB_ASSERT_ERROR(pAlignment <= TAlignment, "MONOMEM",
99 "The requested alignment is higher than what was specified with "
100 "template parameter TAlignment: {} >= {}", pAlignment, TAlignment )
101 (void) pAlignment;
102
103 oldSizeIdx= hookIndex(oldSize);
104 newSizeIdx= hookIndex(newSize);
105 if( newSizeIdx == oldSizeIdx )
106 return mem;
107
108 newSize= GetAllocationSize(newSizeIdx);
109 }
110
111 auto newMem= AllocateByAllocationInfo( newSizeIdx );
112 std::memcpy( newMem, mem, oldSize );
113 #if ALIB_DEBUG_ALLOCATIONS
114 dbgLastRequestedSize= oldSize;
115 #endif
116 FreeByAllocationInfo( oldSizeIdx, mem );
117 return newMem;
118}
119
120template<typename TAllocator, size_t TAlignment>
121void* TPoolAllocator<TAllocator,TAlignment>::AllocateByAllocationInfo(int allocInfo)
123 #if ALIB_DEBUG_ALLOCATIONS
124 // if not set, then this method had been called directly from outside and we store
125 // the hook index instead of the true requested size.
126 if( dbgLastRequestedSize == 0 )
127 dbgLastRequestedSize= size_t(allocInfo);
128 #endif
129
130 #if ALIB_DEBUG_ALLOCATIONS
131 ++dbgOpenAllocations[allocInfo];
132 #endif
133 #if ALIB_DEBUG_MEMORY
134 ++dbgStatAllocCounter[allocInfo];
135 #endif
136
137 void** hook= &hooks[allocInfo];
138
139 // found a recyclable?
140 if( *hook )
141 {
142 void* mem= *hook;
143 *hook= *reinterpret_cast<void**>(mem);
144
145 #if ALIB_DEBUG_ALLOCATIONS
146 lang::DbgAlloc::annotate( mem, dbgLastRequestedSize, MAGIC );
147 dbgLastRequestedSize= 0;
148 #endif
149 return mem;
150 }
151
152 // create a new object, as no recyclable is available
153 size_t allocSize= lang::DbgAlloc::extSize( size_t(1) << (allocInfo + minimumHookIndex()) );
154 auto* mem= allocMember::AI().Alloc( allocSize, TAlignment );
155
156 #if ALIB_DEBUG_ALLOCATIONS
157 lang::DbgAlloc::annotate( mem, dbgLastRequestedSize, MAGIC );
158 dbgLastRequestedSize= 0;
159 #endif
160
161 return mem;
162}
163
164// ========================================= Other ===========================================
165
166template<typename TAllocator, size_t TAlignment>
167integer TPoolAllocator<TAllocator,TAlignment>::TPoolAllocator::GetPoolSize(size_t size)
168{
169 integer result= 0;
170 void* node= hooks[hookIndex(size)];
171 while( node )
172 {
173 node= *reinterpret_cast<void**>(node);
174 ++result;
175 }
176 return result;
177}
178
179} // namespace [alib::monomem]
180
181#endif // !DOXYGEN
182
#define ALIB_DCS
Definition alib.inl:1375
#define ALIB_WARNING(domain,...)
Definition alib.inl:1046
#define ALIB_DBG(...)
Definition alib.inl:836
#define ALIB_ASSERT_ERROR(cond, domain,...)
Definition alib.inl:1049
#define ALIB_DEBUG_ALLOCATIONS
Definition prepro.md:39
#define ALIB_DEBUG_CRITICAL_SECTIONS
Definition prepro.md:43
platform_specific integer
Definition integers.inl:32