BSD 4_3 development
[unix-history] / usr / src / usr.bin / efl / alloc.c
CommitLineData
832026c6
C
1#include "defs"
2
3#define NHISTO 50
4int histo[NHISTO];
5
6int mem[MEMSIZE];
7unsigned int nmemused = 0;
8unsigned int nmemavail = 0;
9long int totalloc = 0;
10long int totfreed = 0;
11
12int nexpblocks = 0;
13ptr expblocks = 0;
14int nexcblocks = 0;
15ptr excblocks = 0;
16ptr chains = 0;
17
18ptr alloc(), calloc(), malloc();
19
20ptr intalloc(n)
21int n;
22{
23int *p;
24
25/*debug*/ if(n>sizeof(struct genblock)) fatal1("intalloc(%d)", n);
26if( (p = calloc(1,n)) == NULL)
27 {
28 if(memdump)
29 prmem();
30 fatal1("Line %d: Cannot allocate memory", yylineno);
31 }
32
33return(p);
34}
35
36
37
38
39ptr calloc(m,n)
40int m, n;
41{
42return(alloc(m*n));
43}
44
45
46
47ptr malloc(m)
48int m;
49{
50return(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
63ptr alloc(k)
64register int k;
65{
66int *p;
67register int i, j;
68
69k = (k + sizeof(int)-1) / sizeof(int);
70if(k <=0) fprintf(diagfile, "alloc(%d words)\n", k);
71else if(k >= NHISTO) ++histo[0];
72else ++histo[k];
73totalloc += k;
74if(k > 256) fprintf(diagfile, "calloc(%d words)\n", k);
75
76/* look for a large enough slot */
77if(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 */
105mem[nmemused] = k;
106p = mem + nmemused + 1;
107nmemused += (k+1);
108if(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 }
116return(p);
117}
118
119
120
121cfree(p)
122ptr p;
123{
124if(p==0)
125 fatal("cfree(0)");
126free(p);
127}
128
129
130
131
132free(p)
133register unsigned int *p;
134{
135if(p<=mem || p>mem+nmemused)
136 {
137 fprintf(diagfile, "attempt to free an unallocated block, ");
138 goto bad;
139 }
140if(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 }
148totfreed += p[-1];
149nmemavail += p[-1]+1;
150p[-1] = - p[-1];
151;
152}
153
154
155prhisto()
156{
157int i;
158fprintf(diagfile, "allocation histogram:\n%4d big blocks\n",histo[0]);
159for(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
167ptr allexpblock()
168{
169ptr p;
170
171if(expblocks)
172 {
173 p = expblocks;
174 expblocks = expblocks->leftp;
175 zeroout(p, sizeof(struct exprblock));
176 --nexpblocks;
177 return(p);
178 }
179else return( ALLOC(exprblock) );
180}
181
182
183
184
185frexpblock(p)
186register ptr p;
187{
188if ( p[-1] != sizeof(struct exprblock)/sizeof(int) )
189 badtag("frexpblock", p->tag);
190if(nexpblocks < EXPRPOOL)
191 {
192 p->leftp = expblocks;
193 p->tag = 0;
194 expblocks = p;
195 ++nexpblocks;
196 }
197else cfree(p);
198}
199
200
201
202
203ptr allexcblock()
204{
205ptr p;
206
207if(excblocks)
208 {
209 p = excblocks;
210 excblocks = excblocks->leftp;
211 zeroout(p, sizeof(struct execblock));
212 --nexcblocks;
213 return(p);
214 }
215else return( ALLOC(execblock) );
216}
217
218
219
220
221frexcblock(p)
222register ptr p;
223{
224if( p[-1] != sizeof(struct execblock)/sizeof(int) )
225 fatal1("invalid frexcblock block of size %d", p[-1]);
226if(nexcblocks < EXECPOOL)
227 {
228 p->leftp = excblocks;
229 p->tag = 0;
230 excblocks = p;
231 ++nexcblocks;
232 }
233else cfree(p);
234}
235
236
237
238zeroout(p,n)
239register int *p;
240int n;
241{
242register int *pn;
243
244pn = p + (n + sizeof(int)-1)/sizeof(int);
245
246while(p < pn)
247 *p++ = 0;
248}
249
250
251
252
253frchain(p0)
254register chainp *p0;
255{
256register ptr p;
257
258if(p0==0 || *p0==0) return;
259
260for(p = *p0 ; p->nextp ; p = p->nextp)
261 p->datap = 0;
262
263p->datap = 0;
264p->nextp = chains;
265chains = *p0;
266*p0 = 0;
267}
268
269
270chainp mkchain(p,q)
271ptr p, q;
272{
273register chainp r;
274
275if(chains)
276 {
277 r = chains;
278 chains = chains->nextp;
279 }
280else r = ALLOC(chain);
281r->datap = p;
282r->nextp = q;
283return(r);
284}
285
286
287
288
289prmem()
290{
291register int i,j;
292
293fprintf(diagfile, "Memory dump:\n");
294
295for(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}