forked from darklegion/tremulous
-
Notifications
You must be signed in to change notification settings - Fork 1
Hunk Memory, The memory allocator (Refacator ideas)
Victor Roemer edited this page Aug 4, 2022
·
4 revisions
In practice, the hunk memory is just a pre-allocated mempool for the mutable state of the game engine and it's modules.
/*
============================
CL_StartHunkUsers
After the server has cleared the hunk, these will need to be restarted
This is the only place that any of these functions are called from
============================
*/
void CL_StartHunkUsers(bool rendererOnly)
cls.rendererStarted = true;
CL_InitRenderer();
cls.soundStarted = true;
S_Init();
cls.soundRegistered = true;
S_BeginRegistration();
cls.uiStarted = true;
CL_InitUI();
Rediculous amount of stuff happening
void Com_InitHunkMemory( void )
{
1. Hunk Initializer needs to operate independently of any other engine components.
// make sure the file system has allocated and "not" freed any temp blocks
// this allows the config and product id files ( journal files too ) to be loaded
// by the file system without redunant routines in the file system utilizing different
// memory systems
if (FS_LoadStack() != 0)
Com_Error( ERR_FATAL, "Hunk initialization failed. File system load stack not zero");
2. Must not be consuming user input directly
// allocate the stack based hunk allocator
cv = Cvar_Get( "com_hunkMegs", DEF_COMHUNKMEGS_S, CVAR_LATCH | CVAR_ARCHIVE );
Cvar_SetDescription(cv, "The size of the hunk memory segment");
3. again, more user input
// if we are not dedicated min allocation is 56, otherwise min is 1
if (com_dedicated && com_dedicated->integer)
{
nMinAlloc = MIN_DEDICATED_COMHUNKMEGS;
pMsg = "Minimum com_hunkMegs for a dedicated server is %i, allocating %i megs.\n";
}
else
{
nMinAlloc = MIN_COMHUNKMEGS;
pMsg = "Minimum com_hunkMegs is %i, allocating %i megs.\n";
}
4. This is probably okay
s_hunkData = (byte*)calloc( s_hunkTotal + 31, 1 );
if ( !s_hunkData )
{
Com_Error( ERR_FATAL, "Hunk data failed to allocate %i megs", s_hunkTotal / (1024*1024) );
}
// cacheline align
s_hunkData = (byte *) ( ( (intptr_t)s_hunkData + 31 ) & ~31 );
Hunk_Clear();
5. But this is not
Cmd_AddCommand( "meminfo", Com_Meminfo_f );
Cmd_AddCommand( "zonelog", Z_LogHeap );
Cmd_AddCommand( "hunklog", Hunk_Log );
Cmd_AddCommand( "hunksmalllog", Hunk_SmallLog );
}
Init should probably be called only a single time ever, from main()
.
void Hunk_Clear( void )
{
#ifndef DEDICATED
CL_ShutdownCGame();
CL_ShutdownUI();
#endif
SV_ShutdownGameProgs();
#ifndef DEDICATED
CIN_CloseAllVideos();
#endif
- All the shutdown calls need to be lifted
Reset state of the allocated address space.
void Hunk_Log( void)
Remove this altogether
/*
===================
Hunk_SetMark
The server calls this after the level and game VM have been loaded
===================
*/
void Hunk_SetMark( void )
/*
=================
Hunk_ClearToMark
The client calls this before starting a vid_restart or snd_restart
=================
*/
void Hunk_ClearToMark( void )
Set's a offset to the games allocated memory positions. Used to optimize easure?
static void Hunk_SwapBanks( void )
{
hunkUsed_t *swap;
// can't swap banks if there is any temp already allocated
if ( hunk_temp->temp != hunk_temp->permanent )
return;
// if we have a larger highwater mark on this side, start making
// our permanent allocations here and use the other side for temp
if ( hunk_temp->tempHighwater - hunk_temp->permanent
> hunk_permanent->tempHighwater - hunk_permanent->permanent )
{
swap = hunk_temp;
hunk_temp = hunk_permanent;
hunk_permanent = swap;
}
}
Fascinating function
/*
=================
Hunk_Alloc
Allocate permanent (until the hunk is cleared) memory
=================
*/
#ifdef HUNK_DEBUG
void *Hunk_AllocDebug( int size, ha_pref preference, const char *label, const char *file, int line )
#else
void *Hunk_Alloc( int size, ha_pref preference )
#endif
{
// can't do preference if there is any temp allocated
if (preference == h_dontcare || hunk_temp->temp != hunk_temp->permanent) {
Hunk_SwapBanks();
} else {
if (preference == h_low && hunk_permanent != &hunk_low) {
Hunk_SwapBanks();
} else if (preference == h_high && hunk_permanent != &hunk_high) {
Hunk_SwapBanks();
}
}
What is happening,