2 static char rcsid[] = "$Id: alloc.c,v 2.11 1994/06/24 10:39:37 ceriel Exp $";
16 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
17 * See the copyright notice in the ACK home directory, in the file "Copyright".
19 * Author: Hans van Staveren
26 #define newcore(size) myalloc(size)
27 #define oldcore(p,size) free(p)
31 #undef CORECHECK /* if defined tests are made to insure
32 each block occurs at most once */
34 #define CCHUNK 1024 /* number of shorts asked from system */
36 short *newcore(),*freshcore();
46 * The following two sizetables contain the sizes of the various kinds
47 * of line and argument structures.
48 * Care has been taken to make this table implementation independent,
49 * but if you think very hard you might find a compiler failing the
51 * A wasteful but safe approach is to replace every line of them by
58 #define LBASE (sizeof(line_t)-sizeof(un_l_a))
66 LBASE+sizeof(s_la_sval),
67 LBASE+sizeof(s_la_lval),
72 #define ABASE (sizeof(arg_t)-sizeof(un_a_a))
78 ABASE+sizeof(s_a_val),
80 ABASE+sizeof(s_a_con),
81 ABASE+sizeof(s_a_con),
82 ABASE+sizeof(s_a_con),
88 * 1) typed alloc and free routines
89 * 2) untyped raw core allocation
96 line_p newline(optyp) int optyp; {
102 lnp = (line_p) newcore(lsizetab[kind]);
103 lnp->l_optyp = optyp;
107 oldline(lnp) register line_p lnp; {
108 register kind=lnp->l_optyp&BMASK;
113 oldargs(lnp->l_a.la_arg);
114 oldcore((short *) lnp,lsizetab[kind]);
117 arg_p newarg(kind) int kind; {
120 ap = (arg_p) newcore(asizetab[kind]);
125 oldargs(ap) register arg_p ap; {
128 while (ap != (arg_p) 0) {
132 oldargb(ap->a_a.a_string.ab_next);
137 oldargb(ap->a_a.a_con.ac_con.ab_next);
140 oldcore((short *) ap,asizetab[ap->a_typ]);
145 oldargb(abp) register argb_p abp; {
146 register argb_p next;
148 while (abp != (argb_p) 0) {
150 oldcore((short *) abp,sizeof (argb_t));
157 return((reg_p) newcore(sizeof(reg_t)));
160 oldreg(rp) reg_p rp; {
162 oldcore((short *) rp,sizeof(reg_t));
167 return((num_p) newcore(sizeof(num_t)));
170 oldnum(lp) num_p lp; {
172 oldcore((short *) lp,sizeof(num_t));
177 return((offset *) newcore(MAXROM*sizeof(offset)));
180 sym_p newsym(len) int len; {
182 * sym_t includes a 2 character s_name at the end
183 * extend this structure with len-2 characters
185 return((sym_p) newcore(sizeof(sym_t) - 2 + len));
190 return((argb_p) newcore(sizeof(argb_t)));
195 /******************************************************************/
196 /****** Start of raw core management package *****************/
197 /******************************************************************/
199 #define MAXSHORT 30 /* Maximum number of shorts one can ask for */
201 short *freelist[MAXSHORT];
203 typedef struct coreblock {
204 struct coreblock *co_next;
208 #define SINC (sizeof(core_t)/sizeof(short))
216 for(size=1;size<MAXSHORT;size++)
217 for (p=freelist[size];p!=0;p = *(short **) p)
219 fprintf(stderr,"Used core %u\n",(shortsasked-sum)*sizeof(short));
226 register core_p corelist=0,tp,cl;
230 fprintf(stderr,"Almost out of core\n");
232 for(size=SINC;size<MAXSHORT;size++) {
233 while ((tp = (core_p) freelist[size]) != (core_p) 0) {
234 freelist[size] = (short *) tp->co_next;
236 if (corelist==0 || tp<corelist) {
237 tp->co_next = corelist;
240 for(cl=corelist;cl->co_next != 0 && tp>cl->co_next;
243 tp->co_next = cl->co_next;
248 while (corelist != 0) {
249 while ((short *) corelist->co_next ==
250 (short *) corelist + corelist->co_size) {
251 corelist->co_size += corelist->co_next->co_size;
252 corelist->co_next = corelist->co_next->co_next;
254 assert(corelist->co_next==0 ||
255 (short *) corelist->co_next >
256 (short *) corelist + corelist->co_size);
257 while (corelist->co_size >= MAXSHORT+SINC) {
258 oldcore((short *) corelist + corelist->co_size-(MAXSHORT-1),
259 sizeof(short)*(MAXSHORT-1));
260 corelist->co_size -= MAXSHORT;
262 if (corelist->co_size >= MAXSHORT) {
263 oldcore((short *) corelist + corelist->co_size-SINC,
265 corelist->co_size -= SINC;
267 cl = corelist->co_next;
268 oldcore((short *) corelist, sizeof(short)*corelist->co_size);
273 short *grabcore(size) int size; {
278 * Desperate situation, can't get more core from system.
279 * Postpone giving up just a little bit by splitting up
280 * larger free blocks if possible.
281 * Algorithm is worst fit.
284 assert(size<2*MAXSHORT);
285 for(trysize=2*MAXSHORT-2; trysize>size; trysize -= 2) {
286 p = freelist[trysize/sizeof(short)];
287 if ( p != (short *) 0) {
288 freelist[trysize/sizeof(short)] = *(short **) p;
289 oldcore(p+size/sizeof(short),trysize-size);
295 * Can't get more core from the biggies, try to combine the
296 * little ones. This is expensive but probably better than
301 if ((p=freelist[size/sizeof(short)]) != 0) {
302 freelist[size/sizeof(short)] = * (short **) p;
305 for(trysize=2*MAXSHORT-2; trysize>size; trysize -= 2) {
306 p = freelist[trysize/sizeof(short)];
307 if ( p != (short *) 0) {
308 freelist[trysize/sizeof(short)] = *(short **) p;
309 oldcore(p+size/sizeof(short),trysize-size);
315 * That's it then. Finished.
322 short *newcore(size) int size; {
323 register short *p,*q;
325 size = (size + sizeof(int) - 1) & ~(sizeof(int) - 1);
326 if( size < 2*MAXSHORT ) {
327 if ((p=freelist[size/sizeof(short)]) != (short *) 0)
328 freelist[size/sizeof(short)] = *(short **) p;
332 if (p == (short *) 0)
339 error("out of memory");
340 for (q=p; size > 0 ; size -= sizeof(short))
348 * stdio uses malloc and free.
349 * you can use these as substitutes
352 char *malloc(size) int size; {
355 * malloc(III) is called by stdio,
356 * this routine is a substitute.
359 return( (char *) newcore(size));
367 oldcore(p,size) short *p; int size; {
372 assert(size<2*MAXSHORT);
374 for (cp=freelist[size/sizeof(short)]; cp != (short *) 0;
378 *(short **) p = freelist[size/sizeof(short)];
379 freelist[size/sizeof(short)] = p;
384 coreinit(p1,p2) short *p1,*p2; {
387 * coreinit is called with the boundaries of a piece of
388 * memory that can be used for starters.
395 short *freshcore(size) int size; {
396 register short *temp;
397 static int cchunk=CCHUNK;
399 while(&ccur[size/sizeof(short)] >= cend && cchunk>0) {
401 temp = (short *) sbrk(cchunk*sizeof(short));
402 if (temp == (short *) -1)
404 else if (temp != cend)
406 } while (temp == (short *) -1 && cchunk>0);
409 shortsasked += cchunk;
415 ccur = &ccur[size/sizeof(short)];
419 #else /* USEMALLOC */
424 * Empty function, no initialization needed
428 short *myalloc(size) register size; {
429 register short *p,*q;
430 extern char *malloc();
432 p = (short *)malloc(size);
434 error("out of memory");
435 for(q=p;size>0;size -= sizeof(short))