home *** CD-ROM | disk | FTP | other *** search
- /*
- Full K&R malloc() and free() for AZTEC C II
-
- This module adapted for the CP/M environment from source code in Brian
- W. Kernighan and Dennis M. Ritchie's "The C Programming Language" by
- William C. Colley III -- 4 OCT 1982.
-
- This module implements the functions alloc(), morecore(), xsbrk(), and
- free() as per pp. 173-7 of Kernighan and Ritchie. Since xsbrk() is
- responsible for preventing collision between the allocated data and
- the stack, it must know how much space to leave for the stack. Thus,
- a function rsvstk() is provided to override the default 1024 bytes.
-
- The functions in this package are:
-
- char *alloc(nb) allocates a block of nb bytes and
- unsigned nb; returns a pointer to it. If no such
- block is available, the value NULL (0)
- is returned.
-
- free(blk) Attaches the storage allocation block
- char *blk; blk to the free list. Returns no
- meaningful value.
-
- HEADER *morecore(nb) Gets a storage allocation block of
- unsigned nb; size nb from the heap and returns a
- pointer to it. Returns NULL (0) if
- not enough space is available.
-
- char *xsbrk(nb) Gets nb bytes from the heap. Returns
- unsigned nb; a pointer to the bytes or -1 if not
- enough bytes are available.
-
- char *xsettop(nb) Gets nb bytes from the heap. Returns
- unsigned nb; a pointer to the bytes or NULL (0) if
- not enough bytes are available.
-
- rsvstk(stk) Changes the minimum allowable remaining
- unsigned stk; stack size at a call to xsbrk() to stk
- bytes. Default value is 1024 bytes.
- */
-
- #define NULL 0
-
- union header {
- struct {
- union header *ptr;
- unsigned size;
- } s;
- long l;
- };
-
- typedef union header HEADER;
-
- static HEADER base, *allocp = NULL;
-
- char *alloc(nb)
- unsigned nb;
- {
- HEADER *morecore();
- register HEADER *p, *q;
- register unsigned nu;
-
- nu = ((nb + 3) >> 2) + 1;
- if ((q = allocp) == NULL) {
- base.s.ptr = allocp = q = &base;
- base.s.size = 1;
- }
- for (p = q->s.ptr; ; q = p, p = p->s.ptr) {
- if (p->s.size >= nu) {
- if (p->s.size == nu) q->s.ptr = p->s.ptr;
- else {
- p->s.size -= nu;
- p += p->s.size;
- p->s.size = nu;
- }
- allocp = q; return (char *)(p + 1);
- }
- if (p == allocp)
- if ((p = morecore(nu)) == NULL) return NULL;
- }
- }
-
- HEADER *morecore(nu)
- unsigned nu;
- {
- char *xsbrk();
- register char *cp;
- register HEADER *up;
-
- if ((int)(cp = xsbrk(nu << 2)) == -1) return NULL;
- up = (HEADER *)cp;
- up->s.size = nu;
- free((char *)(up + 1));
- return allocp;
- }
-
- free(blk)
- char *blk;
- {
- register HEADER *p, *q;
-
- p = (HEADER *)blk - 1;
- for (q = allocp; !(p > q && p < q->s.ptr); q = q->s.ptr)
- if (q >= q ->s.ptr && (p > q || p < q->s.ptr)) break;
-
- if (p + p->s.size == q->s.ptr) {
- p->s.size += q->s.ptr->s.size;
- p->s.ptr = q->s.ptr->s.ptr;
- }
- else p->s.ptr = q->s.ptr;
- if (q + q->s.size == p) {
- q->s.size += p->s.size;
- q->s.ptr = p->s.ptr;
- }
- else q->s.ptr = p;
- allocp = q;
- }
-
- /* The functions xsbrk(), xsettop(), and rsvstk() live in the module xsbrk.mac
- as they have to beat on machine things like the stack pointer. */
-
-