home *** CD-ROM | disk | FTP | other *** search
- static char sccs_id[] = "@(#) alloc.c 5.0 " __DATE__ " HJR";
-
- /* alloc.c (c) Copyright 1990 H.Rogers */
-
- /* features multiple free lists hashed on block size */
-
- #include <stddef.h>
- #include <stdlib.h>
- #include <string.h>
-
- #ifdef M_DEBUG
- #include <stdio.h>
- #include <signal.h>
-
- static int
- __m_fail (char *exp, char *file, int line)
- {
- fprintf (stderr, "\n\"%s\", line %d: Assertion failed: %s\n", file, line, exp);
- raise (SIGABRT);
- return (0);
- }
-
- #define assert(x) (void)((x) ? 0 : __m_fail(#x,__FILE__,__LINE__))
-
- #define addr(x) ((x) ? (*((int *)(x)) | 1) : 0)
-
- #define MAGIC 0x4349474d
- #endif
-
- extern void *sbrk (int);
-
- typedef struct _blk
- {
- #ifdef M_DEBUG
- int magic;
- #endif
- struct _blk *next;
- size_t size;
- }
- blk;
-
- #ifdef M_DEBUG
- #define BLKSIZ 16 /* smallest power of 2 >= sizeof(blk) */
- #else
- #define BLKSIZ 8
- #endif
-
- #define blkalign(x) (((x) + (BLKSIZ<<1) - 1) & (~(BLKSIZ - 1)))
-
- #define NFL 8
-
- static blk __fl[NFL];
- static size_t __flmin[NFL] =
- {
- 4096 + BLKSIZ,
- 1024 + BLKSIZ,
- 256 + BLKSIZ,
- 64 + BLKSIZ,
- 32 + BLKSIZ,
- 16 + BLKSIZ,
- 8 + BLKSIZ,
- 0 + BLKSIZ /* catchall */
- };
-
- #define MEMINC 12 /* sbrk() memory block bit alignment */
-
- void
- __allocinit (void)
- {
- register blk *b;
- register int i;
-
- #ifdef M_DEBUG
- assert (sizeof (struct _blk) <= BLKSIZ);
- #endif
-
- for (i = 0; i < NFL; i++)
- {
- b = __fl + i;
- b->next = b;
- b->size = BLKSIZ;
- #ifdef M_DEBUG
- b->magic = MAGIC;
- #endif
- }
- }
-
- static blk *
- findblk (register int i, register blk * a)
- {
- register blk *b, *p;
-
- p = __fl + i;
- b = p->next;
-
- #ifdef M_DEBUG
- assert (addr (p));
- assert (p->magic == MAGIC);
- #endif
-
- while (b > p)
- {
- #ifdef M_DEBUG
- assert (addr (b));
- assert (b->magic == MAGIC);
- #endif
- if (b >= a)
- break;
- p = b;
- b = b->next;
- }
-
- return (p);
- }
-
- #define addblk(i,n,p) ((n)->next = (p)->next,(p)->next = (n))
-
- #define delblk(i,b,p) ((p)->next = (b)->next)
-
- static void
- concatblk (register blk * a, register blk * p)
- {
- register blk *b;
-
- if (!p)
- return;
-
- b = p->next;
-
- while ((char *) a + a->size == (char *) b)
- {
- a->size += b->size;
- #ifdef M_DEBUG
- b->magic = 0;
- #endif
- b = b->next;
- }
-
- p->next = b;
- }
-
- static int
- flindex (register int size)
- {
- register int i;
-
- for (i = 0; size < __flmin[i]; i++);
-
- return (i);
- }
-
- static blk *
- findsize (register int i, register int size, register blk ** p_)
- {
- register blk *b, *p;
-
- p = __fl + i;
- b = p->next;
-
- while (b > p)
- {
- if (b->size >= size)
- {
- delblk (i, b, p);
- break;
- }
- p = b;
- b = b->next;
- }
-
- if (p_)
- *p_ = p;
- return (b);
- }
-
- void *
- malloc (register size_t size)
- {
- register blk *b;
- register int i;
- blk *p;
-
- if (!size)
- return (0);
-
- size = blkalign (size);
-
- i = flindex (size);
-
- b = findsize (i, size, &p);
-
- if (b <= p)
- {
- register void *m;
- register int _size;
-
- _size = ((size >> MEMINC) + 1) << MEMINC;
- if ((m = sbrk (_size)) == (void *) -1)
- return (0);
-
- if ((char *) p + p->size == (char *) m)
- {
- b = p;
- p = findblk (i, b);
- delblk (i, b, p);
- b->size += _size;
- }
- else
- {
- b = (blk *) m;
- b->size = _size;
- #ifdef M_DEBUG
- b->magic = MAGIC;
- #endif
- }
- }
-
- #ifdef M_DEBUG
- assert (addr (b));
- assert (b->magic == MAGIC);
- #endif
-
- if (b->size > (size + __flmin[i]))
- {
- register blk *n;
-
- n = (blk *) ((char *) b + size);
-
- addblk (i, n, p);
-
- n->size = b->size - size;
- #ifdef M_DEBUG
- n->magic = MAGIC;
- #endif
- b->size = size;
- }
-
- return ((void *) ((char *) b + BLKSIZ));
- }
-
- void *
- realloc (register void *_a, register size_t size)
- {
- register blk *a;
- register int i;
- blk *p;
-
- if (!(_a))
- return (malloc (size));
-
- if (!size)
- {
- free (_a);
- return (0);
- }
-
- size = blkalign (size);
-
- #ifdef M_DEBUG
- assert (addr (_a));
- #endif
-
- a = (blk *) ((char *) _a - BLKSIZ);
-
- #ifdef M_DEBUG
- assert (addr (a));
- assert (a->magic == MAGIC);
- #endif
-
- i = flindex (a->size);
-
- p = findblk (i, a);
-
- concatblk (a, p);
-
- if (a->size < size)
- {
- if ((char *) p + p->size == (char *) a && p->size + a->size >= size)
- {
- register blk *b;
-
- #ifdef M_DEBUG
- assert (addr (p));
- assert (p->magic == MAGIC);
- #endif
- b = p;
- p = findblk (i, b);
- delblk (i, b, p);
- b->size += a->size;
- #ifdef M_DEBUG
- a->magic = 0;
- #endif
- memmove ((char *) b + BLKSIZ, _a, a->size - BLKSIZ);
- _a = (char *) (a = b) + BLKSIZ;
- }
- else
- {
- register void *m;
- register int _size;
-
- _size = ((size >> MEMINC) + 1) << MEMINC;
- if ((m = sbrk (_size)) == (void *) -1)
- return (0);
-
- if ((char *) a + a->size == (char *) m)
- a->size += _size;
- else
- {
- register blk *b;
-
- addblk (i, a, p);
- b = (blk *) m;
- b->size = _size;
- #ifdef M_DEBUG
- b->magic = MAGIC;
- #endif
- memcpy ((char *) b + BLKSIZ, _a, a->size - BLKSIZ);
- _a = (char *) (a = b) + BLKSIZ;
- }
- }
- }
-
- i = flindex (size);
-
- if (a->size > (size + __flmin[i]))
- {
- register blk *n;
-
- p = findblk (i, a);
-
- n = (blk *) ((char *) a + size);
-
- addblk (i, n, p);
-
- n->size = a->size - size;
- #ifdef M_DEBUG
- n->magic = MAGIC;
- #endif
- a->size = size;
- }
-
- return (_a);
- }
-
- void
- free (register void *_a)
- {
- register blk *a, *p;
- register int i;
-
- if (!_a)
- return;
-
- #ifdef M_DEBUG
- assert (addr (_a));
- #endif
-
- a = (blk *) ((char *) _a - BLKSIZ);
-
- #ifdef M_DEBUG
- assert (addr (a));
- assert (a->magic == MAGIC);
- #endif
-
- i = flindex (a->size);
-
- p = findblk (i, a);
-
- concatblk (a, p);
-
- if ((char *) p + p->size == (char *) a)
- {
- p->size += a->size;
- #ifdef M_DEBUG
- a->magic = 0;
- #endif
- }
- else
- addblk (i, a, p);
- }
-
- #ifdef M_DEBUG
- void
- __m_debug (void) /* dump free lists */
- {
- register blk *b;
- register int i;
-
- for (i = 0; i < NFL; i++)
- {
- printf ("\nfl: %d ( >= %d )\n", i, __flmin[i] - BLKSIZ);
- b = __fl + i;
- do
- {
- b = b->next;
- printf ("%7x: next: %7x [%7x] size: %x\n", b, b->next,
- (char *) b + b->size, b->size - BLKSIZ);
- assert (addr (b));
- assert (b->magic == MAGIC);
- }
- while (b->next > b);
- }
- putchar ('\n');
- }
- #endif
-