Figure 1 freelist \ --------\-----+-----+-----+-----+-----+-----+-----+-------- . . . |\ | | | | | | |. . . . . . . | > ---> ---> ---> ---> ---> ---> 0 |. . . . . . . | | | | | | | |. . . . --------+-----+-----+-----+-----+-----+-----+-----+-------- Figure 2 freelist ---------\ -------------- \ / \ --------+-----+-----\-----+/----+-----+-----\-----+-------- . . . | in | in |\ / in | | in |\ |. . . . . . . | use | use | > /| use | > 0 | use | > / |. . . . . . . | | | | | \ | | / |. . . . --------+-----+-----+-----+-----+---\-+-----+-/---+-------- \ / ------- Listing 1 mem.h ----- /* mem.h - defs for fixed size block memory allocator */ typedef int Align; union freelist { union freelist *next; /* next block on free list */ char memory; /* user data */ Align aligner; /* force alignment of blocks */ }; typedef union freelist Freelist; struct freelist_head { int size; /* size of a single elt incl. next ptr */ int bytes; /* if we run out, allocate memory by this many bytes */ Freelist *freelist; }; char *sbrk(), *new(); /* end of mem.h */ Listing 2 mem.c ----- /* mem.c - subroutines to allocate fixed-size blocks */ #include #include "mem.h" /* chop up big block into linked list of small blocks */ Freelist * /* return 0 for failure */ create_freelist(flh,bytes) struct freelist_head *flh; /* freelist head */ int bytes; /* new memory size */ { Freelist *current = (Freelist *)sbrk(bytes); if ((Freelist *)-1 == current) return(0); flh->freelist = current; while ((char *)current + flh->size < ((char *)flh->freelist + bytes)) { current-next = (Freelist *)(¤t->memory + flh->size); current = current->next; } current->next = NULL; return(current); } memory_init(flh,size,alloc1,alloc2) struct freelist_head *flh; /* freelist head */ int size; /* size of a single element */ int alloc1; /* number to allocate initially */ int alloc2; /* number to allocate if we run out */ { /* make block large enough to hold the linked list pointer */ flh->size = (size>sizeof(Freelist *)?size:sizeof(Freelist *)); /* set up for future allocations */ flh->bytes = flh->size * alloc2; if (0 == create_freelist(flh,flh->size*alloc1)) { fprintf(stderr,"memory_init: out of space"); exit(-1); } } char * new(flh) struct freelist_head *flh; { char *obj; if (flh->freelist == NULL && 0 == create_freelist(flh,flh->bytes)) { fprintf(stderr,"new: out of space"); return(0); } obj = &flh->freelist->memory; flh->freelist = flh->freelist->next; return(obj); } delete(flh,link) struct freelist_head *flh; Freelist *link; { link->next = flh->freelist; flh->freelist = link; }