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