home *** CD-ROM | disk | FTP | other *** search
- /* alloc.c - memory allocator
- *
- * The point of this is that it is about 4 times faster than MANX malloc/free
- * in c.lib. Malloc in heapmem.o will not allocate a second heap if the first
- * is exhausted.
- * :ts=8
- */
-
-
- #define NULL 0L
- #define HOWMUCH 4096L /* how much memory to AllocMem() at a time */
-
- typedef struct header {
- struct header *next; /* next block */
- unsigned long size; /* block size */
- };
-
- struct header first;
-
- struct header *head = NULL; /* start of list */
-
-
- char *alloc (bytes)
- unsigned bytes;
- {
- struct header *getmem ();
- register struct header *p, *q;
- register long size;
-
- size = (((bytes + 2 * sizeof (struct header) - 1) >> 3) << 3);
- if ((q = head) == NULL) {
- first.next = head = q = &first;
- first.size = 0L;
- }
- for (p = q->next; ; q = p, p = p->next) {
- if (p->size >= size) { /* if this block is large enough */
- if (p->size == size)
- q ->next = p->next;
- else { /* remove memory from tail of block */
- p->size -= size;
- p = (struct header *) ((char *) p + p->size);
- p->size = size;
- }
- head = q;
- p->next = NULL;
- return ((char *) (p+1));
- }
- if (p == head) /* back where we started */
- if ((p = getmem ()) == NULL)
- return (NULL); /* cannot allocate memory */
- }
- }
-
-
- /* freeit - put block back in free list */
-
- freeit (ptr)
- char *ptr;
- {
- register struct header *p, *q;
-
- p = (struct header *) ptr - 1;
- for (q = head; ; q = q->next) {
- if (p > q && p < q->next)
- break; /* new block goes between q & q->next */
- if (q >= q->next && p > q)
- break; /* new block goes at end of list */
- if (q >= q->next && p < q->next)
- break; /* new block goes at beginning of list */
- }
-
- if ((struct header *) ((char *) p + p->size) == q->next) {
- p->size += q->next->size;
- p->next = q->next->next;
- } else {
- p->next = q->next;
- }
- if ((struct header *) ((char *) q + q->size) == p) {
- q->size += p->size;
- q->next = p->next;
- } else {
- q->next = p;
- }
- head = q;
- }
-
-
- /* getmem - request more memory from system */
-
- struct header *getmem ()
- {
- char *AllocMem ();
- register struct header *up;
-
- if ((up = (struct header *) AllocMem (HOWMUCH, 0L)) == NULL)
- return (NULL); /* can't get more memory */
- up->next = NULL;
- up->size = HOWMUCH;
- freeit ((char *) (up + 1));
- return (head);
- }
-
-
- quit (code)
- int code;
- {
- register struct header *p, *q;
- unsigned long size;
-
- p = head;
- do {
- if (p == NULL)
- break;
- q = p->next;
- if ((size = p->size) > 0L) {
- p->size = 0L;
- FreeMem (p, size);
- }
- p = q;
- } while (p != head);
- exit (code);
- }
-