From fa1173ed10de2d41549e909a462fdb5eb6024223 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 14 Feb 2018 22:52:25 +0000 Subject: [PATCH 1/6] Clean up z_zone.h's function protos to look more readable like m_random.h, don't name functions with "2" if not using PARANOIA or ZDEBUG also, Z_Malloc/Calloc/Realloc are now macros of the "Align" versions, regardless of ZDEBUG or not --- src/z_zone.c | 4 ++-- src/z_zone.h | 53 +++++++++++++++++++--------------------------------- 2 files changed, 21 insertions(+), 36 deletions(-) diff --git a/src/z_zone.c b/src/z_zone.c index a28ea87b0..4e9efef4b 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -541,7 +541,7 @@ void Z_CheckHeap(INT32 i) #ifdef PARANOIA void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line) #else -void Z_ChangeTag2(void *ptr, INT32 tag) +void Z_ChangeTag(void *ptr, INT32 tag) #endif { memblock_t *block; @@ -675,7 +675,7 @@ char *Z_StrDup(const char *s) #ifdef PARANOIA void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line) #else -void Z_SetUser2(void *ptr, void **newuser) +void Z_SetUser(void *ptr, void **newuser) #endif { memblock_t *block; diff --git a/src/z_zone.h b/src/z_zone.h index 552fd87ba..baadb44a6 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -62,60 +62,45 @@ void Z_Init(void); void Z_FreeTags(INT32 lowtag, INT32 hightag); void Z_CheckMemCleanup(void); void Z_CheckHeap(INT32 i); -#ifdef PARANOIA -void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line); -#else -void Z_ChangeTag2(void *ptr, INT32 tag); -#endif #ifdef PARANOIA +// This is used to get the local FILE : LINE info from CPP +// prior to really call the function in question. +// +#define Z_ChangeTag(p,t) Z_ChangeTag2(p, t, __FILE__, __LINE__) +#define Z_SetUser(p,u) Z_SetUser2(p, u, __FILE__, __LINE__) +void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line); void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line); #else -void Z_SetUser2(void *ptr, void **newuser); +void Z_ChangeTag(void *ptr, INT32 tag); +void Z_SetUser(void *ptr, void **newuser); #endif #ifdef ZDEBUG -#define Z_Free(p) Z_Free2(p, __FILE__, __LINE__) -void Z_Free2(void *ptr, const char *file, INT32 line); -#define Z_Malloc(s,t,u) Z_Malloc2(s, t, u, 0, __FILE__, __LINE__) -#define Z_MallocAlign(s,t,u,a) Z_Malloc2(s, t, u, a, __FILE__, __LINE__) -void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1); -#define Z_Calloc(s,t,u) Z_Calloc2(s, t, u, 0, __FILE__, __LINE__) -#define Z_CallocAlign(s,t,u,a) Z_Calloc2(s, t, u, a, __FILE__, __LINE__) -void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1); -#define Z_Realloc(p,s,t,u) Z_Realloc2(p, s, t, u, 0, __FILE__, __LINE__) +#define Z_Free(p) Z_Free2(p, __FILE__, __LINE__) +#define Z_MallocAlign(s,t,u,a) Z_Malloc2(s, t, u, a, __FILE__, __LINE__) +#define Z_CallocAlign(s,t,u,a) Z_Calloc2(s, t, u, a, __FILE__, __LINE__) #define Z_ReallocAlign(p,s,t,u,a) Z_Realloc2(p,s, t, u, a, __FILE__, __LINE__) +void Z_Free2(void *ptr, const char *file, INT32 line); +void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1); +void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1); void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(2); #else void Z_Free(void *ptr); void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(1); -#define Z_Malloc(s,t,u) Z_MallocAlign(s, t, u, 0) void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(1); -#define Z_Calloc(s,t,u) Z_CallocAlign(s, t, u, 0) -void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(2) ; -#define Z_Realloc(p, s,t,u) Z_ReallocAlign(p, s, t, u, 0) +void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(2); #endif +#define Z_Malloc(s,t,u) Z_MallocAlign(s, t, u, 0) +#define Z_Calloc(s,t,u) Z_CallocAlign(s, t, u, 0) +#define Z_Realloc(p,s,t,u) Z_ReallocAlign(p, s, t, u, 0) + size_t Z_TagUsage(INT32 tagnum); size_t Z_TagsUsage(INT32 lowtag, INT32 hightag); char *Z_StrDup(const char *in); -// This is used to get the local FILE : LINE info from CPP -// prior to really call the function in question. -// -#ifdef PARANOIA -#define Z_ChangeTag(p,t) Z_ChangeTag2(p, t, __FILE__, __LINE__) -#else -#define Z_ChangeTag(p,t) Z_ChangeTag2(p, t) -#endif - -#ifdef PARANOIA -#define Z_SetUser(p,u) Z_SetUser2(p, u, __FILE__, __LINE__) -#else -#define Z_SetUser(p,u) Z_SetUser2(p, u) -#endif - #define Z_Unlock(p) (void)p #endif From 4383d1fdd2e92898c72cb7a87ea76237ac734d4c Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 14 Feb 2018 23:16:16 +0000 Subject: [PATCH 2/6] added a quick Z_FreeTag function as a shortcut to Z_FreeTags(tag, tag) where both tags are the same --- src/hardware/hw_cache.c | 8 ++++---- src/z_zone.c | 5 +++++ src/z_zone.h | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 78fc31afc..beda40391 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -581,8 +581,8 @@ void HWR_FreeTextureCache(void) // free all hardware-converted graphics cached in the heap // our gool is only the textures since user of the texture is the texture cache - Z_FreeTags(PU_HWRCACHE, PU_HWRCACHE); - Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRCACHE_UNLOCKED); + Z_FreeTag(PU_HWRCACHE); + Z_FreeTag(PU_HWRCACHE_UNLOCKED); // Alam: free the Z_Blocks before freeing it's users @@ -629,8 +629,8 @@ void HWR_SetPalette(RGBA_t *palette) // now flush data texture cache so 32 bit texture are recomputed if (patchformat == GR_RGBA || textureformat == GR_RGBA) { - Z_FreeTags(PU_HWRCACHE, PU_HWRCACHE); - Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRCACHE_UNLOCKED); + Z_FreeTag(PU_HWRCACHE); + Z_FreeTag(PU_HWRCACHE_UNLOCKED); } } diff --git a/src/z_zone.c b/src/z_zone.c index 4e9efef4b..37ab3d546 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -407,6 +407,11 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag) } } +void Z_FreeTag(INT32 tagnum) +{ + Z_FreeTags(tagnum, tagnum); +} + // // Z_CheckMemCleanup // diff --git a/src/z_zone.h b/src/z_zone.h index baadb44a6..57ad158cf 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -59,6 +59,7 @@ #define PU_HWRPATCHINFO_UNLOCKED 103 void Z_Init(void); +void Z_FreeTag(INT32 tagnum); void Z_FreeTags(INT32 lowtag, INT32 hightag); void Z_CheckMemCleanup(void); void Z_CheckHeap(INT32 i); From c5261c1133a20ea893609b2471080dbf12e55d04 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 15 Feb 2018 16:31:05 +0000 Subject: [PATCH 3/6] Z_FreeTag and Z_TagUsage are now both macros of their respective two arg variants --- src/z_zone.c | 12 +----------- src/z_zone.h | 4 ++-- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/z_zone.c b/src/z_zone.c index 37ab3d546..cf56d0baa 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -407,11 +407,6 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag) } } -void Z_FreeTag(INT32 tagnum) -{ - Z_FreeTags(tagnum, tagnum); -} - // // Z_CheckMemCleanup // @@ -610,12 +605,7 @@ size_t Z_TagsUsage(INT32 lowtag, INT32 hightag) return cnt; } -size_t Z_TagUsage(INT32 tagnum) -{ - return Z_TagsUsage(tagnum, tagnum); -} - -void Command_Memfree_f(void) +static void Command_Memfree_f(void) { UINT32 freebytes, totalbytes; diff --git a/src/z_zone.h b/src/z_zone.h index 57ad158cf..b21d951d6 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -59,7 +59,7 @@ #define PU_HWRPATCHINFO_UNLOCKED 103 void Z_Init(void); -void Z_FreeTag(INT32 tagnum); +#define Z_FreeTag(tagnum) Z_FreeTags(tagnum, tagnum) void Z_FreeTags(INT32 lowtag, INT32 hightag); void Z_CheckMemCleanup(void); void Z_CheckHeap(INT32 i); @@ -97,7 +97,7 @@ void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignb #define Z_Calloc(s,t,u) Z_CallocAlign(s, t, u, 0) #define Z_Realloc(p,s,t,u) Z_ReallocAlign(p, s, t, u, 0) -size_t Z_TagUsage(INT32 tagnum); +#define Z_TagUsage(tagnum) Z_TagsUsage(tagnum, tagnum) size_t Z_TagsUsage(INT32 lowtag, INT32 hightag); char *Z_StrDup(const char *in); From afe4178fd7661a1297a32c5b75bf6faf9800d2f4 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 15 Feb 2018 16:53:58 +0000 Subject: [PATCH 4/6] updating comment for Z_TagsUsage in the .c file --- src/z_zone.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/z_zone.c b/src/z_zone.c index cf56d0baa..e28de13fe 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -584,11 +584,12 @@ void Z_ChangeTag(void *ptr, INT32 tag) } /** Calculates memory usage for a given set of tags. + * NOTE: Z_TagUsage is now just a macro of this function. + * * \param lowtag The lowest tag to consider. * \param hightag The highest tag to consider. * \return Number of bytes currently allocated in the heap for the * given tags. - * \sa Z_TagUsage */ size_t Z_TagsUsage(INT32 lowtag, INT32 hightag) { From 5c6755df7f1446430447e3cd83e3d0c8a647f55f Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 15 Feb 2018 22:09:24 +0000 Subject: [PATCH 5/6] Total reorganisation of z_zone.c/h, added doxygen-compatible comments to all functions and additional regular comments where appropriate, changed purge tag macros to an enum list --- src/z_zone.c | 370 +++++++++++++++++++++++++++++++++------------------ src/z_zone.h | 130 +++++++++++------- 2 files changed, 327 insertions(+), 173 deletions(-) diff --git a/src/z_zone.c b/src/z_zone.c index e28de13fe..2c7cf7c71 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -82,6 +82,59 @@ typedef struct memblock_s struct memblock_s *next, *prev; } ATTRPACK memblock_t; +// both the head and tail of the zone memory block list +static memblock_t head; + +// +// Function prototypes +// +static void Command_Memfree_f(void); +#ifdef ZDEBUG +static void Command_Memdump_f(void); +#endif + +// -------------------------- +// Zone memory initialisation +// -------------------------- + +/** Initialises zone memory. + * Used at game startup. + * + * \sa I_GetFreeMem, Command_Memfree_f, Command_Memdump_f + */ +void Z_Init(void) +{ + UINT32 total, memfree; + + memset(&head, 0x00, sizeof(head)); + + head.next = head.prev = &head; + + memfree = I_GetFreeMem(&total)>>20; + CONS_Printf("System memory: %uMB - Free: %uMB\n", total>>20, memfree); + + // Note: This allocates memory. Watch out. + COM_AddCommand("memfree", Command_Memfree_f); + +#ifdef ZDEBUG + COM_AddCommand("memdump", Command_Memdump_f); +#endif +} + + +// ---------------------- +// Zone memory allocation +// ---------------------- + +/** Returns the corresponding memblock_t for a given memory block. + * + * \param ptr A pointer to allocated memory, + * assumed to have been allocated with Z_Malloc/Z_Calloc. + * \param func A string containing the name of the function that called this, + * to be printed if the function I_Errors + * \return A pointer to the memblock_t for the given memory. + * \sa Z_Free, Z_ReallocAlign + */ #ifdef ZDEBUG #define Ptr2Memblock(s, f) Ptr2Memblock2(s, f, __FILE__, __LINE__) static memblock_t *Ptr2Memblock2(void *ptr, const char* func, const char *file, INT32 line) @@ -131,32 +184,12 @@ static memblock_t *Ptr2Memblock(void *ptr, const char* func) } -static memblock_t head; - -static void Command_Memfree_f(void); -#ifdef ZDEBUG -static void Command_Memdump_f(void); -#endif - -void Z_Init(void) -{ - UINT32 total, memfree; - - memset(&head, 0x00, sizeof(head)); - - head.next = head.prev = &head; - - memfree = I_GetFreeMem(&total)>>20; - CONS_Printf("System memory: %uMB - Free: %uMB\n", total>>20, memfree); - - // Note: This allocates memory. Watch out. - COM_AddCommand("memfree", Command_Memfree_f); - -#ifdef ZDEBUG - COM_AddCommand("memdump", Command_Memdump_f); -#endif -} - +/** Frees allocated memory. + * + * \param ptr A pointer to allocated memory, + * assumed to have been allocated with Z_Malloc/Z_Calloc. + * \sa Z_FreeTags + */ #ifdef ZDEBUG void Z_Free2(void *ptr, const char *file, INT32 line) #else @@ -206,7 +239,11 @@ void Z_Free(void *ptr) #endif } -// malloc() that doesn't accept failure. +/** malloc() that doesn't accept failure. + * + * \param size Amount of memory to be allocated, in bytes. + * \return A pointer to the allocated memory. + */ static void *xm(size_t size) { const size_t padedsize = size+sizeof (size_t); @@ -227,10 +264,18 @@ static void *xm(size_t size) return p; } -// Z_Malloc -// You can pass Z_Malloc() a NULL user if the tag is less than -// PU_PURGELEVEL. - +/** The Z_MallocAlign function. + * Allocates a block of memory, adds it to a linked list so we can keep track of it. + * + * \param size Amount of memory to be allocated, in bytes. + * \param tag Purge tag. + * \param user The address of a pointer to the memory to be allocated. + * When the memory is freed by Z_Free later, + * the pointer at this address will then be automatically set to NULL. + * \param alignbits The alignment of the memory to be allocated, in bits. Can be 0. + * \note You can pass Z_Malloc() a NULL user if the tag is less than PU_PURGELEVEL. + * \sa Z_CallocAlign, Z_ReallocAlign + */ #ifdef ZDEBUG void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) @@ -307,6 +352,19 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) return given; } +/** The Z_CallocAlign function. + * Allocates a block of memory, adds it to a linked list so we can keep track of it. + * Unlike Z_MallocAlign, this also initialises the bytes to zero. + * + * \param size Amount of memory to be allocated, in bytes. + * \param tag Purge tag. + * \param user The address of a pointer to the memory to be allocated. + * When the memory is freed by Z_Free later, + * the pointer at this address will then be automatically set to NULL. + * \param alignbits The alignment of the memory to be allocated, in bits. Can be 0. + * \note You can pass Z_Calloc() a NULL user if the tag is less than PU_PURGELEVEL. + * \sa Z_MallocAlign, Z_ReallocAlign + */ #ifdef ZDEBUG void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) #else @@ -323,10 +381,26 @@ void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) #endif } +/** The Z_ReallocAlign function. + * Reallocates a block of memory with a new size. + * + * \param ptr A pointer to allocated memory, + * assumed to have been allocated with Z_Malloc/Z_Calloc. + * If NULL, this function instead acts as a wrapper for Z_CallocAlign. + * \param size New size of memory block, in bytes. + * If zero, then the memory is freed and NULL is returned. + * \param tag New purge tag. + * \param user The address of a pointer to the memory to be reallocated. + * This can be a different user to the one originally assigned to the memory block. + * \param alignbits The alignment of the memory to be allocated, in bits. Can be 0. + * \return A pointer to the reallocated memory. Can be NULL if memory was freed. + * \note You can pass Z_Realloc() a NULL user if the tag is less than PU_PURGELEVEL. + * \sa Z_MallocAlign, Z_CallocAlign + */ #ifdef ZDEBUG void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) #else -void *Z_ReallocAlign(void *ptr, size_t size,INT32 tag, void *user, INT32 alignbits) +void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits) #endif { void *rez; @@ -393,6 +467,11 @@ void *Z_ReallocAlign(void *ptr, size_t size,INT32 tag, void *user, INT32 alignb return rez; } +/** Frees all memory for a given set of tags. + * + * \param lowtag The lowest tag to consider. + * \param hightag The highest tag to consider. + */ void Z_FreeTags(INT32 lowtag, INT32 hightag) { memblock_t *block, *next; @@ -407,22 +486,25 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag) } } -// -// Z_CheckMemCleanup -// -// TODO: Currently blocks >= PU_PURGELEVEL are freed every -// CLEANUPCOUNT. It might be better to keep track of -// the total size of all purgable memory and free it when the -// size exceeds some value. -// -// This was in Z_Malloc, but was freeing data at -// unsafe times. Now it is only called when it is safe -// to cleanup memory. +// ----------------- +// Utility functions +// ----------------- +// starting value of nextcleanup #define CLEANUPCOUNT 2000 +// number of function calls left before next cleanup static INT32 nextcleanup = CLEANUPCOUNT; +/** This was in Z_Malloc, but was freeing data at + * unsafe times. Now it is only called when it is safe + * to cleanup memory. + * + * \todo Currently blocks >= PU_PURGELEVEL are freed every + * CLEANUPCOUNT. It might be better to keep track of + * the total size of all purgable memory and free it when the + * size exceeds some value. + */ void Z_CheckMemCleanup(void) { if (nextcleanup-- == 0) @@ -538,6 +620,17 @@ void Z_CheckHeap(INT32 i) } } +// ------------------------ +// Zone memory modification +// ------------------------ + +/** Changes a memory block's purge tag. + * + * \param ptr A pointer to allocated memory, + * assumed to have been allocated with Z_Malloc/Z_Calloc. + * \param tag The new tag. + * \sa Z_SetUser + */ #ifdef PARANOIA void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line) #else @@ -583,91 +676,13 @@ void Z_ChangeTag(void *ptr, INT32 tag) block->tag = tag; } -/** Calculates memory usage for a given set of tags. - * NOTE: Z_TagUsage is now just a macro of this function. +/** Changes a memory block's user. * - * \param lowtag The lowest tag to consider. - * \param hightag The highest tag to consider. - * \return Number of bytes currently allocated in the heap for the - * given tags. + * \param ptr A pointer to allocated memory, + * assumed to have been allocated with Z_Malloc/Z_Calloc. + * \param newuser The new user for the memory block. + * \sa Z_ChangeTag */ -size_t Z_TagsUsage(INT32 lowtag, INT32 hightag) -{ - size_t cnt = 0; - memblock_t *rover; - - for (rover = head.next; rover != &head; rover = rover->next) - { - if (rover->tag < lowtag || rover->tag > hightag) - continue; - cnt += rover->size + sizeof *rover; - } - - return cnt; -} - -static void Command_Memfree_f(void) -{ - UINT32 freebytes, totalbytes; - - Z_CheckHeap(-1); - CONS_Printf("\x82%s", M_GetText("Memory Info\n")); - CONS_Printf(M_GetText("Total heap used : %7s KB\n"), sizeu1(Z_TagsUsage(0, INT32_MAX)>>10)); - CONS_Printf(M_GetText("Static : %7s KB\n"), sizeu1(Z_TagUsage(PU_STATIC)>>10)); - CONS_Printf(M_GetText("Static (sound) : %7s KB\n"), sizeu1(Z_TagUsage(PU_SOUND)>>10)); - CONS_Printf(M_GetText("Static (music) : %7s KB\n"), sizeu1(Z_TagUsage(PU_MUSIC)>>10)); - CONS_Printf(M_GetText("Locked cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_CACHE)>>10)); - CONS_Printf(M_GetText("Level : %7s KB\n"), sizeu1(Z_TagUsage(PU_LEVEL)>>10)); - CONS_Printf(M_GetText("Special thinker : %7s KB\n"), sizeu1(Z_TagUsage(PU_LEVSPEC)>>10)); - CONS_Printf(M_GetText("All purgable : %7s KB\n"), - sizeu1(Z_TagsUsage(PU_PURGELEVEL, INT32_MAX)>>10)); - -#ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) - { - CONS_Printf(M_GetText("Patch info headers: %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10)); - CONS_Printf(M_GetText("Mipmap patches : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10)); - CONS_Printf(M_GetText("HW Texture cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10)); - CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10)); - CONS_Printf(M_GetText("HW Texture used : %7d KB\n"), HWR_GetTextureUsed()>>10); - } -#endif - - CONS_Printf("\x82%s", M_GetText("System Memory Info\n")); - freebytes = I_GetFreeMem(&totalbytes); - CONS_Printf(M_GetText(" Total physical memory: %7u KB\n"), totalbytes>>10); - CONS_Printf(M_GetText("Available physical memory: %7u KB\n"), freebytes>>10); -} - -#ifdef ZDEBUG -static void Command_Memdump_f(void) -{ - memblock_t *block; - INT32 mintag = 0, maxtag = INT32_MAX; - INT32 i; - - if ((i = COM_CheckParm("-min"))) - mintag = atoi(COM_Argv(i + 1)); - - if ((i = COM_CheckParm("-max"))) - maxtag = atoi(COM_Argv(i + 1)); - - for (block = head.next; block != &head; block = block->next) - if (block->tag >= mintag && block->tag <= maxtag) - { - char *filename = strrchr(block->ownerfile, PATHSEP[0]); - CONS_Printf("[%3d] %s (%s) bytes @ %s:%d\n", block->tag, sizeu1(block->size), sizeu2(block->realsize), filename ? filename + 1 : block->ownerfile, block->ownerline); - } -} -#endif - -// Creates a copy of a string. -char *Z_StrDup(const char *s) -{ - return strcpy(ZZ_Alloc(strlen(s) + 1), s); -} - - #ifdef PARANOIA void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line) #else @@ -703,3 +718,106 @@ void Z_SetUser(void *ptr, void **newuser) block->user = (void*)newuser; *newuser = ptr; } + +// ----------------- +// Zone memory usage +// ----------------- + +/** Calculates memory usage for a given set of tags. + * + * \param lowtag The lowest tag to consider. + * \param hightag The highest tag to consider. + * \return Number of bytes currently allocated in the heap for the + * given tags. + */ +size_t Z_TagsUsage(INT32 lowtag, INT32 hightag) +{ + size_t cnt = 0; + memblock_t *rover; + + for (rover = head.next; rover != &head; rover = rover->next) + { + if (rover->tag < lowtag || rover->tag > hightag) + continue; + cnt += rover->size + sizeof *rover; + } + + return cnt; +} + +// ----------------------- +// Miscellaneous functions +// ----------------------- + +/** The function called by the "memfree" console command. + * Prints the memory being used by each part of the game to the console. + */ +static void Command_Memfree_f(void) +{ + UINT32 freebytes, totalbytes; + + Z_CheckHeap(-1); + CONS_Printf("\x82%s", M_GetText("Memory Info\n")); + CONS_Printf(M_GetText("Total heap used : %7s KB\n"), sizeu1(Z_TagsUsage(0, INT32_MAX)>>10)); + CONS_Printf(M_GetText("Static : %7s KB\n"), sizeu1(Z_TagUsage(PU_STATIC)>>10)); + CONS_Printf(M_GetText("Static (sound) : %7s KB\n"), sizeu1(Z_TagUsage(PU_SOUND)>>10)); + CONS_Printf(M_GetText("Static (music) : %7s KB\n"), sizeu1(Z_TagUsage(PU_MUSIC)>>10)); + CONS_Printf(M_GetText("Locked cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_CACHE)>>10)); + CONS_Printf(M_GetText("Level : %7s KB\n"), sizeu1(Z_TagUsage(PU_LEVEL)>>10)); + CONS_Printf(M_GetText("Special thinker : %7s KB\n"), sizeu1(Z_TagUsage(PU_LEVSPEC)>>10)); + CONS_Printf(M_GetText("All purgable : %7s KB\n"), + sizeu1(Z_TagsUsage(PU_PURGELEVEL, INT32_MAX)>>10)); + +#ifdef HWRENDER + if (rendermode != render_soft && rendermode != render_none) + { + CONS_Printf(M_GetText("Patch info headers: %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10)); + CONS_Printf(M_GetText("Mipmap patches : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10)); + CONS_Printf(M_GetText("HW Texture cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10)); + CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10)); + CONS_Printf(M_GetText("HW Texture used : %7d KB\n"), HWR_GetTextureUsed()>>10); + } +#endif + + CONS_Printf("\x82%s", M_GetText("System Memory Info\n")); + freebytes = I_GetFreeMem(&totalbytes); + CONS_Printf(M_GetText(" Total physical memory: %7u KB\n"), totalbytes>>10); + CONS_Printf(M_GetText("Available physical memory: %7u KB\n"), freebytes>>10); +} + +#ifdef ZDEBUG +/** The function called by the "memdump" console command. + * Prints zone memory debugging information (i.e. tag, size, location in code allocated). + * Can be all memory allocated in game, or between a set of tags (if -min/-max args used). + * This command is available only if ZDEBUG is enabled. + */ +static void Command_Memdump_f(void) +{ + memblock_t *block; + INT32 mintag = 0, maxtag = INT32_MAX; + INT32 i; + + if ((i = COM_CheckParm("-min"))) + mintag = atoi(COM_Argv(i + 1)); + + if ((i = COM_CheckParm("-max"))) + maxtag = atoi(COM_Argv(i + 1)); + + for (block = head.next; block != &head; block = block->next) + if (block->tag >= mintag && block->tag <= maxtag) + { + char *filename = strrchr(block->ownerfile, PATHSEP[0]); + CONS_Printf("[%3d] %s (%s) bytes @ %s:%d\n", block->tag, sizeu1(block->size), sizeu2(block->realsize), filename ? filename + 1 : block->ownerfile, block->ownerline); + } +} +#endif + +/** Creates a copy of a string. + * + * \param s The string to be copied. + * \return A copy of the string, allocated in zone memory. + */ +char *Z_StrDup(const char *s) +{ + return strcpy(ZZ_Alloc(strlen(s) + 1), s); +} diff --git a/src/z_zone.h b/src/z_zone.h index b21d951d6..d74639be9 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -30,53 +30,53 @@ //#define ZDEBUG // -// ZONE MEMORY -// PU - purge tags. -// Tags < PU_LEVEL are not purged until freed explicitly. -#define PU_STATIC 1 // static entire execution time -#define PU_LUA 2 // static entire execution time -- used by lua so it doesn't get caught in loops forever - -#define PU_SOUND 11 // static while playing -#define PU_MUSIC 12 // static while playing -#define PU_HUDGFX 13 // static until WAD added - -#define PU_HWRPATCHINFO 21 // Hardware GLPatch_t struct for OpenGL texture cache -#define PU_HWRPATCHCOLMIPMAP 22 // Hardware GLMipmap_t struct colromap variation of patch - -#define PU_HWRCACHE 48 // static until unlocked -#define PU_CACHE 49 // static until unlocked - -// Tags s.t. PU_LEVEL <= tag < PU_PURGELEVEL are purged at level start -#define PU_LEVEL 50 // static until level exited -#define PU_LEVSPEC 51 // a special thinker in a level -#define PU_HWRPLANE 52 - -// Tags >= PU_PURGELEVEL are purgable whenever needed -#define PU_PURGELEVEL 100 -#define PU_CACHE_UNLOCKED 101 -#define PU_HWRCACHE_UNLOCKED 102 // 'second-level' cache for graphics - // stored in hardware format and downloaded as needed -#define PU_HWRPATCHINFO_UNLOCKED 103 - -void Z_Init(void); -#define Z_FreeTag(tagnum) Z_FreeTags(tagnum, tagnum) -void Z_FreeTags(INT32 lowtag, INT32 hightag); -void Z_CheckMemCleanup(void); -void Z_CheckHeap(INT32 i); - -#ifdef PARANOIA -// This is used to get the local FILE : LINE info from CPP -// prior to really call the function in question. +// Purge tags // -#define Z_ChangeTag(p,t) Z_ChangeTag2(p, t, __FILE__, __LINE__) -#define Z_SetUser(p,u) Z_SetUser2(p, u, __FILE__, __LINE__) -void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line); -void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line); -#else -void Z_ChangeTag(void *ptr, INT32 tag); -void Z_SetUser(void *ptr, void **newuser); -#endif +// Now they are an enum! -- Monster Iestyn 15/02/18 +// +enum +{ + // Tags < PU_LEVEL are not purged until freed explicitly. + PU_STATIC = 1, // static entire execution time + PU_LUA = 2, // static entire execution time -- used by lua so it doesn't get caught in loops forever + PU_SOUND = 11, // static while playing + PU_MUSIC = 12, // static while playing + PU_HUDGFX = 13, // static until WAD added + + PU_HWRPATCHINFO = 21, // Hardware GLPatch_t struct for OpenGL texture cache + PU_HWRPATCHCOLMIPMAP = 22, // Hardware GLMipmap_t struct colormap variation of patch + + PU_HWRCACHE = 48, // static until unlocked + PU_CACHE = 49, // static until unlocked + + // Tags s.t. PU_LEVEL <= tag < PU_PURGELEVEL are purged at level start + PU_LEVEL = 50, // static until level exited + PU_LEVSPEC = 51, // a special thinker in a level + PU_HWRPLANE = 52, // if ZPLANALLOC is enabled in hw_bsp.c, this is used to alloc polygons for OpenGL + + // Tags >= PU_PURGELEVEL are purgable whenever needed + PU_PURGELEVEL = 100, // Note: this is never actually used as a tag + PU_CACHE_UNLOCKED = 101, // Note: unused + PU_HWRCACHE_UNLOCKED = 102, // 'unlocked' PU_HWRCACHE memory: + // 'second-level' cache for graphics + // stored in hardware format and downloaded as needed + PU_HWRPATCHINFO_UNLOCKED = 103, // 'unlocked' PU_HWRPATCHINFO memory +}; + +// +// Zone memory initialisation +// +void Z_Init(void); + +// +// Zone memory allocation +// +// enable ZDEBUG to get the file + line the functions were called from +// for ZZ_Alloc, see doomdef.h +// + +// Z_Free and alloc with alignment #ifdef ZDEBUG #define Z_Free(p) Z_Free2(p, __FILE__, __LINE__) #define Z_MallocAlign(s,t,u,a) Z_Malloc2(s, t, u, a, __FILE__, __LINE__) @@ -93,15 +93,51 @@ void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALL void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(2); #endif +// Alloc with no alignment #define Z_Malloc(s,t,u) Z_MallocAlign(s, t, u, 0) #define Z_Calloc(s,t,u) Z_CallocAlign(s, t, u, 0) #define Z_Realloc(p,s,t,u) Z_ReallocAlign(p, s, t, u, 0) +// Free all memory by tag +// these don't give line numbers for ZDEBUG currently though +// (perhaps this should be changed in future?) +#define Z_FreeTag(tagnum) Z_FreeTags(tagnum, tagnum) +void Z_FreeTags(INT32 lowtag, INT32 hightag); + +// +// Utility functions +// +void Z_CheckMemCleanup(void); +void Z_CheckHeap(INT32 i); + +// +// Zone memory modification +// +// enable PARANOIA to get the file + line the functions were called from +// +#ifdef PARANOIA +#define Z_ChangeTag(p,t) Z_ChangeTag2(p, t, __FILE__, __LINE__) +#define Z_SetUser(p,u) Z_SetUser2(p, u, __FILE__, __LINE__) +void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line); +void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line); +#else +void Z_ChangeTag(void *ptr, INT32 tag); +void Z_SetUser(void *ptr, void **newuser); +#endif + +// +// Zone memory usage +// +// Note: These give the memory used in bytes, +// shift down by 10 to convert to KB +// #define Z_TagUsage(tagnum) Z_TagsUsage(tagnum, tagnum) size_t Z_TagsUsage(INT32 lowtag, INT32 hightag); +// +// Miscellaneous functions +// char *Z_StrDup(const char *in); - -#define Z_Unlock(p) (void)p +#define Z_Unlock(p) (void)p // TODO: remove this now that NDS code has been removed #endif From 64eba826929536b285fe63a2ad2bf12189ec7d64 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 16 Feb 2018 20:32:43 +0000 Subject: [PATCH 6/6] Added Z_TotalUsage as a shortcut for Z_TagsUsage(0, INT32_MAX) --- src/st_stuff.c | 2 +- src/z_zone.c | 2 +- src/z_zone.h | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 437b6758a..887925666 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -606,7 +606,7 @@ static void ST_drawDebugInfo(void) if (cv_debug & DBG_MEMORY) { - V_DrawRightAlignedString(320, height, V_MONOSPACE, va("Heap: %7sKB", sizeu1(Z_TagsUsage(0, INT32_MAX)>>10))); + V_DrawRightAlignedString(320, height, V_MONOSPACE, va("Heap: %7sKB", sizeu1(Z_TotalUsage()>>10))); } } diff --git a/src/z_zone.c b/src/z_zone.c index 2c7cf7c71..b5799b583 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -758,7 +758,7 @@ static void Command_Memfree_f(void) Z_CheckHeap(-1); CONS_Printf("\x82%s", M_GetText("Memory Info\n")); - CONS_Printf(M_GetText("Total heap used : %7s KB\n"), sizeu1(Z_TagsUsage(0, INT32_MAX)>>10)); + CONS_Printf(M_GetText("Total heap used : %7s KB\n"), sizeu1(Z_TotalUsage()>>10)); CONS_Printf(M_GetText("Static : %7s KB\n"), sizeu1(Z_TagUsage(PU_STATIC)>>10)); CONS_Printf(M_GetText("Static (sound) : %7s KB\n"), sizeu1(Z_TagUsage(PU_SOUND)>>10)); CONS_Printf(M_GetText("Static (music) : %7s KB\n"), sizeu1(Z_TagUsage(PU_MUSIC)>>10)); diff --git a/src/z_zone.h b/src/z_zone.h index d74639be9..205c9ed79 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -133,6 +133,7 @@ void Z_SetUser(void *ptr, void **newuser); // #define Z_TagUsage(tagnum) Z_TagsUsage(tagnum, tagnum) size_t Z_TagsUsage(INT32 lowtag, INT32 hightag); +#define Z_TotalUsage() Z_TagsUsage(0, INT32_MAX) // // Miscellaneous functions