1 /* ***********************************************************
  2    *                                                         *
  3    * Copyright, (C) Honeywell Bull Inc., 1987                *
  4    *                                                         *
  5    * Copyright, (C) Honeywell Information Systems Inc., 1986 *
  6    *                                                         *
  7    *********************************************************** */
  8 
  9 /* HISTORY COMMENTS:
 10   1) change(86-06-06,Westcott), approve(87-07-13,MCR7580),
 11      audit(87-07-13,Leskiw), install(87-08-07,MR12.1-1072):
 12      Created
 13                                                    END HISTORY COMMENTS */
 14 
 15 /* : PROCEDURE FUNCTION
 16 
 17 The following routines are general purpose "memory management" routines used
 18 to manage internal memory buffers.  They are direct copies from
 19 Kernigan & Ritchie.
 20 */
 21 
 22 #include <stdio.h>
 23 #include <alloc.h>
 24 
 25 char *wsalloc (mptr,nbytes)
 26 
 27 struct allocstr *mptr;
 28 unsigned nbytes;
 29 {
 30 HEADER *morecore();
 31 register HEADER *p, *q;
 32 register int nunits;
 33 
 34    nunits = 1+(nbytes+sizeof(HEADER) -1)/sizeof (HEADER);
 35    if ((q = mptr->m_allocp) == NULL) {  /* no free list yet */
 36       mptr->m_base.s.ptr = mptr->m_allocp =q = &mptr->m_base;
 37       mptr->m_base.s.size = 0;
 38    }
 39 
 40    for (p=q->s.ptr; ;q=p, p=p->s.ptr) {
 41       if (p->s.size >= nunits) {  /* big enough */
 42          if (p->s.size == nunits)    /* exactly */
 43             q->s.ptr = p->s.ptr;
 44          else {  /* allocate tail end */
 45             p->s.size -= nunits;
 46             p += p->s.size;
 47             p->s.size = nunits;
 48          }
 49          mptr->m_allocp = q;
 50          return ((char *) (p+1));
 51       }
 52       if ( p == mptr->m_allocp)  /* wrapped around free list */
 53          if ((p = morecore (mptr,nunits)) == NULL)
 54             return (NULL);  /* none left */
 55    }
 56 }
 57 
 58 wsfree (mptr,ap)
 59 
 60 struct allocstr *mptr;
 61 char *ap;
 62 {
 63 register HEADER *p, *q;
 64 
 65    p = (HEADER *) ap -1;  /* point to header */
 66    for (q=mptr->m_allocp; !(p > q && p < q->s.ptr); q=q->s.ptr)
 67       if (q >= q->s.ptr && (p > q || p < q->s.ptr))
 68          break;   /* at one end or other */
 69 
 70    if (p+p->s.size == q->s.ptr) {  /* join to upper neighbor */
 71       p->s.size += q->s.ptr->s.size;
 72       p->s.ptr = q->s.ptr->s.ptr;
 73    }
 74    else
 75       p->s.ptr = q->s.ptr;
 76    if (q+q->s.size == p) {  /* join to lower neighbor */
 77       q->s.size += p->s.size;
 78       q->s.ptr = p->s.ptr;
 79    }
 80    else
 81       q->s.ptr = p;
 82    mptr->m_allocp = q;
 83 }
 84 
 85 HEADER *morecore (mptr,nu)
 86 
 87 struct allocstr *mptr;
 88 unsigned nu;
 89 {
 90 register HEADER *up;
 91 char *cp;
 92 
 93    if (mptr->memory_used == 1)
 94       return(NULL);
 95    cp = mptr->memory;
 96    mptr->memory_used = 1;
 97    up = (HEADER *)cp;
 98    up->s.size = mptr->memory_size / sizeof (HEADER);
 99    wsfree (mptr,(char *) (up+1));
100    return (mptr->m_allocp);
101 }
102 ^Z