|
|
1.1 ! root 1: #include "defs" ! 2: ! 3: #define NHISTO 50 ! 4: int histo[NHISTO]; ! 5: ! 6: int mem[MEMSIZE]; ! 7: unsigned int nmemused = 0; ! 8: unsigned int nmemavail = 0; ! 9: long int totalloc = 0; ! 10: long int totfreed = 0; ! 11: ! 12: int nexpblocks = 0; ! 13: ptr expblocks = 0; ! 14: int nexcblocks = 0; ! 15: ptr excblocks = 0; ! 16: ptr chains = 0; ! 17: ! 18: ptr alloc(), calloc(), malloc(); ! 19: ! 20: ptr intalloc(n) ! 21: int n; ! 22: { ! 23: int *p; ! 24: ! 25: /*debug*/ if(n>sizeof(struct genblock)) fatal1("intalloc(%d)", n); ! 26: if( (p = calloc(1,n)) == NULL) ! 27: { ! 28: if(memdump) ! 29: prmem(); ! 30: fatal1("Line %d: Cannot allocate memory", yylineno); ! 31: } ! 32: ! 33: return(p); ! 34: } ! 35: ! 36: ! 37: ! 38: ! 39: ptr calloc(m,n) ! 40: int m, n; ! 41: { ! 42: return(alloc(m*n)); ! 43: } ! 44: ! 45: ! 46: ! 47: ptr malloc(m) ! 48: int m; ! 49: { ! 50: return(alloc(m)); ! 51: } ! 52: ! 53: ! 54: ! 55: /* Very stupid memory allocator. Stores a count word before ! 56: each block; negative if idle, positive if busy. ! 57: Looks for a block big enough for current request, and splits it ! 58: if necessary. Does not coalesce, always starts at bottom of memory. ! 59: Checks validity of all count words it encounters. ! 60: */ ! 61: ! 62: ! 63: ptr alloc(k) ! 64: register int k; ! 65: { ! 66: int *p; ! 67: register int i, j; ! 68: ! 69: k = (k + sizeof(int)-1) / sizeof(int); ! 70: if(k <=0) fprintf(diagfile, "alloc(%d words)\n", k); ! 71: else if(k >= NHISTO) ++histo[0]; ! 72: else ++histo[k]; ! 73: totalloc += k; ! 74: if(k > 256) fprintf(diagfile, "calloc(%d words)\n", k); ! 75: ! 76: /* look for a large enough slot */ ! 77: if(nmemavail > k) ! 78: for(i=0 ; i<nmemused ; ) ! 79: { ! 80: j = mem[i]; ! 81: if(j>256) ! 82: { ! 83: fprintf(diagfile, "Bad count word %d\n", j); ! 84: goto die; ! 85: } ! 86: if(j>=0 || (j = -j)<k) ! 87: i += (j+1); ! 88: else { ! 89: if(j > 256) ! 90: { ! 91: fprintf(diagfile, "Bad count word %d\n", j); ! 92: goto die; ! 93: } ! 94: mem[i] = k; ! 95: if(j > k) ! 96: mem[i+k+1] = -(j-k-1); ! 97: for(j = i+k ; j>i ; --j) ! 98: mem[j] = 0; ! 99: nmemavail -= (k+1); ! 100: return(mem + i+1); ! 101: } ! 102: } ! 103: ! 104: /* otherwise try to advance the fence */ ! 105: mem[nmemused] = k; ! 106: p = mem + nmemused + 1; ! 107: nmemused += (k+1); ! 108: if(nmemused >= MEMSIZE) ! 109: { ! 110: die: ! 111: /*debug*/ fprintf(diagfile, "Highwater mark %d words. ", nmemused); ! 112: /*debug*/ fprintf(diagfile, "%ld words left over\n", totalloc-totfreed); ! 113: /* prmem(); */ ! 114: fatal1("Line %d: out of memory", yylineno); ! 115: } ! 116: return(p); ! 117: } ! 118: ! 119: ! 120: ! 121: cfree(p) ! 122: ptr p; ! 123: { ! 124: if(p==0) ! 125: fatal("cfree(0)"); ! 126: free(p); ! 127: } ! 128: ! 129: ! 130: ! 131: ! 132: free(p) ! 133: register unsigned int *p; ! 134: { ! 135: if(p<=mem || p>mem+nmemused) ! 136: { ! 137: fprintf(diagfile, "attempt to free an unallocated block, "); ! 138: goto bad; ! 139: } ! 140: if(p[-1]>256 || p[-1]<0) ! 141: { ! 142: fprintf(diagfile, "attempted to free a block of length %u\n",p[-1]); ! 143: bad: fprintf(diagfile, "location %o ", p); ! 144: fprintf(diagfile, "mem=%o lastused=%o\n", mem, mem+nmemused); ! 145: /* if(p[-1]>256 || p[-1]<0) */ ! 146: fatal(""); ! 147: } ! 148: totfreed += p[-1]; ! 149: nmemavail += p[-1]+1; ! 150: p[-1] = - p[-1]; ! 151: ; ! 152: } ! 153: ! 154: ! 155: prhisto() ! 156: { ! 157: int i; ! 158: fprintf(diagfile, "allocation histogram:\n%4d big blocks\n",histo[0]); ! 159: for(i=1;i<NHISTO;++i) ! 160: if(histo[i]>0) fprintf(diagfile, "%4d %2d-word blocks\n", histo[i],i); ! 161: } ! 162: ! 163: ! 164: ! 165: ! 166: ! 167: ptr allexpblock() ! 168: { ! 169: ptr p; ! 170: ! 171: if(expblocks) ! 172: { ! 173: p = expblocks; ! 174: expblocks = expblocks->leftp; ! 175: zeroout(p, sizeof(struct exprblock)); ! 176: --nexpblocks; ! 177: return(p); ! 178: } ! 179: else return( ALLOC(exprblock) ); ! 180: } ! 181: ! 182: ! 183: ! 184: ! 185: frexpblock(p) ! 186: register ptr p; ! 187: { ! 188: if ( p[-1] != sizeof(struct exprblock)/sizeof(int) ) ! 189: badtag("frexpblock", p->tag); ! 190: if(nexpblocks < EXPRPOOL) ! 191: { ! 192: p->leftp = expblocks; ! 193: p->tag = 0; ! 194: expblocks = p; ! 195: ++nexpblocks; ! 196: } ! 197: else cfree(p); ! 198: } ! 199: ! 200: ! 201: ! 202: ! 203: ptr allexcblock() ! 204: { ! 205: ptr p; ! 206: ! 207: if(excblocks) ! 208: { ! 209: p = excblocks; ! 210: excblocks = excblocks->leftp; ! 211: zeroout(p, sizeof(struct execblock)); ! 212: --nexcblocks; ! 213: return(p); ! 214: } ! 215: else return( ALLOC(execblock) ); ! 216: } ! 217: ! 218: ! 219: ! 220: ! 221: frexcblock(p) ! 222: register ptr p; ! 223: { ! 224: if( p[-1] != sizeof(struct execblock)/sizeof(int) ) ! 225: fatal1("invalid frexcblock block of size %d", p[-1]); ! 226: if(nexcblocks < EXECPOOL) ! 227: { ! 228: p->leftp = excblocks; ! 229: p->tag = 0; ! 230: excblocks = p; ! 231: ++nexcblocks; ! 232: } ! 233: else cfree(p); ! 234: } ! 235: ! 236: ! 237: ! 238: zeroout(p,n) ! 239: register int *p; ! 240: int n; ! 241: { ! 242: register int *pn; ! 243: ! 244: pn = p + (n + sizeof(int)-1)/sizeof(int); ! 245: ! 246: while(p < pn) ! 247: *p++ = 0; ! 248: } ! 249: ! 250: ! 251: ! 252: ! 253: frchain(p0) ! 254: register chainp *p0; ! 255: { ! 256: register ptr p; ! 257: ! 258: if(p0==0 || *p0==0) return; ! 259: ! 260: for(p = *p0 ; p->nextp ; p = p->nextp) ! 261: p->datap = 0; ! 262: ! 263: p->datap = 0; ! 264: p->nextp = chains; ! 265: chains = *p0; ! 266: *p0 = 0; ! 267: } ! 268: ! 269: ! 270: chainp mkchain(p,q) ! 271: ptr p, q; ! 272: { ! 273: register chainp r; ! 274: ! 275: if(chains) ! 276: { ! 277: r = chains; ! 278: chains = chains->nextp; ! 279: } ! 280: else r = ALLOC(chain); ! 281: r->datap = p; ! 282: r->nextp = q; ! 283: return(r); ! 284: } ! 285: ! 286: ! 287: ! 288: ! 289: prmem() ! 290: { ! 291: register int i,j; ! 292: ! 293: fprintf(diagfile, "Memory dump:\n"); ! 294: ! 295: for(i=0 ; i<nmemused ; ) ! 296: { ! 297: j = mem[i]; ! 298: fprintf(diagfile, "Loc %6o = Word %5d ", mem+i, i); ! 299: if(j<0) ! 300: fprintf(diagfile, "Idle block length %4d ", j = -j); ! 301: else fprintf(diagfile, "Busy block length %4d ", j); ! 302: fprintf(diagfile, "tag %3d", mem[i+1].tag); ! 303: if(mem[i+1].tag==TNAME && mem[i+1].sthead!=0) ! 304: fprintf(diagfile, " varname %s", mem[i+1].sthead->namep); ! 305: else if(j==2) ! 306: fprintf(diagfile, " chain %o %o", mem[i+1], mem[i+2]); ! 307: else if (mem[i+1].tag > TIOSTAT) ! 308: { ! 309: char *s, *sn; ! 310: s = & mem[i+1]; ! 311: sn = s + 12; ! 312: fprintf(diagfile, " \""); ! 313: while(*s!= '\0' && s<sn) ! 314: putc(*s++, diagfile); ! 315: } ! 316: fprintf(diagfile, "\n"); ! 317: ! 318: i += j+1; ! 319: } ! 320: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.