diff options
Diffstat (limited to 'engine/zone.cpp')
| -rw-r--r-- | engine/zone.cpp | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/engine/zone.cpp b/engine/zone.cpp new file mode 100644 index 0000000..5d90fa5 --- /dev/null +++ b/engine/zone.cpp @@ -0,0 +1,169 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// ZONE MEMORY ALLOCATION +// +// There is never any space between memblocks, and there will never be two +// contiguous free memblocks. +// +// The rover can be left pointing at a non-empty block +// +// The zone calls are pretty much only used for small strings and structures, +// all big things are allocated on the hunk. +//=============================================================================// + +#include "basetypes.h" +#include "zone.h" +#include "host.h" +#include "tier1/strtools.h" +#include "tier0/icommandline.h" +#include "memstack.h" +#include "datacache/idatacache.h" +#include "sys_dll.h" +#include "tier0/memalloc.h" + +#define MINIMUM_WIN_MEMORY 0x03000000 // FIXME: copy from sys_dll.cpp, find a common header at some point + +#ifdef _X360 +#define HUNK_USE_16MB_PAGE +#endif + +CMemoryStack g_HunkMemoryStack; +#ifdef HUNK_USE_16MB_PAGE +CMemoryStack g_HunkOverflow; +static bool g_bWarnedOverflow; +#endif + +static int GetTargetCacheSize() +{ + int nMemLimit = host_parms.memsize - Hunk_Size(); + if ( nMemLimit < 0x100000 ) + { + nMemLimit = 0x100000; + } + return nMemLimit; +} + +/* +=================== +Hunk_AllocName +=================== +*/ +void *Hunk_AllocName (int size, const char *name, bool bClear) +{ + MEM_ALLOC_CREDIT(); + void * p = g_HunkMemoryStack.Alloc( size, bClear ); + if ( p ) + return p; +#ifdef HUNK_USE_16MB_PAGE + if ( !g_bWarnedOverflow ) + { + g_bWarnedOverflow = true; + DevMsg( "Note: Hunk base page exhausted\n" ); + } + + p = g_HunkOverflow.Alloc( size, bClear ); + if ( p ) + return p; +#endif + Error( "Engine hunk overflow!\n" ); + return NULL; +} + +/* +=================== +Hunk_Alloc +=================== +*/ +void *Hunk_Alloc(int size, bool bClear ) +{ + MEM_ALLOC_CREDIT(); + return Hunk_AllocName( size, NULL, bClear ); +} + +int Hunk_LowMark(void) +{ + return (int)( g_HunkMemoryStack.GetCurrentAllocPoint() ); +} + +void Hunk_FreeToLowMark(int mark) +{ + Assert( mark < g_HunkMemoryStack.GetSize() ); +#ifdef HUNK_USE_16MB_PAGE + g_HunkOverflow.FreeAll(); + g_bWarnedOverflow = false; +#endif + g_HunkMemoryStack.FreeToAllocPoint( mark ); +} + +int Hunk_MallocSize() +{ +#ifdef HUNK_USE_16MB_PAGE + return g_HunkMemoryStack.GetSize() + g_HunkOverflow.GetSize(); +#else + return g_HunkMemoryStack.GetSize(); +#endif +} + +int Hunk_Size() +{ +#ifdef HUNK_USE_16MB_PAGE + return g_HunkMemoryStack.GetUsed() + g_HunkOverflow.GetUsed(); +#else + return g_HunkMemoryStack.GetUsed(); +#endif +} + +void Hunk_Print() +{ +#ifdef HUNK_USE_16MB_PAGE + Msg( "Total used memory: %d (%d/%d)\n", Hunk_Size(), g_HunkMemoryStack.GetUsed(), g_HunkOverflow.GetUsed() ); + Msg( "Total committed memory: %d (%d/%d)\n", Hunk_MallocSize(), g_HunkMemoryStack.GetSize(), g_HunkOverflow.GetSize() ); +#else + Msg( "Total used memory: %d\n", Hunk_Size() ); + Msg( "Total committed memory: %d\n", Hunk_MallocSize() ); +#endif +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void Memory_Init( void ) +{ + MEM_ALLOC_CREDIT(); + int nMaxBytes = 48*1024*1024; + const int nMinCommitBytes = 0x8000; +#ifndef HUNK_USE_16MB_PAGE + const int nInitialCommit = 0x280000; + while ( !g_HunkMemoryStack.Init( nMaxBytes, nMinCommitBytes, nInitialCommit ) ) + { + Warning( "Unable to allocate %d MB of memory, trying %d MB instead\n", nMaxBytes, nMaxBytes/2 ); + nMaxBytes /= 2; + if ( nMaxBytes < MINIMUM_WIN_MEMORY ) + { + Error( "Failed to allocate minimum memory requirement for game (%d MB)\n", MINIMUM_WIN_MEMORY/(1024*1024)); + } + } +#else + if ( !g_HunkMemoryStack.InitPhysical( 16*1024*1024 ) || !g_HunkOverflow.Init( nMaxBytes - 16*1024*1024, nMinCommitBytes ) ) + { + Error( "Failed to allocate minimum memory requirement for game (%d MB)\n", nMaxBytes ); + } + +#endif + g_pDataCache->SetSize( GetTargetCacheSize() ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void Memory_Shutdown( void ) +{ + g_HunkMemoryStack.FreeAll(); + + // This disconnects the engine data cache + g_pDataCache->SetSize( 0 ); +} |