10# if !defined(HPP_ALIB_MONOMEM_MONOALLOCATOR)
13# if !defined(HPP_ALIB_MONOMEM_MONOMEM)
16# if ALIB_ALOX && !defined (HPP_ALOX_LOGTOOLS)
19# if ALIB_STRINGS && ALIB_DEBUG_MONOMEM && !defined(HPP_ALIB_STRINGS_ASTRING)
23# if ALIB_THREADS && ALIB_CAMP
27# if ALIB_DEBUG_MONOMEM
58 void MonoAllocator::dbgCheckGlobalAllocatorLock()
64 ,
"MONOMEM",
"Global MonoAllocator not acquired." )
69#if ALIB_DEBUG_MONOMEM && !defined(ALIB_DOX)
70 bool dbgLogLock(
bool lock)
72 static std::atomic_int locker;
100 size_t initialChunkSize,
unsigned int pChunkGrowthInPercent )
101: chunk ( pfirstChunk )
102, recyclables ( nullptr )
103, nextChunksUsableSize( initialChunkSize - MaxUsableSpaceLoss() )
104, chunkGrowthInPercent( pChunkGrowthInPercent )
106 #if ALIB_DEBUG_MONOMEM
108 DbgStats.
HeapSize+=
static_cast<size_t>( pfirstChunk->
end -
reinterpret_cast<char*
>( pfirstChunk ) );
114 "MONOMEM",
"The initial allocation size has to be greater than {}.",
sizeof(
Chunk) )
120, recyclables ( nullptr )
121, nextChunksUsableSize( initialChunkSize - MaxUsableSpaceLoss() )
122, chunkGrowthInPercent( pChunkGrowthInPercent )
124 DBG_MONOMEM_PATH_DOMAIN
125 DBG_MONOMEM_VERBOSE(
LogDomain,
"Created MonoAllocator. Initial chunk size: ", initialChunkSize )
127 "MONOMEM",
"The initial allocation size has to be greater than ",
sizeof(
Chunk) )
132 unsigned int pChunkGrowthInPercent )
134 DBG_MONOMEM_PATH_DOMAIN
135 DBG_MONOMEM_INFO(
"MA/SELFCNT",
"Creating self-contained MonoAllocator. Initial chunk size: ", initialChunkSize )
138 "MONOMEM",
"The initial allocation size has to be greater than {}.",
sizeof(
Chunk) )
142 return new (allocator)
MonoAllocator( firstChunk, initialChunkSize, pChunkGrowthInPercent );
147 #if ALIB_DEBUG_MONOMEM
159 #if ALIB_DEBUG_MONOMEM
177 #if ALIB_DEBUG_MONOMEM
184 DBG_MONOMEM_PATH_DOMAIN
185 DBG_MONOMEM_INFO( logDomain,
"MonoAllocator destructed. #Chunks: {}, #allocations: {}",
186 cntChunks, qtyAllocations )
188 #if ALIB_DEBUG_MONOMEM
190 "ALIB_DEBUG_MONOMEM Warning: More than 15 chunks allocated. "
191 "Chunksize might be increased? #Chunks: ", cntChunks )
200 "Illegal snapshot given. Chunk allocator has no allocations, yet." )
205 if( snapshot.
chunk ==
nullptr )
214 "Parameterless version of MonoAllocator::Reset() was called for a "
215 "self-contained monotonic allocator created with MonoAllocator::Create()." )
219 #if ALIB_DEBUG_MONOMEM
225 while( it != snapshot.
chunk )
243#if ALIB_DEBUG_MONOMEM
244 #define DBG_ALIGNMENT_INIT(chunk) size_t qtyLeftBeforeAlloc= static_cast<size_t>(chunk->end - chunk->act);
245 #define DBG_ALIGNMENT_MEASURE(chunk) if(mem) DbgStats.AlignmentWaste+= \
247 - static_cast<size_t>(chunk->end - chunk->act)\
250 #define DBG_ALIGNMENT_INIT(...)
251 #define DBG_ALIGNMENT_MEASURE(...)
262 #if ALIB_DEBUG_MONOMEM
279 #if ALIB_DEBUG_MONOMEM
282 DbgStats.
HeapSize+=
static_cast<size_t>( newChunk->
end -
reinterpret_cast<char*
>( newChunk ) );
284 "ALIB_DEBUG_MONOMEM Warning: Allocation size matches or exceeds "
285 "chunk size. Chunksize might be increased? Requested size ",
290 char* mem= newChunk->
alloc( size, alignment );
314 { DBG_ALIGNMENT_INIT( recyclable )
315 char* mem= recyclable->
alloc( size, alignment ); DBG_ALIGNMENT_MEASURE( recyclable )
318 *previousPointer= recyclable->
previous;
325 previousPointer= &recyclable->
previous;
335 #if ALIB_DEBUG_MONOMEM
340 char* mem=
chunk->
alloc( size, alignment ); DBG_ALIGNMENT_MEASURE(
chunk )
348#if ALIB_STRINGS && ALIB_DEBUG_MONOMEM
355 result <<
"MonoAllocator Usage Statistics:" <<
NNewLine();
363 result <<
" Avg. alloc./chunk: ";
377 int qtyRecyclables= 0;
380 while( rchunks !=
nullptr )
383 qtyFree+= size_t(rchunks->end - rchunks->act);
384 rchunks= rchunks->previous;
387 result <<
" Free in recyclables: " <<
Format( qtyFree , &nf );
388 result <<
" (" << qtyRecyclables <<
" recyclables)" <<
NNewLine();
395#if ALIB_DEBUG_MONOMEM && !defined(ALIB_DOX)
397 void dbgMonoMemRecyclingOutput(
size_t a,
size_t b,
size_t c,
const std::type_info& typeInfo,
size_t d )
399 DBG_MONOMEM_INFO(
"RECYCLING",
400 "Recycling {} objects from de-allocated memory of size {} (lost {} bytes).\n"
401 "Deallocated type: {!Q<>}{!Q[]}.",
402 a, b, c, typeInfo, d )
static ALIB_API detail::textlogger::TextLogger * DebugLogger
ALIB_API MonoAllocator(size_t initialChunkSize, unsigned int chunkGrowthInPercent=200)
unsigned int chunkGrowthInPercent
size_t nextChunksUsableSize
ALIB_API NAString DbgDumpStats()
static ALIB_API MonoAllocator * Create(size_t initialChunkSize, unsigned int chunkGrowthInPercent=200)
ALIB_API void Reset(const Snapshot &snapshot=Snapshot())
ALIB_API char * getCreateChunk(size_t size, size_t alignment)
static constexpr size_t MaxUsableSpaceLoss()
ALIB_API ~MonoAllocator()
bool IsOwnedByCurrentThread() const
lang::Safeness GetSafeness() const
#define ALIB_IF_THREADS(...)
#define ALIB_ASSERT_ERROR(cond,...)
#define ALIB_ASSERT_WARNING(cond,...)
#define ALIB_ASSERT(cond)
@ Unsafe
Omit checks or perform unsafe operations.
ALIB_API ThreadLock GlobalAllocatorLock
ALIB_API uinteger DbgStatsStringTreeNameOverflows
ALIB_API uinteger DbgStatsStringTreeNames
MonoAllocator GlobalAllocator(8 *1024)
lang::uinteger uinteger
Type alias in namespace alib.
lang::basecamp::BaseCamp BASECAMP
constexpr NCString NNewLine()
monomem::MonoAllocator MonoAllocator
Type alias in namespace alib.
strings::TFormat< character > Format
Type alias in namespace alib.
threads::ThreadLock ThreadLock
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
ALIB_FORCE_INLINE char * alloc(size_t requestedSize, size_t alignment)
Chunk * previous
the previously allocated chunk.
char * end
Pointer to the first byte behind the chunk.
char * act
Pointer to the free space in the chunk.
static ALIB_FORCE_INLINE Chunk * create(size_t size)
size_t QtyChunkSizeExceeds
size_t QtyTrivialAllocations