Skip to content
Snippets Groups Projects
Unverified Commit cee5eb47 authored by Hanicef's avatar Hanicef
Browse files

Clean up and simplify zone memory allocation

parent a752e6c8
No related branches found
No related tags found
1 merge request!2059Clean up and simplify zone memory allocation
......@@ -51,27 +51,11 @@ static boolean Z_calloc = false;
//#define ZDEBUG2
#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
{
void *real;
memhdr_t *hdr;
void **user;
INT32 tag; // purgelevel
UINT32 id; // Should be ZONEID
size_t size; // including the header and blocks
size_t realsize; // size of real data only
......@@ -82,7 +66,10 @@ typedef struct memblock_s
#endif
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
static memblock_t head;
......@@ -128,64 +115,6 @@ void Z_Init(void)
// 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.
*
* \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);
#endif
block = MEMBLOCK(ptr);
#ifdef PARANOIA
if (block->id != ZONEID)
#ifdef ZDEBUG
block = Ptr2Memblock2(ptr, "Z_Free", file, line);
I_Error("Z_Free at %s:%d: wrong id", file, line);
#else
block = Ptr2Memblock(ptr, "Z_Free");
I_Error("Z_Free: wrong id");
#endif
#endif
#ifdef ZDEBUG
......@@ -229,8 +162,6 @@ void Z_Free(void *ptr)
if (block->user != NULL)
*block->user = NULL;
// Free the memory and get rid of the block.
free(block->real);
#ifdef VALGRIND_DESTROY_MEMPOOL
VALGRIND_DESTROY_MEMPOOL(block);
#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)
#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;
void *ptr;
memhdr_t *hdr;
void *given;
size_t blocksize = extrabytes + sizeof *hdr + size;
(void)(alignbits); // no longer used, so silence warnings.
#ifdef ZDEBUG2
CONS_Debug(DBG_MEMORY, "Z_Malloc %s:%d\n", file, line);
#endif
if (blocksize < size)/* overflow check */
I_Error("You are allocating memory too large!");
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);
block = xm(sizeof (memblock_t) + size);
ptr = MEMORY(block);
I_Assert((intptr_t)ptr % sizeof (void *) == 0);
#ifdef HAVE_VALGRIND
Z_calloc = false;
......@@ -326,41 +239,31 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
head.next = block;
block->next->prev = block;
block->real = ptr;
block->hdr = hdr;
block->tag = tag;
block->user = NULL;
#ifdef ZDEBUG
block->ownerline = line;
block->ownerfile = file;
#endif
block->size = blocksize;
block->size = sizeof (memblock_t) + size;
block->realsize = size;
#ifdef VALGRIND_CREATE_MEMPOOL
VALGRIND_CREATE_MEMPOOL(block, padsize, Z_calloc);
VALGRIND_CREATE_MEMPOOL(block, size, Z_calloc);
#endif
//#ifdef VALGRIND_MEMPOOL_ALLOC
// VALGRIND_MEMPOOL_ALLOC(block, hdr, size + sizeof *hdr);
//#endif
hdr->id = ZONEID;
hdr->block = block;
#ifdef VALGRIND_MAKE_MEM_NOACCESS
VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr);
#endif
block->id = ZONEID;
if (user != NULL)
{
block->user = user;
*(void **)user = given;
*(void **)user = ptr;
}
else if (tag >= PU_PURGELEVEL)
I_Error("Z_Malloc: attempted to allocate purgable block "
"(size %s) with no user", sizeu1(size));
return given;
return ptr;
}
/** The Z_CallocAlign function.
......@@ -437,10 +340,14 @@ void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignb
#endif
}
block = MEMBLOCK(ptr);
#ifdef PARANOIA
if (block->id != ZONEID)
#ifdef ZDEBUG
block = Ptr2Memblock2(ptr, "Z_Realloc", file, line);
I_Error("Z_ReallocAlign at %s:%d: wrong id", file, line);
#else
block = Ptr2Memblock(ptr, "Z_Realloc");
I_Error("Z_ReallocAlign: wrong id");
#endif
#endif
if (block == NULL)
......@@ -491,9 +398,8 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag)
for (block = head.next; block != &head; block = next)
{
next = block->next; // get link before freeing
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)
{
void *mem = (UINT8 *)block->hdr + sizeof *block->hdr;
void *mem = MEMORY(block);
boolean free = iterfunc(mem);
if (free)
Z_Free(mem);
......@@ -561,15 +467,13 @@ void Z_CheckMemCleanup(void)
void Z_CheckHeap(INT32 i)
{
memblock_t *block;
memhdr_t *hdr;
UINT32 blocknumon = 0;
void *given;
for (block = head.next; block != &head; block = block->next)
{
blocknumon++;
hdr = block->hdr;
given = (UINT8 *)hdr + sizeof *hdr;
given = MEMORY(block);
#ifdef ZDEBUG2
CONS_Debug(DBG_MEMORY, "block %u owned by %s:%d\n",
blocknumon, block->ownerfile, block->ownerline);
......@@ -585,7 +489,7 @@ void Z_CheckHeap(INT32 i)
#ifdef ZDEBUG
, block->ownerfile, block->ownerline
#endif
);
);
}
#endif
if (block->user != NULL && *(block->user) != given)
......@@ -598,7 +502,7 @@ void Z_CheckHeap(INT32 i)
#ifdef ZDEBUG
, block->ownerfile, block->ownerline
#endif
);
);
}
if (block->next->prev != block)
{
......@@ -610,7 +514,7 @@ void Z_CheckHeap(INT32 i)
#ifdef ZDEBUG
, block->ownerfile, block->ownerline
#endif
);
);
}
if (block->prev->next != block)
{
......@@ -622,25 +526,9 @@ void Z_CheckHeap(INT32 i)
#ifdef ZDEBUG
, block->ownerfile, block->ownerline
#endif
);
);
}
#ifdef VALGRIND_MAKE_MEM_DEFINED
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)
if (block->id != ZONEID)
{
I_Error("Z_CheckHeap %d: block %u"
#ifdef ZDEBUG
......@@ -650,11 +538,8 @@ void Z_CheckHeap(INT32 i)
#ifdef ZDEBUG
, block->ownerfile, block->ownerline
#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
{
memblock_t *block;
memhdr_t *hdr;
if (ptr == NULL)
return;
hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr);
#ifdef VALGRIND_MAKE_MEM_DEFINED
VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr);
#endif
block = MEMBLOCK(ptr);
#ifdef VALGRIND_MEMPOOL_EXISTS
if (!VALGRIND_MEMPOOL_EXISTS(hdr->block))
{
#ifdef PARANOIA
I_Error("Z_CT at %s:%d: bad memblock", 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);
if (block->id != ZONEID) I_Error("Z_ChangeTag at %s:%d: wrong id", file, line);
#endif
if (tag >= PU_PURGELEVEL && block->user == NULL)
......@@ -728,25 +592,14 @@ void Z_SetUser(void *ptr, void **newuser)
#endif
{
memblock_t *block;
memhdr_t *hdr;
if (ptr == NULL)
return;
hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr);
#ifdef VALGRIND_MAKE_MEM_DEFINED
VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr);
#endif
block = MEMBLOCK(ptr);
#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);
if (block->id != ZONEID) I_Error("Z_SetUser at %s:%d: wrong id", file, line);
#endif
if (block->tag >= PU_PURGELEVEL && newuser == NULL)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment