|
|
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.