ack/util/opt/alloc.c

476 lines
8.6 KiB
C
Raw Permalink Normal View History

/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
#include <assert.h>
#include <stdlib.h>
1984-05-17 13:42:36 +00:00
#include <stdio.h>
#include "param.h"
#include "types.h"
#include "tes.h"
1984-05-17 13:42:36 +00:00
#include "alloc.h"
#include "util.h"
1984-05-17 13:42:36 +00:00
#include "line.h"
#include "lookup.h"
#include "proinf.h"
#ifdef USEMALLOC
short *myalloc(register unsigned int);
1984-05-17 13:42:36 +00:00
#define newcore(size) myalloc(size)
#define oldcore(p,size) free(p)
#else
#undef CORECHECK /* if defined tests are made to insure
1984-05-17 13:42:36 +00:00
each block occurs at most once */
#define CCHUNK 1024 /* number of shorts asked from system */
short *newcore(),*freshcore();
extern char *sbrk();
#ifdef COREDEBUG
int shortsasked=0;
#endif
#endif
/*
* The following two sizetables contain the sizes of the various kinds
* of line and argument structures.
* Care has been taken to make this table implementation independent,
* but if you think very hard you might find a compiler failing the
* assumptions made.
* A wasteful but safe approach is to replace every line of them by
* sizeof(line_t)
* and
* sizeof(arg_t)
* respectively.
*/
#define LBASE (sizeof(line_t)-sizeof(un_l_a))
int lsizetab[] = {
LBASE,
LBASE+sizeof(short),
LBASE+sizeof(offset),
LBASE+sizeof(num_p),
LBASE+sizeof(sym_p),
LBASE+sizeof(s_la_sval),
LBASE+sizeof(s_la_lval),
LBASE+sizeof(arg_p),
LBASE
};
#define ABASE (sizeof(arg_t)-sizeof(un_a_a))
int asizetab[] = {
ABASE+sizeof(offset),
ABASE+sizeof(num_p),
ABASE+sizeof(sym_p),
ABASE+sizeof(s_a_val),
ABASE+sizeof(argb_t),
ABASE+sizeof(s_a_con),
ABASE+sizeof(s_a_con),
ABASE+sizeof(s_a_con),
};
/*
* alloc routines:
* Two parts:
* 1) typed alloc and free routines
* 2) untyped raw core allocation
*/
/*
* PART 1
*/
line_p newline(int optyp)
{
1984-05-17 13:42:36 +00:00
register line_p lnp;
register int kind = optyp;
1984-05-17 13:42:36 +00:00
if (kind > OPMINI)
1984-05-17 13:42:36 +00:00
kind = OPMINI;
lnp = (line_p) newcore(lsizetab[kind]);
lnp->l_optyp = optyp;
return (lnp);
1984-05-17 13:42:36 +00:00
}
void oldline(register line_p lnp)
{
register int kind = lnp->l_optyp & BMASK;
1984-05-17 13:42:36 +00:00
if (kind > OPMINI)
1984-05-17 13:42:36 +00:00
kind = OPMINI;
if (kind == OPLIST)
oldargs(lnp->l_a.la_arg);
oldcore((short * ) lnp, lsizetab[kind]);
1984-05-17 13:42:36 +00:00
}
arg_p newarg(int kind)
{
1984-05-17 13:42:36 +00:00
register arg_p ap;
ap = (arg_p) newcore(asizetab[kind]);
ap->a_typ = kind;
return (ap);
1984-05-17 13:42:36 +00:00
}
void oldargs(register arg_p ap)
{
register arg_p next;
1984-05-17 13:42:36 +00:00
while (ap != (arg_p) 0)
{
1984-05-17 13:42:36 +00:00
next = ap->a_next;
switch (ap->a_typ)
{
case ARGSTR:
oldargb(ap->a_a.a_string.ab_next);
break;
case ARGICN:
case ARGUCN:
case ARGFCN:
oldargb(ap->a_a.a_con.ac_con.ab_next);
break;
1984-05-17 13:42:36 +00:00
}
oldcore((short * ) ap, asizetab[ap->a_typ]);
1984-05-17 13:42:36 +00:00
ap = next;
}
}
void oldargb(register argb_p abp)
{
1984-05-17 13:42:36 +00:00
register argb_p next;
while (abp != (argb_p) 0)
{
1984-05-17 13:42:36 +00:00
next = abp->ab_next;
oldcore((short * ) abp, sizeof (argb_t));
1984-05-17 13:42:36 +00:00
abp = next;
}
}
reg_p newreg(void)
{
return ((reg_p) newcore(sizeof(reg_t)));
1984-05-17 13:42:36 +00:00
}
void oldreg(reg_p rp)
{
1984-05-17 13:42:36 +00:00
oldcore((short * ) rp, sizeof(reg_t));
1984-05-17 13:42:36 +00:00
}
num_p newnum(void)
{
return ((num_p) newcore(sizeof(num_t)));
1984-05-17 13:42:36 +00:00
}
void oldnum(num_p lp)
{
oldcore((short * ) lp, sizeof(num_t));
1984-05-17 13:42:36 +00:00
}
offset *newrom(void)
{
return ((offset *) newcore(MAXROM*sizeof(offset)));
1984-05-17 13:42:36 +00:00
}
sym_p newsym(int len)
{
/*
* sym_t includes a 2 character s_name at the end
* extend this structure with len-2 characters
*/
return ((sym_p) newcore(sizeof(sym_t) - 2 + len));
1984-05-17 13:42:36 +00:00
}
argb_p newargb(void)
{
return ((argb_p) newcore(sizeof(argb_t)));
1984-05-17 13:42:36 +00:00
}
#ifndef USEMALLOC
/******************************************************************/
/****** Start of raw core management package *****************/
/******************************************************************/
#define MAXSHORT 30 /* Maximum number of shorts one can ask for */
short *freelist[MAXSHORT];
typedef struct coreblock
{
1984-05-17 13:42:36 +00:00
struct coreblock *co_next;
short co_size;
}core_t,*core_p;
1984-05-17 13:42:36 +00:00
#define SINC (sizeof(core_t)/sizeof(short))
#ifdef COREDEBUG
coreverbose()
{
1984-05-17 13:42:36 +00:00
register size;
register short *p;
register sum;
sum = 0;
for(size=1;size<MAXSHORT;size++)
for (p=freelist[size];p!=0;p = *(short **) p)
sum += size;
1984-05-17 13:42:36 +00:00
fprintf(stderr,"Used core %u\n",(shortsasked-sum)*sizeof(short));
}
#endif
#ifdef SEPID
compactcore()
{
1984-05-17 13:42:36 +00:00
register core_p corelist=0,tp,cl;
int size;
#ifdef COREDEBUG
fprintf(stderr,"Almost out of core\n");
#endif
for(size=SINC;size<MAXSHORT;size++)
{
while ((tp = (core_p) freelist[size]) != (core_p) 0)
{
1984-05-17 13:42:36 +00:00
freelist[size] = (short *) tp->co_next;
tp->co_size = size;
if (corelist==0 || tp<corelist)
{
1984-05-17 13:42:36 +00:00
tp->co_next = corelist;
corelist = tp;
}
else
{
1984-05-17 13:42:36 +00:00
for(cl=corelist;cl->co_next != 0 && tp>cl->co_next;
cl = cl->co_next)
;
1984-05-17 13:42:36 +00:00
tp->co_next = cl->co_next;
cl->co_next = tp;
}
}
}
while (corelist != 0)
{
1984-05-17 13:42:36 +00:00
while ((short *) corelist->co_next ==
(short *) corelist + corelist->co_size)
{
1984-05-17 13:42:36 +00:00
corelist->co_size += corelist->co_next->co_size;
corelist->co_next = corelist->co_next->co_next;
1984-05-17 13:42:36 +00:00
}
assert(corelist->co_next==0 ||
(short *) corelist->co_next >
(short *) corelist + corelist->co_size);
while (corelist->co_size >= MAXSHORT+SINC)
{
1984-05-17 13:42:36 +00:00
oldcore((short *) corelist + corelist->co_size-(MAXSHORT-1),
sizeof(short)*(MAXSHORT-1));
1984-05-17 13:42:36 +00:00
corelist->co_size -= MAXSHORT;
}
if (corelist->co_size >= MAXSHORT)
{
1984-05-17 13:42:36 +00:00
oldcore((short *) corelist + corelist->co_size-SINC,
sizeof(short)*SINC);
1984-05-17 13:42:36 +00:00
corelist->co_size -= SINC;
}
cl = corelist->co_next;
oldcore((short *) corelist, sizeof(short)*corelist->co_size);
corelist = cl;
}
}
short *grabcore(size) int size;
{
1984-05-17 13:42:36 +00:00
register short *p;
register trysize;
/*
* Desperate situation, can't get more core from system.
* Postpone giving up just a little bit by splitting up
* larger free blocks if possible.
* Algorithm is worst fit.
*/
assert(size<2*MAXSHORT);
for(trysize=2*MAXSHORT-2; trysize>size; trysize -= 2)
{
1984-05-17 13:42:36 +00:00
p = freelist[trysize/sizeof(short)];
if ( p != (short *) 0)
{
1984-05-17 13:42:36 +00:00
freelist[trysize/sizeof(short)] = *(short **) p;
oldcore(p+size/sizeof(short),trysize-size);
return(p);
}
}
/*
* Can't get more core from the biggies, try to combine the
* little ones. This is expensive but probably better than
* giving up.
*/
compactcore();
if ((p=freelist[size/sizeof(short)]) != 0)
{
1984-05-17 13:42:36 +00:00
freelist[size/sizeof(short)] = * (short **) p;
return(p);
}
for(trysize=2*MAXSHORT-2; trysize>size; trysize -= 2)
{
1984-05-17 13:42:36 +00:00
p = freelist[trysize/sizeof(short)];
if ( p != (short *) 0)
{
1984-05-17 13:42:36 +00:00
freelist[trysize/sizeof(short)] = *(short **) p;
oldcore(p+size/sizeof(short),trysize-size);
return(p);
}
}
/*
* That's it then. Finished.
*/
return(0);
}
#endif /* SEPID */
short *newcore(size) int size;
{
1984-05-17 13:42:36 +00:00
register short *p,*q;
1988-04-19 19:46:28 +00:00
size = (size + sizeof(int) - 1) & ~(sizeof(int) - 1);
if( size < 2*MAXSHORT )
{
1984-05-17 13:42:36 +00:00
if ((p=freelist[size/sizeof(short)]) != (short *) 0)
freelist[size/sizeof(short)] = *(short **) p;
else
{
1984-05-17 13:42:36 +00:00
p = freshcore(size);
#ifdef SEPID
if (p == (short *) 0)
p = grabcore(size);
1984-05-17 13:42:36 +00:00
#endif
}
}
else
p = freshcore(size);
1984-05-17 13:42:36 +00:00
if (p == 0)
error("out of memory");
for (q=p; size > 0; size -= sizeof(short))
*q++ = 0;
1984-05-17 13:42:36 +00:00
return(p);
}
1991-02-19 16:54:06 +00:00
#ifndef USEMALLOC
1984-05-17 13:42:36 +00:00
/*
* stdio uses malloc and free.
* you can use these as substitutes
*/
char *malloc(size) int size;
{
1984-05-17 13:42:36 +00:00
/*
* malloc(III) is called by stdio,
* this routine is a substitute.
*/
return( (char *) newcore(size));
}
free()
{
1984-05-17 13:42:36 +00:00
}
#endif
oldcore(p,size) short *p; int size;
{
1984-05-17 13:42:36 +00:00
#ifdef CORECHECK
register short *cp;
#endif
assert(size<2*MAXSHORT);
#ifdef CORECHECK
for (cp=freelist[size/sizeof(short)]; cp != (short *) 0;
cp = *(short **) cp)
assert(cp != p);
1984-05-17 13:42:36 +00:00
#endif
*(short **) p = freelist[size/sizeof(short)];
freelist[size/sizeof(short)] = p;
}
short *ccur,*cend;
coreinit(p1,p2) short *p1,*p2;
{
1984-05-17 13:42:36 +00:00
/*
* coreinit is called with the boundaries of a piece of
* memory that can be used for starters.
*/
ccur = p1;
cend = p2;
}
short *freshcore(size) int size;
{
1984-05-17 13:42:36 +00:00
register short *temp;
static int cchunk=CCHUNK;
while(&ccur[size/sizeof(short)] >= cend && cchunk>0)
{
do
{
1984-05-17 13:42:36 +00:00
temp = (short *) sbrk(cchunk*sizeof(short));
if (temp == (short *) -1)
cchunk >>= 1;
1984-05-17 13:42:36 +00:00
else if (temp != cend)
ccur = cend = temp;
}while (temp == (short *) -1 && cchunk>0);
1984-05-17 13:42:36 +00:00
cend += cchunk;
#ifdef COREDEBUG
shortsasked += cchunk;
#endif
}
if (cchunk==0)
return(0);
1984-05-17 13:42:36 +00:00
temp = ccur;
ccur = &ccur[size/sizeof(short)];
return(temp);
}
#else /* USEMALLOC */
void coreinit(void)
{
1984-05-17 13:42:36 +00:00
/*
* Empty function, no initialization needed
*/
}
short *myalloc(register unsigned int size)
{
register short *p, *q;
1984-05-17 13:42:36 +00:00
p = (short *) malloc(size);
1984-05-17 13:42:36 +00:00
if (p == 0)
error("out of memory");
for (q = p; size > 0; size -= sizeof(short))
1984-05-17 13:42:36 +00:00
*q++ = 0;
return (p);
1984-05-17 13:42:36 +00:00
}
#endif