Files CCore/inc/HeapEngine.h CCore/src/HeapEngine.cpp
HeapEngine is a fully-featured heap class. It is a Resource Provider Type. It implements the heap functionality using another heap class. HeapEngine adds three important things: mutex protection, statistic accounting and usage limitation.
template <class Heap>
class HeapEngine : NoCopy
{
Mutex mutex;
Heap heap;
MemStatData stat;
MemStatData peak;
ulen limit;
public:
template <class ... SS>
explicit HeapEngine(TextLabel name,SS && ... ss);
~HeapEngine();
void * alloc(ulen len);
ulen getLen(const void *mem); // mem may == 0
void free(void *mem); // mem may == 0
bool extend(void *mem,ulen len); // mem may == 0
bool shrink(void *mem,ulen len); // mem may == 0
void setLim(ulen limit);
void getStat(MemStatData &ret);
void getPeak(MemStatData &ret);
};
The name in constructor is used to name the mutex. Other arguments are used to initialize the heap.
The semantic of methods are the same as of global heap functions Mem...().
setLim() sets the limit on memory allocation. Value zero means no limit. If the limit is set, then the HeapEngine will keep the total allocated memory below this limit.
getStat() returns the current memory allocation statistics.
getPeak() returns the peak memory allocation statistics.
alloc() tries to allocate the memory block. On success it returns its address, on failure — null. Even if the len is null, the address of the allocated memory block is not null and its actual length too. The actual length of the allocated memory block may be a slightly greater than the len. Memory is aligned, but this is ensured by the underlying class Heap.
In the remaining four methods the argument mem may be null, in this case methods do nothing. Otherwise it must be an address of a previously allocated memory block.
getLen() returns the actual length of the allocated memory block. If the mem is null, it returns null.
free() releases the allocated memory block.
extend() extends the memory block, if it is possible. The len is the required length of the new block. The return value means the success of the operation. If the mem is null, it returns false. extend() is always successful (but does nothing) if the len is not greater than the actual length of the memory block.
shrink() shrinks the memory block. The len is the required length of the new block. The return value means the success of the operation. If the mem is null, it returns false. shrink() fails only if the len is greater than the actual length of the memory block.
The underlying class Heap must provide the following functionality:
class Heap { public: Heap(); Heap(....); ~Heap(); Space alloc(ulen len); // ret.len!=0 on success (==memlen) ulen getLen(const void *mem); // mem!=0, return memlen ulen free(void *mem); // mem!=0, return memlen DeltaLen extend(void *mem,ulen len); // mem!=0 DeltaLen shrink(void *mem,ulen len); // mem!=0 };
It may have several constructors with different arguments as necessary.
It is highly recommended that the destructor checks memory leaks and abort execution if there is unreleased memory.
alloc() tries to allocate a memory. On failure it returns a null Space object. Otherwise the resulting Space object contains non-zero memory pointer and non-zero memory length, which is greater or equal than the argument len.
Other methods require a valid non-null pointer mem.
getLen() returns the length of the memory block.
free() releases the memory block, this method returns the length of the memory block.
extend() extends the memory block up to the given len, if possible. If the len is not greater than the length of the memory block, the operation is successful, but change nothing. The resulting DeltaLen object has the field ok, which indicates success of the operation, and the field delta, equals the difference between the length of the new block and the old one.
shrink() shrinks the memory block down to the given len. This operation is successful only if the len is not greater than the length of the memory block. The resulting DeltaLen object has the field ok, which indicates success of the operation, and the field delta, equals the difference between the length of the old block and the new one.