Code: Select all
void *Z_Malloc (int size, int tag, void *user)
{
int extra;
memblock_t *start, *rover, *new, *base;
//
// scan through the block list looking for the first free block
// of sufficient size, throwing out any purgable blocks along the way
//
size += sizeof(memblock_t); // account for size of block header
//
// if there is a free block behind the rover, back up over them
//
base = mainzone->rover;
if (!base->prev->user)
base = base->prev;
rover = base;
start = base->prev;
do
{
if (rover == start) // scaned all the way around the list
{
SoftError("OHSHIT\n");
Z_DumpHeap(0,200);
Error ("Z_Malloc: failed on allocation of %i bytes",size);
}
if (rover->user)
{
if (rover->tag < PU_PURGELEVEL)
// hit a block that can't be purged, so move base past it
base = rover = rover->next;
else
{
// free the rover block (adding the size to base)
base = base->prev; // the rover can be the base block
Z_Free ((byte *)rover+sizeof(memblock_t));
base = base->next;
rover = base->next;
}
}
else
rover = rover->next;
} while (base->user || base->size < size);
//
// found a block big enough
//
extra = base->size - size;
if (extra > MINFRAGMENT)
{ // there will be a free fragment after the allocated block
new = (memblock_t *) ((byte *)base + size );
new->size = extra; //!!!EXECUTION BREAKS HERE!!!
new->user = NULL; // free block
new->tag = 0;
new->prev = base;
new->next = base->next;
new->next->prev = new;
base->next = new;
base->size = size;
}
if (user)
{
base->user = user; // mark as an in use block
*(void **)user = (void *) ((byte *)base + sizeof(memblock_t));
}
else
{
if (tag >= PU_PURGELEVEL)
Error ("Z_Malloc: an owner is required for purgable blocks");
base->user = (void *)2; // mark as in use, but unowned
}
base->tag = tag;
mainzone->rover = base->next; // next allocation will start looking here
return (void *) ((byte *)base + sizeof(memblock_t));
}
Code: Select all
typedef struct memblock_s
{
int size; // including the header and possibly tiny fragments
void **user; // NULL if a free block
int tag; // purgelevel
struct memblock_s *next, *prev;
} memblock_t;
typedef struct
{
int size; // total bytes malloced, including header
memblock_t blocklist; // start / end cap for linked list
memblock_t *rover;
} memzone_t;
Same code runs fine under cygwin.
Thank you in advance