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