1: #define debug YES
   2: #ifndef debug
   3: #define ASSERT(p)
   4: #endif
   5: #ifdef debug
   6: #define ASSERT(p) if(!(p))botch("p");else
   7: botch(s)
   8: char *s;
   9: {
  10:     printf("assertion botched: %s\n",s);
  11:     abort();
  12: }
  13: #endif
  14: /*	C storage allocator
  15:  *	circular first-fit strategy
  16:  *	works with noncontiguous, but monotonically linked, arena
  17:  *	each block is preceded by a ptr to the (pointer of)
  18:  *	the next following block
  19:  *	blocks are exact number of words long; BUSY
  20:  *	bit in ptr is 1 for busy, 0 for idle
  21:  *	gaps in arena are merely noted as busy blocks
  22:  *	last block of arena (pointed to by alloct) is empty and
  23:  *	has a pointer to first
  24:  *	idle blocks are coalesced during space search
  25: */
  26: /*	all these defines must be powers of 2 */
  27: #define WORD sizeof(struct store)
  28: #define BLOCK 1024
  29: #define BUSY 1
  30: #define NULL 0
  31: #define testbusy(p) ((int)(p)&BUSY)
  32: #define setbusy(p) (struct store *)((int)(p)+BUSY)
  33: #define clearbusy(p) (struct store *)((int)(p)&~BUSY)
  34: 
  35: struct store { struct store *ptr; };
  36: 
  37: struct store allocs[] = {   /*initial arena*/
  38:     setbusy(&allocs[1].ptr),
  39:     setbusy(&allocs[0].ptr)
  40: };
  41: struct store *allocp = &allocs[1];  /*search ptr*/
  42: struct store *alloct = &allocs[1];  /*arena top*/
  43: struct store *allocx = 0;       /*for benefit of realloc*/
  44: struct store *sbrk();
  45: 
  46: struct store *
  47: malloc(nbytes)
  48: unsigned nbytes;
  49: {
  50:     struct store *p, *q;
  51:     register nw;
  52:     static temp;    /*coroutines assume no auto*/
  53: 
  54: #ifdef verbose
  55:     printf("malloc(%d) ",nbytes);
  56: #endif
  57:     nw = (nbytes+2*WORD-1)/WORD;
  58:     ASSERT(allocp>allocs && allocp<=alloct);
  59:     for(p=allocp; ; ) {
  60:         for(temp=0; ; ) {
  61:             if(!testbusy(p->ptr)) {
  62:                 while(!testbusy((q=p->ptr)->ptr)) {
  63:                     ASSERT(q>p&&q<alloct);
  64:                     p->ptr = q->ptr;
  65:                 }
  66:                 if(q>=p+nw && p+nw>=p)
  67:                     goto found;
  68:             }
  69:             q = p;
  70:             p = clearbusy(p->ptr);
  71:             if(p>q)
  72:                 ASSERT(p<=alloct);
  73:             else if(q!=alloct || p!=allocs) {
  74:                 write(2,"corrupt arena\n",14);
  75: #ifdef debug
  76:                 abort();
  77: #endif
  78:                 exit(0175);
  79:             } else if(++temp>1)
  80:                 break;
  81:         }
  82:         temp = (nw+BLOCK/WORD)&~(BLOCK/WORD-1);
  83:         q = sbrk(temp*WORD); /*SYSDEP*/
  84:         if((int)q == -1)
  85:             return(NULL);
  86:         ASSERT(q>alloct);
  87:         alloct->ptr = q;
  88:         if(q!=alloct+1)
  89:             alloct->ptr = setbusy(alloct->ptr);
  90:         alloct = q->ptr = q+temp-1;
  91:         alloct->ptr = setbusy(allocs);
  92:     }
  93: found:
  94:     allocp = p + nw;
  95:     ASSERT(allocp<=alloct);
  96:     if(q>allocp) {
  97:         allocx = allocp->ptr;
  98:         allocp->ptr = p->ptr;
  99:     }
 100:     p->ptr = setbusy(allocp);
 101: #ifdef verbose
 102:     printf("= %o\n",p+1);
 103: #endif
 104:     return(p+1);
 105: }
 106: /*	freeing strategy tuned for LIFO allocation
 107: */
 108: free(p)
 109:  struct store *p;
 110: {
 111:     struct store *savep=p;
 112: #ifdef verbose
 113:     printf("free(%o)\n",p);
 114: #endif
 115:     ASSERT(p>clearbusy(allocs[1].ptr)&&p<=alloct);
 116:     allocp = --p;
 117:     ASSERT(testbusy(p->ptr));
 118:     p->ptr = clearbusy(p->ptr);
 119:     ASSERT(p->ptr > allocp && p->ptr <= alloct);
 120: }
 121: char *calloc(nbytes,count)
 122: {   char *c;
 123:     c=(char *)malloc(nbytes*count);
 124:     return(c);
 125: }
 126: /*
 127: ahist(s) char *s;
 128: {	char **ap;
 129: 	printf("%s allocp %o alloct %o\n",s,allocp,alloct);
 130: 	for(ap= allocs;ap<alloct;ap= *ap&~BUSY)
 131: 		if(*ap&BUSY) printf("%o ",ap);
 132: 	printf("\n");
 133: }
 134: */
 135: struct store *
 136: realloc(p, nbytes)
 137: register struct store *p;
 138: unsigned nbytes;
 139: {
 140:     register struct store *q;
 141:     struct store *s, *t;
 142:     register unsigned nw;
 143:     unsigned onw;
 144: 
 145:     onw = p[-1].ptr - p;
 146:     q = malloc(nbytes);
 147:     if(q==NULL || q==p)
 148:         return(q);
 149:     s = p;
 150:     t = q;
 151:     nw = (nbytes+WORD-1)/WORD;
 152:     if(nw<onw)
 153:         onw = nw;
 154:     while(onw--!=0)
 155:         (t++)->ptr = (s++)->ptr;
 156:     if(q<p && q+nw>=p)
 157:         (q+(q+nw-p))->ptr = allocx;
 158:     return(q);
 159: }

Defined functions

botch defined in line 7; used 1 times
  • in line 6
calloc defined in line 121; never used
free defined in line 108; never used
malloc defined in line 46; used 2 times
realloc defined in line 135; never used

Defined variables

allocp defined in line 41; used 11 times
allocs defined in line 37; used 8 times
alloct defined in line 42; used 14 times
allocx defined in line 43; used 2 times

Defined struct's

store defined in line 35; used 28 times

Defined macros

ASSERT defined in line 6; used 8 times
BLOCK defined in line 28; used 2 times
  • in line 82(2)
BUSY defined in line 29; used 3 times
NULL defined in line 30; used 2 times
WORD defined in line 27; used 7 times
clearbusy defined in line 33; used 3 times
debug defined in line 1; used 3 times
  • in line 2-5(2), 75
setbusy defined in line 32; used 5 times
testbusy defined in line 31; used 3 times
Last modified: 1979-01-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 624
Valid CSS Valid XHTML 1.0 Strict