quake4-sdk/source/idlib/rvMemSys.h

145 lines
5.1 KiB
C++

//
// rvMemSys.h - Memory management system
// Date: 12/17/04
// Created by: Dwight Luetscher
//
// Date: 04/01/05
// Modified by: Marcus Whitlock
// Added permanent heap and new heap push function to push the heap that contains
// a specified piece of memory.
//
// Date: 04/04/05
// Modified by: Marcus Whitlock
// Added rvAutoHeapCtxt class for push and auto-pop of heap context.
//
#ifndef __RV_MEM_SYS_H__
#define __RV_MEM_SYS_H__
typedef enum
{
RV_HEAP_ID_DEFAULT, // heap that exists on application startup
RV_HEAP_ID_PERMANENT, // heap for allocations that have permanent (application scope) lifetime
RV_HEAP_ID_LEVEL, // heap for allocations that have a level lifetime
RV_HEAP_ID_MULTIPLE_FRAME, // heap for run-time allocations that have a lifetime of multiple draw frames
RV_HEAP_ID_SINGLE_FRAME, // heap for run-time allocations that have a lifetime of a single draw frame
RV_HEAP_ID_TEMPORARY, // heap for objects that have a short lifetime (temporaries generally used for level loading)
RV_HEAP_ID_IO_TEMP, // heap for allocations that are temporaries used in I/O operations like level loading or writing out data
rv_heap_ID_max_count // just a count, not a valid type
}
Rv_Sys_Heap_ID_t;
static const uint MAX_SYSTEM_HEAPS = (uint) rv_heap_ID_max_count;
#ifdef _RV_MEM_SYS_SUPPORT
//
// _RV_MEM_SYS_SUPPORT is defined
//
extern rvHeapArena *currentHeapArena;
// Functions for getting and setting the system heaps.
void rvSetSysHeap( Rv_Sys_Heap_ID_t sysHeapID, rvHeap *heapPtr ); // associates a heap with the given system heap ID value
rvHeap* rvGetSysHeap( Rv_Sys_Heap_ID_t sysHeapID ); // retrieves the specified system heap
void rvGetAllSysHeaps( rvHeap *destSystemHeapArray[MAX_SYSTEM_HEAPS] ); // retrieves all the MAX_SYSTEM_HEAPS heap pointers into the given array
void rvSetAllSysHeaps( rvHeap *srcSystemHeapArray[MAX_SYSTEM_HEAPS] ); // associates all the MAX_SYSTEM_HEAPS heap pointers from the given array with their corresponding id value
bool rvPushHeapContainingMemory( const void* mem ); // pushes the heap containg the memory specified to the top of the arena stack, making it current - mwhitlock
void rvEnterArenaCriticalSection( ); // enters the heap arena critical section
void rvExitArenaCriticalSection( ); // exits the heap arena critical section
void rvPushSysHeap(Rv_Sys_Heap_ID_t sysHeapID); // pushes the system heap associated with the given identifier to the top of the arena stack, making it current
// Useful in situations where a heap is pushed, but a return on error or an
// exception could cause the stack to be unwound, bypassing the heap pop
// operation - mwhitlock.
class rvAutoHeapCtxt
{
bool mPushed;
public:
rvAutoHeapCtxt(void) :
mPushed(false)
{
// Should never call this.
assert(0);
}
rvAutoHeapCtxt(Rv_Sys_Heap_ID_t sysHeapID) :
mPushed(false)
{
rvPushSysHeap(sysHeapID);
mPushed = true;
}
rvAutoHeapCtxt(const void* mem) :
mPushed(false)
{
mPushed = rvPushHeapContainingMemory( mem );
}
~rvAutoHeapCtxt(void)
{
if(mPushed)
{
currentHeapArena->Pop();
}
}
};
//
// RV_PUSH_SYS_HEAP_ID()
// Push system heaps by their ID (always available to idLib, Game and executable).
//
#define RV_PUSH_SYS_HEAP_ID(sysHeapID) rvPushSysHeap(sysHeapID)
#define RV_PUSH_SYS_HEAP_ID_AUTO(varName,sysHeapID) rvAutoHeapCtxt varName(sysHeapID)
//
// RV_PUSH_HEAP_MEM()
// Push the heap containing the piece of memory pointed to. Note that if the
// piece of memory is not from a heap, no heap will be pushed.
//
#define RV_PUSH_HEAP_MEM(memPtr) rvPushHeapContainingMemory(memPtr)
#define RV_PUSH_HEAP_MEM_AUTO(varName,memPtr) rvAutoHeapCtxt varName(memPtr)
//
// RV_PUSH_HEAP_PTR()
// Local heaps used mainly by executable (idLib and Game would use these only
// if heap was passed in)
//
#define RV_PUSH_HEAP_PTR(heapPtr) ( (heapPtr)->PushCurrent() )
//
// RV_PUSH_SYS_HEAP()
// Pop top of heap stack, regardless of how it was pushed.
//
#define RV_POP_HEAP() ( currentHeapArena->Pop() )
// The following versions enter/exit the heap arena's critical section so that
// critical section protection remains active between a push/pop pair (NOTE that
// the heap and heap arena are always protected by critical sections within a single method call)
#define RV_PUSH_SYS_HEAP_ENTER_CRIT_SECT(sysHeapID) { rvEnterArenaCriticalSection( ); rvPushSysHeap( sysHeapID ); }
#define RV_PUSH_HEAP_ENTER_CRIT_SECT(heapPtr) { rvEnterArenaCriticalSection( ); (heapPtr)->PushCurrent( ); }
#define RV_POP_HEAP_EXIT_CRIT_SECT() { currentHeapArena->Pop( ); rvExitArenaCriticalSection( ); }
#else // #ifdef _RV_MEM_SYS_SUPPORT
//
// _RV_MEM_SYS_SUPPORT is not defined
//
#define RV_PUSH_SYS_HEAP_ID(sysHeapID)
#define RV_PUSH_SYS_HEAP_ID_AUTO(varName,sysHeapID)
#define RV_PUSH_HEAP_MEM(memPtr)
#define RV_PUSH_HEAP_MEM_AUTO(varName,memPtr)
#define RV_PUSH_HEAP_PTR(heapPtr)
#define RV_POP_HEAP()
#define RV_PUSH_SYS_HEAP_ENTER_CRIT_SECT(sysHeapID)
#define RV_PUSH_HEAP_ENTER_CRIT_SECT(heapPtr)
#define RV_POP_HEAP_EXIT_CRIT_SECT()
#endif // #else not #ifdef _RV_MEM_SYS_SUPPORT
#endif // #ifndef __RV_MEM_SYS_H__