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