Handle based Memory Manager. More...
Classes | |
struct | Handle_t |
Structure describing an allocated chunk of memory. More... | |
struct | SystemBlock_t |
Public Types | |
enum | eMemoryStage { kStageCompact , kStagePurge , kStageHailMary , kStageGiveup } |
typedef void(*) | MemPurgeProc(void *pThis, eMemoryStage uStage) |
Function prototype for user supplied garbage collection subroutine. | |
Public Types inherited from Burger::MemoryManager | |
typedef void *(*) | ProcAlloc(MemoryManager *pThis, uintptr_t uSize) |
Function prototype for allocating memory. | |
typedef void(*) | ProcFree(MemoryManager *pThis, const void *pInput) |
Function prototype for releasing memory. | |
typedef void *(*) | ProcRealloc(MemoryManager *pThis, const void *pInput, uintptr_t uSize) |
Function prototype for reallocating memory. | |
typedef void(*) | ProcShutdown(MemoryManager *pThis) |
Function prototype for destructor. | |
Public Member Functions | |
MemoryManagerHandle (uintptr_t uDefaultMemorySize=kSystemMemoryChuckSize, uint_t uDefaultHandleCount=kDefaultHandleCount, uintptr_t uMinReserveSize=kSystemMemoryReservedSize) noexcept | |
Initialize the Handle based Memory Manager. | |
~MemoryManagerHandle () | |
The destructor for the Handle based Memory Manager. | |
uintptr_t | GetTotalAllocatedMemory (void) const noexcept |
Returns the total allocated memory used by pointers and handles in bytes. | |
void * | alloc (uintptr_t uSize) noexcept |
Allocate fixed memory. | |
void | free (const void *pInput) noexcept |
Release fixed memory. | |
void * | realloc (const void *pInput, uintptr_t uSize) noexcept |
Resize a preexisting allocated block of memory. | |
void | shutdown (void) noexcept |
Shutdown the handle based Memory Manager. | |
void ** | alloc_handle (uintptr_t uSize, uint_t uFlags=0) noexcept |
Allocates a block of memory. | |
void | free_handle (void **ppInput) noexcept |
Dispose of a memory handle into the free handle pool. | |
void ** | ReallocHandle (void **ppInput, uintptr_t uSize) noexcept |
Resize a handle. | |
void ** | RefreshHandle (void **ppInput) noexcept |
If the handle was purged, reallocate memory to it. | |
void ** | FindHandle (const void *pInput) noexcept |
Search the handle tree for a pointer. | |
uintptr_t | GetTotalFreeMemory (void) noexcept |
Returns the total free space with purging. | |
void | clear_purge_flag (void **ppInput) noexcept |
void | set_purge_flag (void **ppInput) noexcept |
Set the purge flag to a given handle. | |
void | SetLockedState (void **ppInput, uint_t uFlag) noexcept |
Set the current purge and lock flags of the handle. | |
void | Purge (void **ppInput) noexcept |
Move a handle into the purged list. | |
uint_t | PurgeHandles (uintptr_t uSize) noexcept |
Purges handles until the amount of memory requested is freed. | |
void | CompactHandles (void) noexcept |
Compact all of the movable blocks together. | |
void | dump_handles (void) noexcept |
Display all the memory. | |
Public Member Functions inherited from Burger::MemoryManager | |
void * | alloc (uintptr_t uSize) noexcept |
Allocate memory. | |
void | free (const void *pInput) noexcept |
Release memory. | |
void * | realloc (const void *pInput, uintptr_t uSize) noexcept |
Reallocate memory. | |
void | shutdown (void) noexcept |
Shut down the memory manager. | |
void * | alloc_clear (uintptr_t uSize) noexcept |
Allocate a block of pre-zeroed memory. | |
Static Public Member Functions | |
static uintptr_t | GetSize (void **ppInput) noexcept |
Returns the size of a memory handle. | |
static uintptr_t | GetSize (const void *pInput) noexcept |
Returns the size of a memory pointer. | |
static void * | lock (void **ppInput) noexcept |
Set the lock flag to a given handle and return the data pointer. | |
static void | unlock (void **ppInput) noexcept |
Clear the lock flag to a given handle. | |
static void | set_ID (void **ppInput, uint_t uID) noexcept |
Set a user supplied ID value for a handle. | |
static uint_t | GetLockedState (void **ppInput) noexcept |
Get the current purge and lock flags of the handle. | |
Static Public Member Functions inherited from Burger::MemoryManager | |
static void | shutdown (MemoryManager *pThis) noexcept |
Default memory manager destructor. | |
Static Public Attributes | |
static const uint32_t | kFlagLocked = 0x80 |
Set if the memory handle is temporarily locked. | |
static const uint32_t | kFlagFixed = 0x40 |
Set if the memory cannot be moved (High memory) | |
static const uint32_t | kFlagMalloc = 0x20 |
Set if the memory was allocated with malloc() | |
static const uint32_t | kFlagPurgable = 0x01 |
Set if the handle is purgable. | |
static const uintptr_t | kAlignment = 16 |
Memory alignment, power of 2, larger or equal to sizeof(void*) | |
static const uint32_t | kDefaultHandleCount = 512 |
Default starting number of memory handles. | |
static const uintptr_t | kSystemMemoryChuckSize = 0x1000000 |
Default memory chunk allocation size from system. | |
static const uintptr_t | kSystemMemoryReservedSize = 0x40000 |
Default reserved system memory size. | |
static const uint32_t | kMemoryIDUnused = UINT32_MAX - 2 |
Unused handle memory ID. | |
static const uint32_t | kMemoryIDFree = UINT32_MAX - 1 |
Free handle memory ID. | |
static const uint32_t | kMemoryIDReserved = UINT32_MAX |
Reserved handle memory ID. | |
Private Member Functions | |
MemoryManagerHandle (const MemoryManagerHandle &)=delete | |
MemoryManagerHandle & | operator= (const MemoryManagerHandle &)=delete |
MemoryManagerHandle (MemoryManagerHandle &&)=delete | |
MemoryManagerHandle & | operator= (MemoryManagerHandle &&)=delete |
Handle_t * | AllocNewHandle (void) noexcept |
Allocate a new handle record. | |
void | GrabMemoryRange (void *pData, uintptr_t uLength, Handle_t *pParent, Handle_t *pHandle) noexcept |
Remove a range of memory from the free memory pool. | |
void | ReleaseMemoryRange (void *pData, uintptr_t uLength, Handle_t *pParent) noexcept |
Add a range of memory to the free memory list. | |
void | PrintHandles (const Handle_t *pFirst, const Handle_t *pLast, uint_t bNoCheck) noexcept |
Print the state of the memory to Burger::Debug::String(const char *) | |
Static Private Member Functions | |
static void * | alloc_proc (MemoryManager *pThis, uintptr_t uSize) noexcept |
Allocate fixed memory. | |
static void | free_proc (MemoryManager *pThis, const void *pInput) noexcept |
Release fixed memory. | |
static void * | realloc_proc (MemoryManager *pThis, const void *pInput, uintptr_t uSize) noexcept |
Resize a preexisting allocated block of memory. | |
static void | shutdown_proc (MemoryManager *pThis) noexcept |
Shutdown the handle based Memory Manager. | |
Private Attributes | |
SystemBlock_t * | m_pSystemMemoryBlocks |
Linked list of memory blocks taken from the system. | |
MemPurgeProc | m_MemPurgeCallBack |
Callback before memory purging. | |
void * | m_pMemPurge |
User pointer for memory purge. | |
uintptr_t | m_uTotalAllocatedMemory |
All of the memory currently allocated. | |
uintptr_t | m_uTotalSystemMemory |
Total allocated system memory. | |
Handle_t * | m_pFreeHandle |
Pointer to the free handle list. | |
uint_t | m_uTotalHandleCount |
Number of handles allocated. | |
Handle_t | m_LowestUsedMemory |
First used memory handle (Start of linked list) | |
Handle_t | m_HighestUsedMemory |
Last used memory handle (End of linked list) | |
Handle_t | m_FreeMemoryChunks |
Free handle list. | |
Handle_t | m_PurgeHands |
Purged handle list. | |
Handle_t | m_PurgeHandleFiFo |
Purged handle linked list. | |
Mutex | m_Lock |
Lock for multi-threading support. | |
Additional Inherited Members | |
Public Attributes inherited from Burger::MemoryManager | |
ProcAlloc | m_pAlloc |
Pointer to allocation function. | |
ProcFree | m_pFree |
Pointer to memory release function. | |
ProcRealloc | m_pRealloc |
Pointer to the memory reallocation function. | |
ProcShutdown | m_pShutdown |
Pointer to the shutdown function. | |
Handle based Memory Manager.
This class allocates and releases memory using movable memory blocks and can allocate from the top and bottom of memory if needed. Fixed memory blocks are allocate from the top of memory and movable memory blocks are allocated from the bottom. Movable blocks can be marked as purgeable so in low memory situations, the memory can be freed without the main application's knowledge. To accomplish this, any access to a handle must be first locked and then tested if it's been purged. If it's purged, the memory must be reallocated and reloaded with the data. It's mostly used by the resource, texture and audio managers to cache in data chunks that can be reloaded from disk if need be.
void( *) Burger::MemoryManagerHandle::MemPurgeProc(void *pThis, eMemoryStage uStage) |
Function prototype for user supplied garbage collection subroutine.
|
privatedelete |
|
privatedelete |
|
noexcept |
Initialize the Handle based Memory Manager.
Burger::MemoryManagerHandle::~MemoryManagerHandle | ( | ) |
The destructor for the Handle based Memory Manager.
This calls Burger::MemoryManagerHandle::shutdown(MemoryManager *) to do the actual work
|
inlinenoexcept |
Allocate fixed memory.
Allocates a pointer to a block of memory in high (Fixed) memory.
uSize | Number of bytes requested |
|
noexcept |
Allocates a block of memory.
Allocates from the top down if fixed and bottom up if movable This routine handles all the magic for memory purging and allocation.
uSize | Number of bytes requested |
uFlags | Flags to modify how the memory is allocated, kFlagFixed for fixed memory, 0 for movable memory |
|
staticprivatenoexcept |
Allocate fixed memory.
Static function to allocate a pointer to a block of memory in high (Fixed) memory.
pThis | Pointer to the MemoryManagerHandle instance |
uSize | Size of memory block request |
|
privatenoexcept |
Allocate a new handle record.
If out of handles in the pool, allocate memory from the operating system in kDefaultHandleCount * sizeof( MemoryManagerHandle::Handle_t) chunks
|
noexcept |
|
noexcept |
Compact all of the movable blocks together.
Packs all memory together to reduce or eliminate fragmentation This doesn't alter the handle list in any way but it can move memory around to get rid of empty holes in the memory map.
|
noexcept |
|
noexcept |
Search the handle tree for a pointer.
pInput | Pointer to memory to locate |
|
inlinenoexcept |
Release fixed memory.
When a pointer is allocated using Burger::MemoryManagerHandle::alloc(uintptr_t), it has a pointer to the handle that references this memory prefixed to it. If the input is not NULL it will use this prefixed pointer to release the handle and therefore this memory.
pInput | Pointer to memory to release, NULL does nothing |
|
noexcept |
Dispose of a memory handle into the free handle pool.
ppInput | Handle to memory allocated by alloc_handle(uintptr_t,uint_t) |
|
staticprivatenoexcept |
Release fixed memory.
When a pointer is allocated using Burger::MemoryManagerHandle::alloc_proc() It has a pointer to the handle that references this memory prefixed to it. If the input is not NULL it will use this prefixed pointer to release the handle and therefore this memory.
pThis | Pointer to the MemoryManagerHandle instance |
pInput | Pointer to memory to release, NULL does nothing |
|
staticnoexcept |
Get the current purge and lock flags of the handle.
ppInput | Pointer to valid handle. NULL is invalid |
|
staticnoexcept |
|
staticnoexcept |
|
inlinenoexcept |
Returns the total allocated memory used by pointers and handles in bytes.
This is the total number of bytes allocated with all padding necessary for data alignment
|
noexcept |
Returns the total free space with purging.
This is accomplished by adding all the memory found in the free memory linked list and then adding all the memory in the used list that can be purged.
|
privatenoexcept |
Remove a range of memory from the free memory pool.
Assume that the memory range is either attached to the end of a free memory segment or the end of a free memory segment.
If not, bad things will happen!
pData | Pointer to the start of the memory block to reserve |
uLength | Size in bytes of the memory block to reserve |
pParent | Pointer to the handle to the allocated handle BEFORE this block |
pHandle | Handle of the currently free block of memory to allocate from or NULL if the function has to scan manually |
|
staticnoexcept |
Set the lock flag to a given handle and return the data pointer.
ppInput | Pointer to handle to lock or NULL |
|
privatedelete |
|
privatedelete |
|
privatenoexcept |
Print the state of the memory to Burger::Debug::String(const char *)
Walk the linked list of handles from pFirst to pLast and print to the text output a report of the memory handles. All text is printed via Debug::String(const char *)
pFirst | Pointer to the first block to dump |
pLast | Pointer to the block that the dump will cease (Don't dump it) |
bNoCheck | If true, print pFirst at all times |
|
noexcept |
Move a handle into the purged list.
This routine will move a handle from the used list into the purged handle list. The handle is not discarded. This is the only way a handle can be placed into the purged list.
It will call Burger::MemoryManagerHandle::ReleaseMemoryRange() to alert the free memory list that there is new free memory.
ppInput | Handle to allocated memory or NULL to perform no action |
|
noexcept |
Purges handles until the amount of memory requested is freed.
Purges all handles that are purgeable and are greater or equal to the amount of memory It will call Purge(void **) to alert the free memory list that there is free memory.
uSize | The number of bytes to recover before aborting |
|
inlinenoexcept |
Resize a preexisting allocated block of memory.
Using a pointer to memory, reallocate the size and copy the contents. If a zero length buffer is requested, the input pointer is deallocated, if the input pointer is NULL, a fresh pointer is created.
pInput | Pointer to memory to resize, NULL forces a new block to be created |
uSize | Size of memory block request |
|
staticprivatenoexcept |
Resize a preexisting allocated block of memory.
Using a pointer to memory, reallocate the size and copy the contents. If a zero length buffer is requested, the input pointer is deallocated, if the input pointer is NULL, a fresh pointer is created.
pThis | Pointer to the MemoryManagerHandle instance |
pInput | Pointer to memory to resize, NULL forces a new block to be created |
uSize | Size of memory block request |
|
noexcept |
Resize a handle.
Using a handle to memory, reallocate the size and copy the contents. If the input handle is NULL, then just allocate a new handle, if the size requested is zero then discard the input handle.
ppInput | Handle to resize |
uSize | Size in bytes of the new handle |
|
noexcept |
If the handle was purged, reallocate memory to it.
ppInput | Handle to be restored |
|
privatenoexcept |
Add a range of memory to the free memory list.
pData | Pointer to the memory block to return to the pool |
uLength | Size of the memory block to return to the pool |
pParent | Pointer to the Handle_t structure of the memory that was released |
|
staticnoexcept |
Set a user supplied ID value for a handle.
ppInput | Pointer to handle to set the ID |
uID | Handle ID |
|
noexcept |
|
noexcept |
Set the current purge and lock flags of the handle.
ppInput | Handle to valid memory. |
uFlag | kFlagPurgable and kFlagLocked are the only valid input flags |
|
inlinenoexcept |
Shutdown the handle based Memory Manager.
|
staticprivatenoexcept |
Shutdown the handle based Memory Manager.
pThis | Pointer to the MemoryManagerHandle instance |
|
staticnoexcept |
Clear the lock flag to a given handle.
ppInput | Pointer to handle to unlock or NULL |
|
static |
Memory alignment, power of 2, larger or equal to sizeof(void*)
|
static |
Default starting number of memory handles.
|
static |
Set if the memory cannot be moved (High memory)
|
static |
Set if the memory handle is temporarily locked.
|
static |
Set if the memory was allocated with malloc()
|
static |
Set if the handle is purgable.
|
static |
Free handle memory ID.
|
static |
Reserved handle memory ID.
|
static |
Unused handle memory ID.
|
static |
Default memory chunk allocation size from system.
|
static |
Default reserved system memory size.
|
private |
Free handle list.
|
private |
Last used memory handle (End of linked list)
|
private |
Lock for multi-threading support.
|
private |
First used memory handle (Start of linked list)
|
private |
Callback before memory purging.
|
private |
Pointer to the free handle list.
|
private |
User pointer for memory purge.
|
private |
Linked list of memory blocks taken from the system.
|
private |
Purged handle linked list.
|
private |
Purged handle list.
|
private |
All of the memory currently allocated.
|
private |
Number of handles allocated.
|
private |
Total allocated system memory.