void *_Mem_Alloc(mempool_t *pool, int size, char *filename, int fileline)
{
+#if MEMCLUMPING
int i, j, k, needed, endbit, largest;
memclump_t *clump, **clumpchainpointer;
+#endif
memheader_t *mem;
if (size <= 0)
return NULL;
Sys_Error("Mem_Alloc: pool == NULL (alloc at %s:%i)", filename, fileline);
Con_DPrintf("Mem_Alloc: pool %s, file %s:%i, size %i bytes\n", pool->name, filename, fileline, size);
pool->totalsize += size;
+#if MEMCLUMPING
if (size < 4096)
{
// clumping
else
{
// big allocations are not clumped
+#endif
pool->realsize += sizeof(memheader_t) + size + sizeof(int);
mem = malloc(sizeof(memheader_t) + size + sizeof(int));
if (mem == NULL)
Sys_Error("Mem_Alloc: out of memory (alloc at %s:%i)", filename, fileline);
+#if MEMCLUMPING
mem->clump = NULL;
}
+#endif
mem->filename = filename;
mem->fileline = fileline;
mem->size = size;
void _Mem_Free(void *data, char *filename, int fileline)
{
+#if MEMCLUMPING
int i, firstblock, endblock;
memclump_t *clump, **clumpchainpointer;
+#endif
memheader_t *mem, **memchainpointer;
mempool_t *pool;
if (data == NULL)
{
*memchainpointer = mem->chain;
pool->totalsize -= mem->size;
+#if MEMCLUMPING
if ((clump = mem->clump))
{
if (clump->sentinel1 != MEMCLUMP_SENTINEL)
}
else
{
+#endif
pool->realsize -= sizeof(memheader_t) + mem->size + sizeof(int);
memset(mem, 0xBF, sizeof(memheader_t) + mem->size + sizeof(int));
free(mem);
+#if MEMCLUMPING
}
+#endif
return;
}
}
Sys_Error("Mem_CheckSentinels: trashed header sentinel 2 (block allocated at %s:%i, sentinel check at %s:%i)", mem->filename, mem->fileline, filename, fileline);
}
+#if MEMCLUMPING
static void _Mem_CheckClumpSentinels(memclump_t *clump, char *filename, int fileline)
{
// this isn't really very useful
if (clump->sentinel2 != MEMCLUMP_SENTINEL)
Sys_Error("Mem_CheckClumpSentinels: trashed sentinel 2 (sentinel check at %s:%i)", filename, fileline);
}
+#endif
void _Mem_CheckSentinelsGlobal(char *filename, int fileline)
{
memheader_t *mem;
+#if MEMCLUMPING
memclump_t *clump;
+#endif
mempool_t *pool;
for (pool = poolchain;pool;pool = pool->next)
+#if MEMCLUMPING
{
+#endif
for (mem = pool->chain;mem;mem = mem->chain)
_Mem_CheckSentinels((void *)((qbyte *) mem + sizeof(memheader_t)), filename, fileline);
+#if MEMCLUMPING
for (clump = pool->clumpchain;clump;clump = clump->chain)
_Mem_CheckClumpSentinels(clump, filename, fileline);
}
+#endif
}
// used for temporary memory allocations around the engine, not for longterm
#ifndef ZONE_H
#define ZONE_H
+// LordHavoc: this is pointless with a good C library
+//#define MEMCLUMPING
+
#define POOLNAMESIZE 128
+#if MEMCLUMPING
// give malloc padding so we can't waste most of a page at the end
#define MEMCLUMPSIZE (65536 - 1536)
// smallest unit we care about is this many bytes
#define MEMUNIT 8
#define MEMBITS (MEMCLUMPSIZE / MEMUNIT)
#define MEMBITINTS (MEMBITS / 32)
+#define MEMCLUMP_SENTINEL 0xABADCAFE
+#endif
#define MEMHEADER_SENTINEL1 0xDEADF00D
#define MEMHEADER_SENTINEL2 0xDF
-#define MEMCLUMP_SENTINEL 0xABADCAFE
typedef struct memheader_s
{
struct memheader_s *chain;
// pool this memheader belongs to
struct mempool_s *pool;
+#if MEMCLUMPING
// clump this memheader lives in, NULL if not in a clump
struct memclump_s *clump;
+#endif
// size of the memory after the header (excluding header and sentinel2)
int size;
// file name and line where Mem_Alloc was called
}
memheader_t;
+#if MEMCLUMPING
typedef struct memclump_s
{
// contents of the clump
struct memclump_s *chain;
}
memclump_t;
+#endif
typedef struct mempool_s
{
// chain of individual memory allocations
struct memheader_s *chain;
+#if MEMCLUMPING
// chain of clumps (if any)
struct memclump_s *clumpchain;
+#endif
// total memory allocated in this pool (inside memheaders)
int totalsize;
// total memory allocated in this pool (actual malloc total)