You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
4.1 KiB
170 lines
4.1 KiB
5 years ago
|
//========= 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 );
|
||
|
}
|