mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-21 20:11:12 +00:00
Clean up and simplify zone memory allocation
This commit is contained in:
parent
a752e6c8e4
commit
cee5eb47b5
1 changed files with 39 additions and 186 deletions
215
src/z_zone.c
215
src/z_zone.c
|
@ -51,27 +51,11 @@ static boolean Z_calloc = false;
|
||||||
//#define ZDEBUG2
|
//#define ZDEBUG2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct memblock_s;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
struct memblock_s *block; // Describing this memory
|
|
||||||
UINT32 id; // Should be ZONEID
|
|
||||||
} ATTRPACK memhdr_t;
|
|
||||||
|
|
||||||
// Some code might want aligned memory. Assume it wants memory n bytes
|
|
||||||
// aligned -- then we allocate n-1 extra bytes and return a pointer to
|
|
||||||
// the first byte aligned as requested.
|
|
||||||
// Thus, "real" is the pointer we get from malloc() and will free()
|
|
||||||
// later, but "hdr" is where the memhdr_t starts.
|
|
||||||
// For non-aligned allocations they will be the same.
|
|
||||||
typedef struct memblock_s
|
typedef struct memblock_s
|
||||||
{
|
{
|
||||||
void *real;
|
|
||||||
memhdr_t *hdr;
|
|
||||||
|
|
||||||
void **user;
|
void **user;
|
||||||
INT32 tag; // purgelevel
|
INT32 tag; // purgelevel
|
||||||
|
UINT32 id; // Should be ZONEID
|
||||||
|
|
||||||
size_t size; // including the header and blocks
|
size_t size; // including the header and blocks
|
||||||
size_t realsize; // size of real data only
|
size_t realsize; // size of real data only
|
||||||
|
@ -82,7 +66,10 @@ typedef struct memblock_s
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct memblock_s *next, *prev;
|
struct memblock_s *next, *prev;
|
||||||
} ATTRPACK memblock_t;
|
} memblock_t;
|
||||||
|
|
||||||
|
#define MEMORY(x) (void *)((uintptr_t)(x) + sizeof(memblock_t))
|
||||||
|
#define MEMBLOCK(x) (memblock_t *)((uintptr_t)(x) - sizeof(memblock_t))
|
||||||
|
|
||||||
// both the head and tail of the zone memory block list
|
// both the head and tail of the zone memory block list
|
||||||
static memblock_t head;
|
static memblock_t head;
|
||||||
|
@ -128,64 +115,6 @@ void Z_Init(void)
|
||||||
// Zone memory allocation
|
// 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)
|
|
||||||
#else
|
|
||||||
static memblock_t *Ptr2Memblock(void *ptr, const char* func)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
memhdr_t *hdr;
|
|
||||||
memblock_t *block;
|
|
||||||
|
|
||||||
if (ptr == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
#ifdef ZDEBUG2
|
|
||||||
CONS_Printf("%s %s:%d\n", func, file, line);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr);
|
|
||||||
|
|
||||||
#ifdef VALGRIND_MAKE_MEM_DEFINED
|
|
||||||
VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef VALGRIND_MEMPOOL_EXISTS
|
|
||||||
if (!VALGRIND_MEMPOOL_EXISTS(hdr->block))
|
|
||||||
{
|
|
||||||
#ifdef ZDEBUG
|
|
||||||
I_Error("%s: bad memblock from %s:%d", func, file, line);
|
|
||||||
#else
|
|
||||||
I_Error("%s: bad memblock", func);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (hdr->id != ZONEID)
|
|
||||||
{
|
|
||||||
#ifdef ZDEBUG
|
|
||||||
I_Error("%s: wrong id from %s:%d", func, file, line);
|
|
||||||
#else
|
|
||||||
I_Error("%s: wrong id", func);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
block = hdr->block;
|
|
||||||
#ifdef VALGRIND_MAKE_MEM_NOACCESS
|
|
||||||
VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr);
|
|
||||||
#endif
|
|
||||||
return block;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Frees allocated memory.
|
/** Frees allocated memory.
|
||||||
*
|
*
|
||||||
* \param ptr A pointer to allocated memory,
|
* \param ptr A pointer to allocated memory,
|
||||||
|
@ -207,10 +136,14 @@ void Z_Free(void *ptr)
|
||||||
CONS_Debug(DBG_MEMORY, "Z_Free %s:%d\n", file, line);
|
CONS_Debug(DBG_MEMORY, "Z_Free %s:%d\n", file, line);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
block = MEMBLOCK(ptr);
|
||||||
|
#ifdef PARANOIA
|
||||||
|
if (block->id != ZONEID)
|
||||||
#ifdef ZDEBUG
|
#ifdef ZDEBUG
|
||||||
block = Ptr2Memblock2(ptr, "Z_Free", file, line);
|
I_Error("Z_Free at %s:%d: wrong id", file, line);
|
||||||
#else
|
#else
|
||||||
block = Ptr2Memblock(ptr, "Z_Free");
|
I_Error("Z_Free: wrong id");
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ZDEBUG
|
#ifdef ZDEBUG
|
||||||
|
@ -229,8 +162,6 @@ void Z_Free(void *ptr)
|
||||||
if (block->user != NULL)
|
if (block->user != NULL)
|
||||||
*block->user = NULL;
|
*block->user = NULL;
|
||||||
|
|
||||||
// Free the memory and get rid of the block.
|
|
||||||
free(block->real);
|
|
||||||
#ifdef VALGRIND_DESTROY_MEMPOOL
|
#ifdef VALGRIND_DESTROY_MEMPOOL
|
||||||
VALGRIND_DESTROY_MEMPOOL(block);
|
VALGRIND_DESTROY_MEMPOOL(block);
|
||||||
#endif
|
#endif
|
||||||
|
@ -287,35 +218,17 @@ void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits,
|
||||||
void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
|
void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
I_Assert(alignbits >= 0 && alignbits < (INT32)(sizeof(size_t) * 8));
|
|
||||||
size_t extrabytes = ((size_t)1<<alignbits) - 1;
|
|
||||||
size_t padsize = 0;
|
|
||||||
memblock_t *block;
|
memblock_t *block;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
memhdr_t *hdr;
|
(void)(alignbits); // no longer used, so silence warnings.
|
||||||
void *given;
|
|
||||||
size_t blocksize = extrabytes + sizeof *hdr + size;
|
|
||||||
|
|
||||||
#ifdef ZDEBUG2
|
#ifdef ZDEBUG2
|
||||||
CONS_Debug(DBG_MEMORY, "Z_Malloc %s:%d\n", file, line);
|
CONS_Debug(DBG_MEMORY, "Z_Malloc %s:%d\n", file, line);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (blocksize < size)/* overflow check */
|
block = xm(sizeof (memblock_t) + size);
|
||||||
I_Error("You are allocating memory too large!");
|
ptr = MEMORY(block);
|
||||||
|
I_Assert((intptr_t)ptr % sizeof (void *) == 0);
|
||||||
block = xm(sizeof *block);
|
|
||||||
#ifdef HAVE_VALGRIND
|
|
||||||
padsize += (1<<sizeof(size_t))*2;
|
|
||||||
#endif
|
|
||||||
ptr = xm(blocksize + padsize*2);
|
|
||||||
|
|
||||||
// This horrible calculation makes sure that "given" is aligned
|
|
||||||
// properly.
|
|
||||||
given = (void *)((size_t)((UINT8 *)ptr + extrabytes + sizeof *hdr + padsize/2)
|
|
||||||
& ~extrabytes);
|
|
||||||
|
|
||||||
// The mem header lives 'sizeof (memhdr_t)' bytes before given.
|
|
||||||
hdr = (memhdr_t *)((UINT8 *)given - sizeof *hdr);
|
|
||||||
|
|
||||||
#ifdef HAVE_VALGRIND
|
#ifdef HAVE_VALGRIND
|
||||||
Z_calloc = false;
|
Z_calloc = false;
|
||||||
|
@ -326,41 +239,31 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
|
||||||
head.next = block;
|
head.next = block;
|
||||||
block->next->prev = block;
|
block->next->prev = block;
|
||||||
|
|
||||||
block->real = ptr;
|
|
||||||
block->hdr = hdr;
|
|
||||||
block->tag = tag;
|
block->tag = tag;
|
||||||
block->user = NULL;
|
block->user = NULL;
|
||||||
#ifdef ZDEBUG
|
#ifdef ZDEBUG
|
||||||
block->ownerline = line;
|
block->ownerline = line;
|
||||||
block->ownerfile = file;
|
block->ownerfile = file;
|
||||||
#endif
|
#endif
|
||||||
block->size = blocksize;
|
block->size = sizeof (memblock_t) + size;
|
||||||
block->realsize = size;
|
block->realsize = size;
|
||||||
|
|
||||||
#ifdef VALGRIND_CREATE_MEMPOOL
|
#ifdef VALGRIND_CREATE_MEMPOOL
|
||||||
VALGRIND_CREATE_MEMPOOL(block, padsize, Z_calloc);
|
VALGRIND_CREATE_MEMPOOL(block, size, Z_calloc);
|
||||||
#endif
|
#endif
|
||||||
//#ifdef VALGRIND_MEMPOOL_ALLOC
|
|
||||||
// VALGRIND_MEMPOOL_ALLOC(block, hdr, size + sizeof *hdr);
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
hdr->id = ZONEID;
|
block->id = ZONEID;
|
||||||
hdr->block = block;
|
|
||||||
|
|
||||||
#ifdef VALGRIND_MAKE_MEM_NOACCESS
|
|
||||||
VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (user != NULL)
|
if (user != NULL)
|
||||||
{
|
{
|
||||||
block->user = user;
|
block->user = user;
|
||||||
*(void **)user = given;
|
*(void **)user = ptr;
|
||||||
}
|
}
|
||||||
else if (tag >= PU_PURGELEVEL)
|
else if (tag >= PU_PURGELEVEL)
|
||||||
I_Error("Z_Malloc: attempted to allocate purgable block "
|
I_Error("Z_Malloc: attempted to allocate purgable block "
|
||||||
"(size %s) with no user", sizeu1(size));
|
"(size %s) with no user", sizeu1(size));
|
||||||
|
|
||||||
return given;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The Z_CallocAlign function.
|
/** The Z_CallocAlign function.
|
||||||
|
@ -437,10 +340,14 @@ void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignb
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
block = MEMBLOCK(ptr);
|
||||||
|
#ifdef PARANOIA
|
||||||
|
if (block->id != ZONEID)
|
||||||
#ifdef ZDEBUG
|
#ifdef ZDEBUG
|
||||||
block = Ptr2Memblock2(ptr, "Z_Realloc", file, line);
|
I_Error("Z_ReallocAlign at %s:%d: wrong id", file, line);
|
||||||
#else
|
#else
|
||||||
block = Ptr2Memblock(ptr, "Z_Realloc");
|
I_Error("Z_ReallocAlign: wrong id");
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (block == NULL)
|
if (block == NULL)
|
||||||
|
@ -491,9 +398,8 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag)
|
||||||
for (block = head.next; block != &head; block = next)
|
for (block = head.next; block != &head; block = next)
|
||||||
{
|
{
|
||||||
next = block->next; // get link before freeing
|
next = block->next; // get link before freeing
|
||||||
|
|
||||||
if (block->tag >= lowtag && block->tag <= hightag)
|
if (block->tag >= lowtag && block->tag <= hightag)
|
||||||
Z_Free((UINT8 *)block->hdr + sizeof *block->hdr);
|
Z_Free(MEMORY(block));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,7 +422,7 @@ void Z_IterateTags(INT32 lowtag, INT32 hightag, boolean (*iterfunc)(void *))
|
||||||
|
|
||||||
if (block->tag >= lowtag && block->tag <= hightag)
|
if (block->tag >= lowtag && block->tag <= hightag)
|
||||||
{
|
{
|
||||||
void *mem = (UINT8 *)block->hdr + sizeof *block->hdr;
|
void *mem = MEMORY(block);
|
||||||
boolean free = iterfunc(mem);
|
boolean free = iterfunc(mem);
|
||||||
if (free)
|
if (free)
|
||||||
Z_Free(mem);
|
Z_Free(mem);
|
||||||
|
@ -561,15 +467,13 @@ void Z_CheckMemCleanup(void)
|
||||||
void Z_CheckHeap(INT32 i)
|
void Z_CheckHeap(INT32 i)
|
||||||
{
|
{
|
||||||
memblock_t *block;
|
memblock_t *block;
|
||||||
memhdr_t *hdr;
|
|
||||||
UINT32 blocknumon = 0;
|
UINT32 blocknumon = 0;
|
||||||
void *given;
|
void *given;
|
||||||
|
|
||||||
for (block = head.next; block != &head; block = block->next)
|
for (block = head.next; block != &head; block = block->next)
|
||||||
{
|
{
|
||||||
blocknumon++;
|
blocknumon++;
|
||||||
hdr = block->hdr;
|
given = MEMORY(block);
|
||||||
given = (UINT8 *)hdr + sizeof *hdr;
|
|
||||||
#ifdef ZDEBUG2
|
#ifdef ZDEBUG2
|
||||||
CONS_Debug(DBG_MEMORY, "block %u owned by %s:%d\n",
|
CONS_Debug(DBG_MEMORY, "block %u owned by %s:%d\n",
|
||||||
blocknumon, block->ownerfile, block->ownerline);
|
blocknumon, block->ownerfile, block->ownerline);
|
||||||
|
@ -624,23 +528,7 @@ void Z_CheckHeap(INT32 i)
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
#ifdef VALGRIND_MAKE_MEM_DEFINED
|
if (block->id != ZONEID)
|
||||||
VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr);
|
|
||||||
#endif
|
|
||||||
if (hdr->block != block)
|
|
||||||
{
|
|
||||||
I_Error("Z_CheckHeap %d: block %u"
|
|
||||||
#ifdef ZDEBUG
|
|
||||||
"(owned by %s:%d)"
|
|
||||||
#endif
|
|
||||||
" doesn't have linkback from allocated memory",
|
|
||||||
i, blocknumon
|
|
||||||
#ifdef ZDEBUG
|
|
||||||
, block->ownerfile, block->ownerline
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (hdr->id != ZONEID)
|
|
||||||
{
|
{
|
||||||
I_Error("Z_CheckHeap %d: block %u"
|
I_Error("Z_CheckHeap %d: block %u"
|
||||||
#ifdef ZDEBUG
|
#ifdef ZDEBUG
|
||||||
|
@ -652,9 +540,6 @@ void Z_CheckHeap(INT32 i)
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
#ifdef VALGRIND_MAKE_MEM_NOACCESS
|
|
||||||
VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,35 +561,14 @@ void Z_ChangeTag(void *ptr, INT32 tag)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
memblock_t *block;
|
memblock_t *block;
|
||||||
memhdr_t *hdr;
|
|
||||||
|
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr);
|
block = MEMBLOCK(ptr);
|
||||||
|
|
||||||
#ifdef VALGRIND_MAKE_MEM_DEFINED
|
|
||||||
VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef VALGRIND_MEMPOOL_EXISTS
|
|
||||||
if (!VALGRIND_MEMPOOL_EXISTS(hdr->block))
|
|
||||||
{
|
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
I_Error("Z_CT at %s:%d: bad memblock", file, line);
|
if (block->id != ZONEID) I_Error("Z_ChangeTag at %s:%d: wrong id", file, line);
|
||||||
#else
|
|
||||||
I_Error("Z_CT: bad memblock");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef PARANOIA
|
|
||||||
if (hdr->id != ZONEID) I_Error("Z_CT at %s:%d: wrong id", file, line);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
block = hdr->block;
|
|
||||||
|
|
||||||
#ifdef VALGRIND_MAKE_MEM_NOACCESS
|
|
||||||
VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (tag >= PU_PURGELEVEL && block->user == NULL)
|
if (tag >= PU_PURGELEVEL && block->user == NULL)
|
||||||
|
@ -728,25 +592,14 @@ void Z_SetUser(void *ptr, void **newuser)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
memblock_t *block;
|
memblock_t *block;
|
||||||
memhdr_t *hdr;
|
|
||||||
|
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr);
|
block = MEMBLOCK(ptr);
|
||||||
|
|
||||||
#ifdef VALGRIND_MAKE_MEM_DEFINED
|
|
||||||
VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
if (hdr->id != ZONEID) I_Error("Z_CT at %s:%d: wrong id", file, line);
|
if (block->id != ZONEID) I_Error("Z_SetUser at %s:%d: wrong id", file, line);
|
||||||
#endif
|
|
||||||
|
|
||||||
block = hdr->block;
|
|
||||||
|
|
||||||
#ifdef VALGRIND_MAKE_MEM_NOACCESS
|
|
||||||
VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (block->tag >= PU_PURGELEVEL && newuser == NULL)
|
if (block->tag >= PU_PURGELEVEL && newuser == NULL)
|
||||||
|
|
Loading…
Reference in a new issue