1: /*************************************************************************
   2:  * This program is copyright (C) 1985, 1986 by Jonathan Payne.  It is    *
   3:  * provided to you without charge for use only on a licensed Unix        *
   4:  * system.  You may copy JOVE provided that this notice is included with *
   5:  * the copy.  You may not sell copies of this program or versions        *
   6:  * modified for use on microcomputer systems, unless the copies are      *
   7:  * included with a Unix system distribution and the source is provided.  *
   8:  *************************************************************************/
   9: 
  10: #include "tune.h"
  11: 
  12: #ifdef MY_MALLOC
  13: 
  14: /*	avoid break bug */
  15: #ifdef pdp11
  16: #	define GRANULE 64
  17: #else
  18: #	define GRANULE 0
  19: #endif
  20: 
  21: /*	C storage allocator
  22:  *	circular first-fit strategy
  23:  *	works with noncontiguous, but monotonically linked, arena
  24:  *	each block is preceded by a ptr to the (pointer of)
  25:  *	the next following block
  26:  *	blocks are exact number of words long
  27:  *	aligned to the data type requirements of ALIGN
  28:  *	pointers to blocks must have BUSY bit 0
  29:  *	bit in ptr is 1 for busy, 0 for idle
  30:  *	gaps in arena are merely noted as busy blocks
  31:  *	last block of arena (pointed to by alloct) is empty and
  32:  *	has a pointer to first
  33:  *	idle blocks are coalesced during space search
  34:  *
  35:  *	a different implementation may need to redefine
  36:  *	ALIGN, NALIGN, BLOCK, BUSY, INT
  37:  *	where INT is integer type to which a pointer can be cast
  38:  */
  39: 
  40: #define INT     int
  41: #define ALIGN       int
  42: #define NALIGN      1
  43: #define WORD        sizeof(union store)
  44: #define BLOCK       1024    /* a multiple of WORD*/
  45: #define BUSY        1
  46: #define NULL        0
  47: #define testbusy(p) ((INT)(p)&BUSY)
  48: #define setbusy(p)  (union store *) ((INT) (p) | BUSY)
  49: #define clearbusy(p)    (union store *) ((INT) (p) &~ BUSY)
  50: 
  51: union store {
  52:     union store *ptr;
  53:     ALIGN   dummy[NALIGN];
  54:     int calloc;     /*calloc clears an array of integers*/
  55: };
  56: 
  57: static union store  allocs[2],  /*initial arena*/
  58:             *allocp,    /*search ptr*/
  59:             *alloct,    /*arena top*/
  60:             *allocx;    /*for benefit of realloc*/
  61: 
  62: char    *sbrk();
  63: 
  64: char *
  65: malloc(nbytes)
  66: unsigned int    nbytes;
  67: {
  68:     register union store    *p,
  69:                 *q;
  70:     register int    nw;
  71:     static int  temp;   /* coroutines assume no auto */
  72: 
  73:     if (allocs[0].ptr == 0) {   /* first time */
  74:         allocs[0].ptr = setbusy(&allocs[1]);
  75:         allocs[1].ptr = setbusy(&allocs[0]);
  76:         alloct = &allocs[1];
  77:         allocp = &allocs[0];
  78:     }
  79:     nw = (nbytes + WORD + WORD - 1) / WORD;
  80:     for (p = allocp; ; ) {
  81:         for (temp = 0; ; ) {
  82:             if (!testbusy(p->ptr)) {
  83:                 while (!testbusy((q = p->ptr)->ptr))
  84:                     p->ptr = q->ptr;
  85:                 if(q >= p + nw && p + nw >= p)
  86:                     goto found;
  87:             }
  88:             q = p;
  89:             p = clearbusy(p->ptr);
  90:             if (p > q)
  91:                 ;
  92:             else if (q != alloct || p != allocs)
  93:                 return NULL;
  94:             else if (++temp > 1)
  95:                 break;
  96:         }
  97:         temp = ((nw + BLOCK/WORD) / (BLOCK/WORD)) * (BLOCK/WORD);
  98:         q = (union store *) sbrk(0);
  99:         if (q + temp + GRANULE < q)
 100:             return NULL;
 101:         q = (union store *) sbrk(temp * WORD);
 102:         if ((INT) q == -1)
 103:             return NULL;
 104:         alloct->ptr = q;
 105:         if (q != alloct+1)
 106:             alloct->ptr = setbusy(alloct->ptr);
 107:         alloct = q->ptr = q + temp - 1;
 108:         alloct->ptr = setbusy(allocs);
 109:     }
 110: found:
 111:     allocp = p + nw;
 112:     if (q > allocp) {
 113:         allocx = allocp->ptr;
 114:         allocp->ptr = p->ptr;
 115:     }
 116:     p->ptr = setbusy(allocp);
 117:     return (char *) (p + 1);
 118: }
 119: 
 120: /* freeing strategy tuned for LIFO allocation */
 121: 
 122: free(ap)
 123: register char   *ap;
 124: {
 125:     register union store    *p = (union store *) ap;
 126: 
 127:     allocp = --p;
 128:     p->ptr = clearbusy(p->ptr);
 129: }
 130: 
 131: /*	realloc(p, nbytes) reallocates a block obtained from malloc()
 132:  *	and freed since last call of malloc()
 133:  *	to have new size nbytes, and old content
 134:  *	returns new location, or 0 on failure
 135: */
 136: 
 137: char *
 138: realloc(obj, nbytes)
 139: char    *obj;
 140: unsigned int    nbytes;
 141: {
 142:     register union store    *q,
 143:                 *p = (union store *) obj;
 144:     union store *s,
 145:             *t;
 146:     register unsigned int   nw;
 147:     unsigned int    onw;
 148: 
 149:     if (testbusy(p[-1].ptr))
 150:         free((char *) p);
 151:     onw = p[-1].ptr - p;
 152:     q = (union store *) malloc(nbytes);
 153:     if(q == NULL || q == p)
 154:         return((char *) q);
 155:     s = p;
 156:     t = q;
 157:     nw = (nbytes + WORD - 1)/WORD;
 158:     if (nw < onw)
 159:         onw = nw;
 160:     while (onw-- != 0)
 161:         *t++ = *s++;
 162:     if(q < p && q + nw >= p)
 163:         (q + (q+nw-p))->ptr = allocx;
 164:     return (char *) q;
 165: }
 166: 
 167: #endif MY_MALLOC

Defined functions

Defined variables

allocp defined in line 58; used 8 times
allocs defined in line 57; used 9 times
alloct defined in line 59; used 8 times
allocx defined in line 60; used 2 times

Defined union's

store defined in line 51; used 22 times

Defined macros

ALIGN defined in line 41; used 1 times
  • in line 53
BLOCK defined in line 44; used 3 times
  • in line 97(3)
BUSY defined in line 45; used 3 times
GRANULE defined in line 18; used 1 times
  • in line 99
INT defined in line 40; used 4 times
NALIGN defined in line 42; used 1 times
  • in line 53
NULL defined in line 46; used 4 times
WORD defined in line 43; used 9 times
clearbusy defined in line 49; used 2 times
setbusy defined in line 48; used 5 times
testbusy defined in line 47; used 3 times
Last modified: 1986-03-28
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1179
Valid CSS Valid XHTML 1.0 Strict