mirror of
https://github.com/fabiangreffrath/woof.git
synced 2025-09-22 03:12:00 -04:00
simplify and adapt z_zone.c to DSDA-Doom (#620)
* simplify and adapt z_zone.c to DSDA-Doom * remove the INSTRUMENTED macro * remove Z_Init() and Z_CheckHeap() * remove PU_LOCKED * eplicitly free all cached memory blocks on level setup * assure proper pointer alignment * fix headers * reorder struct memblock, decrease padding * add back historic changelogs
This commit is contained in:
parent
5cbd8e49d1
commit
0e6e346b32
@ -48,7 +48,6 @@ if(NOT WIN32)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Toggle-able defines added at compile-time.
|
# Toggle-able defines added at compile-time.
|
||||||
option("${PROJECT_NAME}_INSTRUMENTED" "Enable memory allocation statistics" OFF)
|
|
||||||
option("${PROJECT_NAME}_RANGECHECK" "Enable bounds-checking of performance-sensitive functions" ON)
|
option("${PROJECT_NAME}_RANGECHECK" "Enable bounds-checking of performance-sensitive functions" ON)
|
||||||
option("${PROJECT_NAME}_STRICT" "Prefer original MBF code paths over demo compatiblity with PrBoom+" OFF)
|
option("${PROJECT_NAME}_STRICT" "Prefer original MBF code paths over demo compatiblity with PrBoom+" OFF)
|
||||||
|
|
||||||
|
@ -178,8 +178,6 @@ static void MissionSet(void)
|
|||||||
|
|
||||||
void D_DoomMain(void)
|
void D_DoomMain(void)
|
||||||
{
|
{
|
||||||
Z_Init();
|
|
||||||
|
|
||||||
//SetupMission(MissionSet);
|
//SetupMission(MissionSet);
|
||||||
MissionSet();
|
MissionSet();
|
||||||
|
|
||||||
|
@ -176,9 +176,6 @@ endif()
|
|||||||
#
|
#
|
||||||
# Our defines are not namespaced, so we pass them at compile-time instead of
|
# Our defines are not namespaced, so we pass them at compile-time instead of
|
||||||
# using config.h.
|
# using config.h.
|
||||||
if("${${PROJECT_NAME}_INSTRUMENTED}")
|
|
||||||
target_compile_definitions(woof PRIVATE INSTRUMENTED)
|
|
||||||
endif()
|
|
||||||
if("${${PROJECT_NAME}_RANGECHECK}")
|
if("${${PROJECT_NAME}_RANGECHECK}")
|
||||||
target_compile_definitions(woof PRIVATE RANGECHECK)
|
target_compile_definitions(woof PRIVATE RANGECHECK)
|
||||||
endif()
|
endif()
|
||||||
|
@ -1648,8 +1648,6 @@ void D_DoomMain(void)
|
|||||||
|
|
||||||
setbuf(stdout,NULL);
|
setbuf(stdout,NULL);
|
||||||
|
|
||||||
Z_Init(); // 1/18/98 killough: start up memory stuff first
|
|
||||||
|
|
||||||
I_AtExitPrio(I_QuitFirst, true, "I_QuitFirst", exit_priority_first);
|
I_AtExitPrio(I_QuitFirst, true, "I_QuitFirst", exit_priority_first);
|
||||||
I_AtExitPrio(I_QuitLast, false, "I_QuitLast", exit_priority_last);
|
I_AtExitPrio(I_QuitLast, false, "I_QuitLast", exit_priority_last);
|
||||||
I_AtExitPrio(I_Quit, true, "I_Quit", exit_priority_last);
|
I_AtExitPrio(I_Quit, true, "I_Quit", exit_priority_last);
|
||||||
|
11
src/g_game.c
11
src/g_game.c
@ -716,7 +716,6 @@ static void G_DoLoadLevel(void)
|
|||||||
P_SetupLevel (gameepisode, gamemap, 0, gameskill);
|
P_SetupLevel (gameepisode, gamemap, 0, gameskill);
|
||||||
displayplayer = consoleplayer; // view the guy you are playing
|
displayplayer = consoleplayer; // view the guy you are playing
|
||||||
gameaction = ga_nothing;
|
gameaction = ga_nothing;
|
||||||
Z_CheckHeap();
|
|
||||||
|
|
||||||
// clear cmd building stuff
|
// clear cmd building stuff
|
||||||
memset (gamekeydown, 0, sizeof(gamekeydown));
|
memset (gamekeydown, 0, sizeof(gamekeydown));
|
||||||
@ -1759,17 +1758,11 @@ static void G_DoSaveGame(void)
|
|||||||
// killough 11/98: save revenant tracer state
|
// killough 11/98: save revenant tracer state
|
||||||
*save_p++ = (gametic-basetic) & 255;
|
*save_p++ = (gametic-basetic) & 255;
|
||||||
|
|
||||||
// killough 3/22/98: add Z_CheckHeap after each call to ensure consistency
|
|
||||||
Z_CheckHeap();
|
|
||||||
P_ArchivePlayers();
|
P_ArchivePlayers();
|
||||||
Z_CheckHeap();
|
|
||||||
P_ArchiveWorld();
|
P_ArchiveWorld();
|
||||||
Z_CheckHeap();
|
|
||||||
P_ArchiveThinkers();
|
P_ArchiveThinkers();
|
||||||
Z_CheckHeap();
|
|
||||||
P_ArchiveSpecials();
|
P_ArchiveSpecials();
|
||||||
P_ArchiveRNG(); // killough 1/18/98: save RNG information
|
P_ArchiveRNG(); // killough 1/18/98: save RNG information
|
||||||
Z_CheckHeap();
|
|
||||||
P_ArchiveMap(); // killough 1/22/98: save automap information
|
P_ArchiveMap(); // killough 1/22/98: save automap information
|
||||||
|
|
||||||
*save_p++ = 0xe6; // consistancy marker
|
*save_p++ = 0xe6; // consistancy marker
|
||||||
@ -1792,8 +1785,6 @@ static void G_DoSaveGame(void)
|
|||||||
|
|
||||||
length = save_p - savebuffer;
|
length = save_p - savebuffer;
|
||||||
|
|
||||||
Z_CheckHeap();
|
|
||||||
|
|
||||||
if (!M_WriteFile(name, savebuffer, length))
|
if (!M_WriteFile(name, savebuffer, length))
|
||||||
dprintf("%s", errno ? strerror(errno) : "Could not save game: Error unknown");
|
dprintf("%s", errno ? strerror(errno) : "Could not save game: Error unknown");
|
||||||
else
|
else
|
||||||
@ -1969,8 +1960,6 @@ static void G_DoLoadGame(void)
|
|||||||
// draw the pattern into the back screen
|
// draw the pattern into the back screen
|
||||||
R_FillBackScreen();
|
R_FillBackScreen();
|
||||||
|
|
||||||
Z_CheckHeap();
|
|
||||||
|
|
||||||
// killough 12/98: support -recordfrom and -loadgame -playdemo
|
// killough 12/98: support -recordfrom and -loadgame -playdemo
|
||||||
if (!command_loadgame)
|
if (!command_loadgame)
|
||||||
singledemo = false; // Clear singledemo flag if loading from menu
|
singledemo = false; // Clear singledemo flag if loading from menu
|
||||||
|
@ -1669,8 +1669,6 @@ void I_ResetScreen(void)
|
|||||||
WI_DrawBackground();
|
WI_DrawBackground();
|
||||||
V_CopyRect(0, 0, 1, SCREENWIDTH, SCREENHEIGHT, 0, 0, 0);
|
V_CopyRect(0, 0, 1, SCREENWIDTH, SCREENHEIGHT, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Z_CheckHeap();
|
|
||||||
|
|
||||||
M_ResetSetupMenuVideo();
|
M_ResetSetupMenuVideo();
|
||||||
}
|
}
|
||||||
@ -1705,8 +1703,6 @@ void I_InitGraphics(void)
|
|||||||
|
|
||||||
I_InitGraphicsMode(); // killough 10/98
|
I_InitGraphicsMode(); // killough 10/98
|
||||||
|
|
||||||
Z_CheckHeap();
|
|
||||||
|
|
||||||
M_ResetSetupMenuVideo();
|
M_ResetSetupMenuVideo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,10 +84,6 @@ static void cheat_rate();
|
|||||||
static void cheat_buddha();
|
static void cheat_buddha();
|
||||||
static void cheat_spechits();
|
static void cheat_spechits();
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
static void cheat_printstats(); // killough 8/23/98
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void cheat_autoaim(); // killough 7/19/98
|
static void cheat_autoaim(); // killough 7/19/98
|
||||||
static void cheat_tst();
|
static void cheat_tst();
|
||||||
static void cheat_showfps(); // [FG] FPS counter widget
|
static void cheat_showfps(); // [FG] FPS counter widget
|
||||||
@ -274,11 +270,6 @@ struct cheat_s cheat[] = {
|
|||||||
{"nc", NULL, not_net | not_demo | beta_only,
|
{"nc", NULL, not_net | not_demo | beta_only,
|
||||||
cheat_noclip },
|
cheat_noclip },
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
{"stat", NULL, always,
|
|
||||||
cheat_printstats},
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// [FG] FPS counter widget
|
// [FG] FPS counter widget
|
||||||
{"showfps", NULL, always,
|
{"showfps", NULL, always,
|
||||||
cheat_showfps},
|
cheat_showfps},
|
||||||
@ -288,14 +279,6 @@ struct cheat_s cheat[] = {
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
static void cheat_printstats() // killough 8/23/98
|
|
||||||
{
|
|
||||||
if (!(printstats=!printstats))
|
|
||||||
plyr->message = "Memory stats off";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// [FG] FPS counter widget
|
// [FG] FPS counter widget
|
||||||
static void cheat_showfps()
|
static void cheat_showfps()
|
||||||
{
|
{
|
||||||
|
@ -717,8 +717,6 @@ int main(int argc, char *argv[])
|
|||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Z_Init();
|
|
||||||
|
|
||||||
infile_len = M_ReadFile(argv[1], &infile);
|
infile_len = M_ReadFile(argv[1], &infile);
|
||||||
|
|
||||||
src = mem_fopen_read(infile, infile_len);
|
src = mem_fopen_read(infile, infile_len);
|
||||||
|
@ -1528,7 +1528,8 @@ void P_SetupLevel(int episode, int map, int playermask, skill_t skill)
|
|||||||
// Make sure all sounds are stopped before Z_FreeTags.
|
// Make sure all sounds are stopped before Z_FreeTags.
|
||||||
S_Start();
|
S_Start();
|
||||||
|
|
||||||
Z_FreeTags(PU_LEVEL, PU_PURGELEVEL-1);
|
Z_FreeTag(PU_LEVEL);
|
||||||
|
Z_FreeTag(PU_CACHE);
|
||||||
|
|
||||||
P_InitThinkers();
|
P_InitThinkers();
|
||||||
|
|
||||||
|
724
src/z_zone.c
724
src/z_zone.c
@ -35,670 +35,176 @@
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
#include "doomstat.h"
|
#include "i_system.h"
|
||||||
#include "m_argv.h"
|
|
||||||
|
|
||||||
// Uncomment this to see real-time memory allocation
|
|
||||||
// statistics, to and enable extra debugging features
|
|
||||||
//#define INSTRUMENTED
|
|
||||||
|
|
||||||
// Uncomment this to exhaustively run memory checks
|
|
||||||
// while the game is running (this is EXTREMELY slow).
|
|
||||||
// Only useful if INSTRUMENTED is also defined.
|
|
||||||
//#define CHECKHEAP
|
|
||||||
|
|
||||||
// Uncomment this to perform id checks on zone blocks,
|
|
||||||
// to detect corrupted and illegally freed blocks
|
|
||||||
#define ZONEIDCHECK
|
|
||||||
|
|
||||||
// Tunables
|
|
||||||
|
|
||||||
// Alignment of zone memory (benefit may be negated by HEADER_SIZE, CHUNK_SIZE)
|
|
||||||
#define CACHE_ALIGN 32
|
|
||||||
|
|
||||||
// size of block header
|
|
||||||
//#define HEADER_SIZE 32
|
|
||||||
|
|
||||||
// Minimum chunk size at which blocks are allocated
|
// Minimum chunk size at which blocks are allocated
|
||||||
#define CHUNK_SIZE 32
|
#define CHUNK_SIZE sizeof(void *)
|
||||||
|
|
||||||
// Minimum size a block must be to become part of a split
|
|
||||||
#define MIN_BLOCK_SPLIT (1024)
|
|
||||||
|
|
||||||
// How much RAM to leave aside for other libraries
|
|
||||||
#define LEAVE_ASIDE (128*1024)
|
|
||||||
|
|
||||||
// Minimum RAM machine is assumed to have
|
|
||||||
#define MIN_RAM (7*1024*1024)
|
|
||||||
|
|
||||||
// [FG] allocate 64 MiB by default
|
|
||||||
#define DEF_RAM (64*1024*1024)
|
|
||||||
|
|
||||||
// Amount to subtract when retrying failed attempts to allocate initial pool
|
|
||||||
#define RETRY_AMOUNT (256*1024)
|
|
||||||
|
|
||||||
// signature for block header
|
// signature for block header
|
||||||
#define ZONEID 0x931d4a11
|
#define ZONEID 0x931d4a11
|
||||||
|
|
||||||
// Number of mallocs & frees kept in history buffer (must be a power of 2)
|
|
||||||
#define ZONE_HISTORY 4
|
|
||||||
|
|
||||||
// End Tunables
|
|
||||||
|
|
||||||
typedef struct memblock {
|
typedef struct memblock {
|
||||||
|
|
||||||
#ifdef ZONEIDCHECK
|
|
||||||
unsigned id;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct memblock *next,*prev;
|
struct memblock *next,*prev;
|
||||||
size_t size;
|
size_t size;
|
||||||
void **user;
|
void **user;
|
||||||
unsigned char tag,vm;
|
unsigned id;
|
||||||
|
int tag;
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
unsigned short extra;
|
|
||||||
const char *file;
|
|
||||||
int line;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} memblock_t;
|
} memblock_t;
|
||||||
|
|
||||||
/* size of block header
|
|
||||||
* cph - base on sizeof(memblock_t), which can be larger than CHUNK_SIZE on
|
|
||||||
* 64bit architectures */
|
|
||||||
static const size_t HEADER_SIZE = (sizeof(memblock_t)+CHUNK_SIZE-1) & ~(CHUNK_SIZE-1);
|
static const size_t HEADER_SIZE = (sizeof(memblock_t)+CHUNK_SIZE-1) & ~(CHUNK_SIZE-1);
|
||||||
|
|
||||||
static memblock_t *rover; // roving pointer to memory blocks
|
|
||||||
static memblock_t *zone; // pointer to first block
|
|
||||||
static memblock_t *zonebase; // pointer to entire zone memory
|
|
||||||
static size_t zonebase_size; // zone memory allocated size
|
|
||||||
static memblock_t *blockbytag[PU_MAX];
|
static memblock_t *blockbytag[PU_MAX];
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
|
|
||||||
// statistics for evaluating performance
|
|
||||||
static size_t free_memory;
|
|
||||||
static size_t active_memory;
|
|
||||||
static size_t purgable_memory;
|
|
||||||
static size_t inactive_memory;
|
|
||||||
static size_t virtual_memory;
|
|
||||||
|
|
||||||
int printstats; // killough 8/23/98
|
|
||||||
|
|
||||||
void Z_PrintStats(void) // Print allocation statistics
|
|
||||||
{
|
|
||||||
if (printstats)
|
|
||||||
{
|
|
||||||
unsigned long total_memory = free_memory + active_memory +
|
|
||||||
purgable_memory + inactive_memory +
|
|
||||||
virtual_memory;
|
|
||||||
double s = 100.0 / total_memory;
|
|
||||||
|
|
||||||
dprintf("%-5lu\t%6.01f%%\tstatic\n"
|
|
||||||
"%-5lu\t%6.01f%%\tpurgable\n"
|
|
||||||
"%-5lu\t%6.01f%%\tfree\n"
|
|
||||||
"%-5lu\t%6.01f%%\tfragmentary\n"
|
|
||||||
"%-5lu\t%6.01f%%\tvirtual\n"
|
|
||||||
"%-5lu\t\ttotal\n",
|
|
||||||
active_memory,
|
|
||||||
active_memory*s,
|
|
||||||
purgable_memory,
|
|
||||||
purgable_memory*s,
|
|
||||||
free_memory,
|
|
||||||
free_memory*s,
|
|
||||||
inactive_memory,
|
|
||||||
inactive_memory*s,
|
|
||||||
virtual_memory,
|
|
||||||
virtual_memory*s,
|
|
||||||
total_memory
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
|
|
||||||
// killough 4/26/98: Add history information
|
|
||||||
|
|
||||||
enum {malloc_history, free_history, NUM_HISTORY_TYPES};
|
|
||||||
|
|
||||||
static const char *file_history[NUM_HISTORY_TYPES][ZONE_HISTORY];
|
|
||||||
static int line_history[NUM_HISTORY_TYPES][ZONE_HISTORY];
|
|
||||||
static int history_index[NUM_HISTORY_TYPES];
|
|
||||||
static const char *const desc[NUM_HISTORY_TYPES] = {"malloc()'s", "free()'s"};
|
|
||||||
|
|
||||||
void Z_DumpHistory(char *buf)
|
|
||||||
{
|
|
||||||
int i,j;
|
|
||||||
char s[1024];
|
|
||||||
strcat(buf,"\n");
|
|
||||||
for (i=0;i<NUM_HISTORY_TYPES;i++)
|
|
||||||
{
|
|
||||||
sprintf(s,"\nLast several %s:\n\n", desc[i]);
|
|
||||||
strcat(buf,s);
|
|
||||||
for (j=0; j<ZONE_HISTORY; j++)
|
|
||||||
{
|
|
||||||
int k = (history_index[i]-j-1) & (ZONE_HISTORY-1);
|
|
||||||
if (file_history[i][k])
|
|
||||||
{
|
|
||||||
sprintf(s, "File: %s, Line: %d\n", file_history[i][k],
|
|
||||||
line_history[i][k]);
|
|
||||||
strcat(buf,s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
void Z_DumpHistory(char *buf)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void Z_Close(void)
|
|
||||||
{
|
|
||||||
free(zonebase);
|
|
||||||
zone = rover = zonebase = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Z_Init(void)
|
|
||||||
{
|
|
||||||
// haleyjd: -heapsize support
|
|
||||||
int p, mb_size;
|
|
||||||
size_t size = DEF_RAM; // [FG] allocate 32 MiB by default
|
|
||||||
|
|
||||||
p = M_CheckParm("-heapsize");
|
|
||||||
|
|
||||||
// [FG] support Chocolate Doom's -mb parameter
|
|
||||||
if (!p)
|
|
||||||
{
|
|
||||||
p = M_CheckParm("-mb");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(p && ++p < myargc)
|
|
||||||
{
|
|
||||||
mb_size = atoi(myargv[p]);
|
|
||||||
size = (size_t)(mb_size * 1024 * 1024);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size < MIN_RAM) // If less than MIN_RAM, assume MIN_RAM anyway
|
|
||||||
size = MIN_RAM;
|
|
||||||
|
|
||||||
size -= LEAVE_ASIDE; // Leave aside some for other libraries
|
|
||||||
|
|
||||||
assert(HEADER_SIZE >= sizeof(memblock_t) && MIN_RAM > LEAVE_ASIDE);
|
|
||||||
|
|
||||||
I_AtExitPrio(Z_Close, true, "Z_Close", exit_priority_verylast); // exit handler
|
|
||||||
|
|
||||||
size = (size+CHUNK_SIZE-1) & ~(CHUNK_SIZE-1); // round to chunk size
|
|
||||||
|
|
||||||
// Allocate the memory
|
|
||||||
|
|
||||||
while (!(zonebase=malloc(zonebase_size=size + HEADER_SIZE + CACHE_ALIGN)))
|
|
||||||
if (size < (MIN_RAM-LEAVE_ASIDE < RETRY_AMOUNT ? RETRY_AMOUNT :
|
|
||||||
MIN_RAM-LEAVE_ASIDE))
|
|
||||||
I_Error("Z_Init: failed on allocation of %lu bytes",(unsigned long)
|
|
||||||
zonebase_size);
|
|
||||||
else
|
|
||||||
size -= RETRY_AMOUNT;
|
|
||||||
|
|
||||||
// Align on cache boundary
|
|
||||||
|
|
||||||
zone = (memblock_t *) ((char *) zonebase + CACHE_ALIGN -
|
|
||||||
((uintptr_t) zonebase & (CACHE_ALIGN-1)));
|
|
||||||
|
|
||||||
rover = zone; // Rover points to base of zone mem
|
|
||||||
zone->next = zone->prev = zone; // Single node
|
|
||||||
zone->size = size; // All memory in one block
|
|
||||||
zone->tag = PU_FREE; // A free block
|
|
||||||
zone->vm = 0;
|
|
||||||
|
|
||||||
#ifdef ZONEIDCHECK
|
|
||||||
zone->id = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
free_memory = size;
|
|
||||||
inactive_memory = zonebase_size - size;
|
|
||||||
active_memory = purgable_memory = 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Z_Malloc
|
// Z_Malloc
|
||||||
// You can pass a NULL user if the tag is < PU_PURGELEVEL.
|
// You can pass a NULL user if the tag is < PU_CACHE.
|
||||||
|
|
||||||
void *(Z_Malloc)(size_t size, int tag, void **user, const char *file, int line)
|
void *Z_Malloc(size_t size, int tag, void **user)
|
||||||
{
|
{
|
||||||
register memblock_t *block;
|
memblock_t *block = NULL;
|
||||||
memblock_t *start;
|
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
size_t size_orig = size;
|
|
||||||
#ifdef CHECKHEAP
|
|
||||||
Z_CheckHeap();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
file_history[malloc_history][history_index[malloc_history]] = file;
|
|
||||||
line_history[malloc_history][history_index[malloc_history]++] = line;
|
|
||||||
history_index[malloc_history] &= ZONE_HISTORY-1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ZONEIDCHECK
|
if (tag == PU_CACHE && !user)
|
||||||
if(tag >= PU_PURGELEVEL && !user)
|
I_Error ("Z_Malloc: An owner is required for purgable blocks");
|
||||||
I_Error("Z_Malloc: an owner is required for purgable blocks\n"
|
|
||||||
"Source: %s:%d", file, line);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(!size)
|
if (!size)
|
||||||
return user ? *user = NULL : NULL; // malloc(0) returns NULL
|
return user ? *user = NULL : NULL; // malloc(0) returns NULL
|
||||||
|
|
||||||
size = (size+CHUNK_SIZE-1) & ~(CHUNK_SIZE-1); // round to chunk size
|
|
||||||
|
|
||||||
block = rover;
|
|
||||||
|
|
||||||
if(block->prev->tag == PU_FREE)
|
|
||||||
block = block->prev;
|
|
||||||
|
|
||||||
start = block;
|
|
||||||
|
|
||||||
// haleyjd 06/17/08: import from EE:
|
while (!(block = malloc(size + HEADER_SIZE)))
|
||||||
// the first if() inside the loop below contains cph's memory
|
{
|
||||||
// purging efficiency fix
|
if (!blockbytag[PU_CACHE])
|
||||||
|
I_Error ("Z_Malloc: Failure trying to allocate %lu bytes", (unsigned long) size);
|
||||||
|
Z_FreeTag(PU_CACHE);
|
||||||
|
}
|
||||||
|
|
||||||
do
|
if (!blockbytag[tag])
|
||||||
{
|
{
|
||||||
// Free purgable blocks; replacement is roughly FIFO
|
blockbytag[tag] = block;
|
||||||
if(block->tag >= PU_PURGELEVEL)
|
block->next = block->prev = block;
|
||||||
{
|
}
|
||||||
start = block->prev;
|
else
|
||||||
Z_Free((char *) block + HEADER_SIZE);
|
{
|
||||||
/* cph - If start->next == block, we did not merge with the previous
|
blockbytag[tag]->prev->next = block;
|
||||||
* If !=, we did, so we continue from start.
|
block->prev = blockbytag[tag]->prev;
|
||||||
* Important: we've reset start!
|
block->next = blockbytag[tag];
|
||||||
*/
|
blockbytag[tag]->prev = block;
|
||||||
if(start->next == block)
|
}
|
||||||
start = start->next;
|
|
||||||
else
|
|
||||||
block = start;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(block->tag == PU_FREE && block->size >= size) // First-fit
|
|
||||||
{
|
|
||||||
size_t extra = block->size - size;
|
|
||||||
if(extra >= MIN_BLOCK_SPLIT + HEADER_SIZE)
|
|
||||||
{
|
|
||||||
memblock_t *newb =
|
|
||||||
(memblock_t *)((char *) block + HEADER_SIZE + size);
|
|
||||||
|
|
||||||
(newb->next = block->next)->prev = newb;
|
block->size = size;
|
||||||
(newb->prev = block)->next = newb; // Split up block
|
block->id = ZONEID; // signature required in block header
|
||||||
block->size = size;
|
block->tag = tag; // tag
|
||||||
newb->size = extra - HEADER_SIZE;
|
block->user = user; // user
|
||||||
newb->tag = PU_FREE;
|
block = (memblock_t *)((char *) block + HEADER_SIZE);
|
||||||
newb->vm = 0;
|
if (user) // if there is a user
|
||||||
|
*user = block; // set user to point to new block
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
inactive_memory += HEADER_SIZE;
|
|
||||||
free_memory -= HEADER_SIZE;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
rover = block->next; // set roving pointer for next search
|
return block;
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
inactive_memory += block->extra = block->size - size_orig;
|
|
||||||
if(tag >= PU_PURGELEVEL)
|
|
||||||
purgable_memory += size_orig;
|
|
||||||
else
|
|
||||||
active_memory += size_orig;
|
|
||||||
free_memory -= block->size;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
allocated:
|
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
block->file = file;
|
|
||||||
block->line = line;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ZONEIDCHECK
|
|
||||||
block->id = ZONEID; // signature required in block header
|
|
||||||
#endif
|
|
||||||
block->tag = tag; // tag
|
|
||||||
block->user = user; // user
|
|
||||||
block = (memblock_t *)((char *) block + HEADER_SIZE);
|
|
||||||
if(user) // if there is a user
|
|
||||||
*user = block; // set user to point to new block
|
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
Z_PrintStats(); // print memory allocation stats
|
|
||||||
// scramble memory -- weed out any bugs
|
|
||||||
memset(block, gametic & 0xff, size);
|
|
||||||
#endif
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while ((block = block->next) != start); // detect cycles as failure
|
|
||||||
|
|
||||||
// We've run out of physical memory, or so we think.
|
|
||||||
// Although less efficient, we'll just use ordinary malloc.
|
|
||||||
// This will squeeze the remaining juice out of this machine
|
|
||||||
// and start cutting into virtual memory if it has it.
|
|
||||||
|
|
||||||
while(!(block = malloc(size + HEADER_SIZE)))
|
|
||||||
{
|
|
||||||
if(!blockbytag[PU_CACHE])
|
|
||||||
I_Error("Z_Malloc: Failure trying to allocate %lu bytes"
|
|
||||||
"\nSource: %s:%d",(unsigned long) size, file, line);
|
|
||||||
Z_FreeTags(PU_CACHE, PU_CACHE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if((block->next = blockbytag[tag]))
|
|
||||||
block->next->prev = (memblock_t *) &block->next;
|
|
||||||
blockbytag[tag] = block;
|
|
||||||
block->prev = (memblock_t *) &blockbytag[tag];
|
|
||||||
block->vm = 1;
|
|
||||||
|
|
||||||
// haleyjd: cph's virtual memory error fix
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
virtual_memory += size + HEADER_SIZE;
|
|
||||||
|
|
||||||
// haleyjd 06/17/08: Import from EE:
|
|
||||||
// Big problem: extra wasn't being initialized for vm
|
|
||||||
// blocks. This caused the memset used to randomize freed memory when
|
|
||||||
// INSTRUMENTED is defined to stomp all over the C heap.
|
|
||||||
block->extra = 0;
|
|
||||||
#endif
|
|
||||||
/* cph - the next line was lost in the #ifdef above, and also added an
|
|
||||||
* extra HEADER_SIZE to block->size, which was incorrect */
|
|
||||||
block->size = size;
|
|
||||||
goto allocated;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void (Z_Free)(void *p, const char *file, int line)
|
void Z_Free(void *p)
|
||||||
{
|
{
|
||||||
#ifdef INSTRUMENTED
|
memblock_t *block = (memblock_t *)((char *) p - HEADER_SIZE);
|
||||||
#ifdef CHECKHEAP
|
|
||||||
Z_CheckHeap();
|
|
||||||
#endif
|
|
||||||
file_history[free_history][history_index[free_history]] = file;
|
|
||||||
line_history[free_history][history_index[free_history]++] = line;
|
|
||||||
history_index[free_history] &= ZONE_HISTORY-1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(p)
|
|
||||||
{
|
|
||||||
memblock_t *other, *block = (memblock_t *)((char *) p - HEADER_SIZE);
|
|
||||||
|
|
||||||
#ifdef ZONEIDCHECK
|
|
||||||
if(block->id != ZONEID)
|
|
||||||
I_Error("Z_Free: freed a pointer without ZONEID\n"
|
|
||||||
"Source: %s:%d"
|
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
if (!p)
|
||||||
"\nSource of malloc: %s:%d"
|
return;
|
||||||
, file, line, block->file, block->line
|
|
||||||
#else
|
|
||||||
, file, line
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
block->id = 0; // Nullify id so another free fails
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
if (block->id != ZONEID)
|
||||||
// scramble memory -- weed out any bugs
|
I_Error("Z_Free: freed a pointer without ZONEID");
|
||||||
memset(p, gametic & 0xff, block->size - block->extra);
|
block->id = 0; // Nullify id so another free fails
|
||||||
#endif
|
|
||||||
|
|
||||||
if(block->user) // Nullify user if one exists
|
if (block->user) // Nullify user if one exists
|
||||||
*block->user = NULL;
|
*block->user = NULL;
|
||||||
|
|
||||||
if(block->vm)
|
|
||||||
{
|
|
||||||
if((*(memblock_t **) block->prev = block->next))
|
|
||||||
block->next->prev = block->prev;
|
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
if (block == block->next)
|
||||||
virtual_memory -= block->size;
|
blockbytag[block->tag] = NULL;
|
||||||
#endif
|
else
|
||||||
// free(block); // [FG] TODO
|
if (blockbytag[block->tag] == block)
|
||||||
}
|
blockbytag[block->tag] = block->next;
|
||||||
else
|
block->prev->next = block->next;
|
||||||
{
|
block->next->prev = block->prev;
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
free(block);
|
||||||
free_memory += block->size;
|
|
||||||
inactive_memory -= block->extra;
|
|
||||||
if(block->tag >= PU_PURGELEVEL)
|
|
||||||
purgable_memory -= block->size - block->extra;
|
|
||||||
else
|
|
||||||
active_memory -= block->size - block->extra;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
block->tag = PU_FREE; // Mark block freed
|
|
||||||
|
|
||||||
if(block != zone)
|
|
||||||
{
|
|
||||||
other = block->prev; // Possibly merge with previous block
|
|
||||||
if(other->tag == PU_FREE)
|
|
||||||
{
|
|
||||||
if(rover == block) // Move back rover if it points at block
|
|
||||||
rover = other;
|
|
||||||
(other->next = block->next)->prev = other;
|
|
||||||
other->size += block->size + HEADER_SIZE;
|
|
||||||
block = other;
|
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
inactive_memory -= HEADER_SIZE;
|
|
||||||
free_memory += HEADER_SIZE;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
other = block->next; // Possibly merge with next block
|
|
||||||
if(other->tag == PU_FREE && other != zone)
|
|
||||||
{
|
|
||||||
if(rover == other) // Move back rover if it points at next block
|
|
||||||
rover = block;
|
|
||||||
(block->next = other->next)->prev = block;
|
|
||||||
block->size += other->size + HEADER_SIZE;
|
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
inactive_memory -= HEADER_SIZE;
|
|
||||||
free_memory += HEADER_SIZE;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
Z_PrintStats(); // print memory allocation stats
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void (Z_FreeTags)(int lowtag, int hightag, const char *file, int line)
|
void Z_FreeTag(int tag)
|
||||||
{
|
{
|
||||||
memblock_t *block = zone;
|
memblock_t *block, *end_block;
|
||||||
|
|
||||||
if(lowtag <= PU_FREE)
|
|
||||||
lowtag = PU_FREE+1;
|
|
||||||
|
|
||||||
// haleyjd: code inside this do loop has been updated with
|
if (tag < 0 || tag >= PU_MAX)
|
||||||
// cph's fix for memory wastage
|
I_Error("Z_FreeTag: Tag %i does not exist", tag);
|
||||||
|
|
||||||
do // Scan through list, searching for tags in range
|
|
||||||
{
|
|
||||||
if(block->tag >= lowtag && block->tag <= hightag)
|
|
||||||
{
|
|
||||||
memblock_t *prev = block->prev, *cur = block;;
|
|
||||||
(Z_Free)((char *) block + HEADER_SIZE, file, line);
|
|
||||||
/* cph - be more careful here, we were skipping blocks!
|
|
||||||
* If the current block was not merged with the previous,
|
|
||||||
* cur is still a valid pointer, prev->next == cur, and cur is
|
|
||||||
* already free so skip to the next.
|
|
||||||
* If the current block was merged with the previous,
|
|
||||||
* the next block to analyse is prev->next.
|
|
||||||
* Note that the while() below does the actual step forward
|
|
||||||
*/
|
|
||||||
block = (prev->next == cur) ? cur : prev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while((block = block->next) != zone);
|
|
||||||
|
|
||||||
if(hightag > PU_CACHE)
|
block = blockbytag[tag];
|
||||||
hightag = PU_CACHE;
|
if (!block)
|
||||||
|
return;
|
||||||
for(; lowtag <= hightag; ++lowtag)
|
end_block = block->prev;
|
||||||
{
|
while (1)
|
||||||
for(block = blockbytag[lowtag], blockbytag[lowtag] = NULL; block;)
|
{
|
||||||
{
|
memblock_t *next = block->next;
|
||||||
memblock_t *next = block->next;
|
Z_Free((char *) block + HEADER_SIZE);
|
||||||
|
if (block == end_block)
|
||||||
#ifdef ZONEIDCHECK
|
break;
|
||||||
if(block->id != ZONEID)
|
block = next; // Advance to next block
|
||||||
I_Error("Z_FreeTags: Changed a tag without ZONEID\n"
|
}
|
||||||
"Source: %s:%d"
|
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
"\nSource of malloc: %s:%d"
|
|
||||||
, file, line, block->file, block->line
|
|
||||||
#else
|
|
||||||
, file, line
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
|
|
||||||
block->id = 0; // Nullify id so another free fails
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
virtual_memory -= block->size;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(block->user) // Nullify user if one exists
|
|
||||||
*block->user = NULL;
|
|
||||||
|
|
||||||
free(block); // Free the block
|
|
||||||
|
|
||||||
block = next; // Advance to next block
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void (Z_ChangeTag)(void *ptr, int tag, const char *file, int line)
|
void Z_ChangeTag(void *ptr, int tag)
|
||||||
{
|
{
|
||||||
memblock_t *block = (memblock_t *)((char *) ptr - HEADER_SIZE);
|
memblock_t *block = (memblock_t *)((char *) ptr - HEADER_SIZE);
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
// proff - added sanity check, this can happen when an empty lump is locked
|
||||||
#ifdef CHECKHEAP
|
if (!ptr)
|
||||||
Z_CheckHeap();
|
return;
|
||||||
#endif
|
|
||||||
#endif
|
// proff - do nothing if tag doesn't differ
|
||||||
|
if (tag == block->tag)
|
||||||
|
return;
|
||||||
|
|
||||||
#ifdef ZONEIDCHECK
|
|
||||||
if (block->id != ZONEID)
|
if (block->id != ZONEID)
|
||||||
I_Error ("Z_ChangeTag: Changed a tag without ZONEID"
|
I_Error ("Z_ChangeTag: freed a pointer without ZONEID");
|
||||||
"\nSource: %s:%d"
|
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
if (tag == PU_CACHE && !block->user)
|
||||||
"\nSource of malloc: %s:%d"
|
I_Error ("Z_ChangeTag: an owner is required for purgable blocks\n");
|
||||||
, file, line, block->file, block->line
|
|
||||||
#else
|
|
||||||
, file, line
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
|
|
||||||
if (tag >= PU_PURGELEVEL && !block->user)
|
if (block == block->next)
|
||||||
I_Error ("Z_ChangeTag: an owner is required for purgable blocks\n"
|
blockbytag[block->tag] = NULL;
|
||||||
"Source: %s:%d"
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
"\nSource of malloc: %s:%d"
|
|
||||||
, file, line, block->file, block->line
|
|
||||||
#else
|
|
||||||
, file, line
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif // ZONEIDCHECK
|
|
||||||
|
|
||||||
if (block->vm)
|
|
||||||
{
|
|
||||||
if ((*(memblock_t **) block->prev = block->next))
|
|
||||||
block->next->prev = block->prev;
|
|
||||||
if ((block->next = blockbytag[tag]))
|
|
||||||
block->next->prev = (memblock_t *) &block->next;
|
|
||||||
block->prev = (memblock_t *) &blockbytag[tag];
|
|
||||||
blockbytag[tag] = block;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
if (blockbytag[block->tag] == block)
|
||||||
#ifdef INSTRUMENTED
|
blockbytag[block->tag] = block->next;
|
||||||
if (block->tag < PU_PURGELEVEL && tag >= PU_PURGELEVEL)
|
block->prev->next = block->next;
|
||||||
{
|
block->next->prev = block->prev;
|
||||||
active_memory -= block->size - block->extra;
|
|
||||||
purgable_memory += block->size - block->extra;
|
if (!blockbytag[tag])
|
||||||
}
|
{
|
||||||
else
|
blockbytag[tag] = block;
|
||||||
if (block->tag >= PU_PURGELEVEL && tag < PU_PURGELEVEL)
|
block->next = block->prev = block;
|
||||||
{
|
}
|
||||||
active_memory += block->size - block->extra;
|
else
|
||||||
purgable_memory -= block->size - block->extra;
|
{
|
||||||
}
|
blockbytag[tag]->prev->next = block;
|
||||||
#endif
|
block->prev = blockbytag[tag]->prev;
|
||||||
}
|
block->next = blockbytag[tag];
|
||||||
|
blockbytag[tag]->prev = block;
|
||||||
|
}
|
||||||
|
|
||||||
block->tag = tag;
|
block->tag = tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *(Z_Realloc)(void *ptr, size_t n, int tag, void **user,
|
void *Z_Realloc(void *ptr, size_t n, int tag, void **user)
|
||||||
const char *file, int line)
|
|
||||||
{
|
{
|
||||||
void *p = (Z_Malloc)(n, tag, user, file, line);
|
void *p = Z_Malloc(n, tag, user);
|
||||||
if(ptr)
|
if (ptr)
|
||||||
{
|
{
|
||||||
memblock_t *block = (memblock_t *)((char *)ptr - HEADER_SIZE);
|
memblock_t *block = (memblock_t *)((char *) ptr - HEADER_SIZE);
|
||||||
if(p) // haleyjd 06/17/08: allow to return NULL without crashing
|
memcpy(p, ptr, n <= block->size ? n : block->size);
|
||||||
memcpy(p, ptr, n <= block->size ? n : block->size);
|
Z_Free(ptr);
|
||||||
(Z_Free)(ptr, file, line);
|
if (user) // in case Z_Free nullified same user
|
||||||
if(user) // in case Z_Free nullified same user
|
*user=p;
|
||||||
*user=p;
|
}
|
||||||
}
|
return p;
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *(Z_Calloc)(size_t n1, size_t n2, int tag, void **user,
|
void *Z_Calloc(size_t n1, size_t n2, int tag, void **user)
|
||||||
const char *file, int line)
|
|
||||||
{
|
{
|
||||||
return (n1*=n2) ? memset((Z_Malloc)(n1, tag, user, file, line), 0, n1) : NULL;
|
return
|
||||||
}
|
(n1*=n2) ? memset(Z_Malloc(n1, tag, user), 0, n1) : NULL;
|
||||||
|
|
||||||
char *(Z_Strdup)(const char *s, int tag, void **user,
|
|
||||||
const char *file, int line)
|
|
||||||
{
|
|
||||||
return strcpy((Z_Malloc)(strlen(s)+1, tag, user, file, line), s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void (Z_CheckHeap)(const char *file, int line)
|
|
||||||
{
|
|
||||||
memblock_t *block = zone; // Start at base of zone mem
|
|
||||||
do // Consistency check (last node treated special)
|
|
||||||
{
|
|
||||||
if((block->next != zone &&
|
|
||||||
(memblock_t *)((char *) block+HEADER_SIZE+block->size) != block->next) ||
|
|
||||||
block->next->prev != block || block->prev->next != block)
|
|
||||||
{
|
|
||||||
I_Error("Z_CheckHeap: Block size does not touch the next block\n"
|
|
||||||
"Source: %s:%d"
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
"\nSource of offending block: %s:%d"
|
|
||||||
, file, line, block->file, block->line
|
|
||||||
#else
|
|
||||||
, file, line
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while((block = block->next) != zone);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
43
src/z_zone.h
43
src/z_zone.h
@ -47,43 +47,28 @@
|
|||||||
// ZONE MEMORY
|
// ZONE MEMORY
|
||||||
// PU - purge tags.
|
// PU - purge tags.
|
||||||
|
|
||||||
enum {PU_FREE, PU_STATIC, PU_SOUND, PU_MUSIC, PU_LEVEL, PU_LEVSPEC, PU_CACHE,
|
enum {
|
||||||
/* Must always be last -- killough */ PU_MAX};
|
PU_STATIC,
|
||||||
|
PU_LEVEL,
|
||||||
|
PU_CACHE,
|
||||||
|
/* Must always be last -- killough */
|
||||||
|
PU_MAX
|
||||||
|
};
|
||||||
|
|
||||||
#define PU_PURGELEVEL PU_CACHE /* First purgable tag's level */
|
#define PU_LEVSPEC PU_LEVEL
|
||||||
|
|
||||||
void *(Z_Malloc)(size_t size, int tag, void **ptr, const char *, int);
|
void *Z_Malloc(size_t size, int tag, void **ptr);
|
||||||
void (Z_Free)(void *ptr, const char *, int);
|
void Z_Free(void *ptr);
|
||||||
void (Z_FreeTags)(int lowtag, int hightag, const char *, int);
|
void Z_FreeTag(int tag);
|
||||||
void (Z_ChangeTag)(void *ptr, int tag, const char *, int);
|
void Z_ChangeTag(void *ptr, int tag);
|
||||||
void (Z_Init)(void);
|
void *Z_Calloc(size_t n, size_t n2, int tag, void **user);
|
||||||
void *(Z_Calloc)(size_t n, size_t n2, int tag, void **user, const char *, int);
|
void *Z_Realloc(void *p, size_t n, int tag, void **user);
|
||||||
void *(Z_Realloc)(void *p, size_t n, int tag, void **user, const char *, int);
|
|
||||||
char *(Z_Strdup)(const char *s, int tag, void **user, const char *, int);
|
|
||||||
void (Z_CheckHeap)(const char *,int); // killough 3/22/98: add file/line info
|
|
||||||
void Z_DumpHistory(char *);
|
|
||||||
|
|
||||||
#define Z_Free(a) (Z_Free) (a, __FILE__,__LINE__)
|
|
||||||
#define Z_FreeTags(a,b) (Z_FreeTags) (a,b, __FILE__,__LINE__)
|
|
||||||
#define Z_ChangeTag(a,b) (Z_ChangeTag)(a,b, __FILE__,__LINE__)
|
|
||||||
#define Z_Malloc(a,b,c) (Z_Malloc) (a,b,c, __FILE__,__LINE__)
|
|
||||||
#define Z_Strdup(a,b,c) (Z_Strdup) (a,b,c, __FILE__,__LINE__)
|
|
||||||
#define Z_Calloc(a,b,c,d) (Z_Calloc) (a,b,c,d,__FILE__,__LINE__)
|
|
||||||
#define Z_Realloc(a,b,c,d) (Z_Realloc) (a,b,c,d,__FILE__,__LINE__)
|
|
||||||
#define Z_CheckHeap() (Z_CheckHeap)(__FILE__,__LINE__)
|
|
||||||
|
|
||||||
// dprintf() is already declared in <stdio.h>, define it out of the way
|
// dprintf() is already declared in <stdio.h>, define it out of the way
|
||||||
#define dprintf doomprintf
|
#define dprintf doomprintf
|
||||||
// Doom-style printf
|
// Doom-style printf
|
||||||
void dprintf(const char *, ...) PRINTF_ATTR(1, 2);
|
void dprintf(const char *, ...) PRINTF_ATTR(1, 2);
|
||||||
|
|
||||||
void Z_ZoneHistory(char *);
|
|
||||||
|
|
||||||
#ifdef INSTRUMENTED
|
|
||||||
extern int printstats; // killough 8/23/98
|
|
||||||
void Z_PrintStats(void); // killough 8/23/98
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user