10 #include <sys/types.h> 11 #include <sys/times.h> 20 #define nextbuddy(p) ((bpointer)((int)p+(buddysize[p->h.bix]*sizeof(pointer)))) 21 #define marked(p) (p->h.mark) 22 #define markon(p) p->h.mark=1 23 #define markoff(p) p->h.mark=0 24 #define myctx (euscontexts[thr_self()]) 48 register struct chunk *cp;
49 if (k<DEFAULTCHUNKINDEX) k=DEFAULTCHUNKINDEX;
50 if (
QDEBUG && debug) fprintf(stderr,
";; newchunk: k=%d\n",k);
52 cp=(
struct chunk *)(malloc((s+2)*
sizeof(
pointer)+3) & ~3);
54 if (cp==
NULL)
return(ERR);
94 b1->
h.
b=0; b1->
h.
bix= k-1; b2->
h.
b=1;
108 ctx->alloc_big_count++;
111 while (buddy[k].
bp==0) k++;
117 for (k=req; buddy[k].
bp==0; ) k++;}
126 while (req<k) {
splitheap(k--,&buddy);
if (k>req) k--;}
130 for (i=0; i<k; i++) b->
b.
c[i]=0;
131 ctx->lastalloc=makepointer(b);
144 {
register int i, j, k,kk;
147 static long buddyfill[MAXTHRBUDDY+1]={0,500,300,50,25,20,0};
158 for (i=1; i<MAXTHRBUDDY; i++) {
159 k=kk=buddyfill[i] - tb[i].
count;
160 while (buddy[i].
count < k) {
163 while (buddy[j].
bp==0) j++;
182 tb[i].
bp=buddy[i].
bp;
184 buddy[i].
count -= kk;
185 tb[i].
count=buddyfill[i];
206 if (tb[req].
count==0)
220 {
register int bs=1,i,ss;
226 if (bs>=MAXBUDDY)
return(
NULL);
237 while (nils<
s) v[nils++]=
NIL;
244 {
register int req=1,i,ss,k;
253 if (req>=MAXBUDDY)
return(
NULL);
258 while (buddy[k].
bp==0) k++;
264 for (k=req; buddy[k].
bp==0; ) k++;}
268 while (req<k) {
splitheap(k--,&buddy);
if (k>req) k--;}
272 for (i=0; i<k; i++) b->
b.
c[i]=0;
285 while (nils<
s) v[nils++]=
NIL;
294 #define DEFAULT_MAX_GCSTACK 65536*2 296 #define gcpush(v) (*lgcsp++=((pointer)v)) 297 #define gcpop() (*--lgcsp) 312 if (lgcsp<=gcstack)
return;
316 if ((
int)p<(
int)
_end || (
pointer)0x20000000<p)
goto markloop;
318 if ((
int)p<(
int)
edata || (
pointer)0x20000000<p)
goto markloop;
321 if (marked(bp))
goto markloop;
323 if (pisclosure(p))
goto markloop;
328 for (i=0; i<
s; i++) {
330 if (ispointer(p2))
gcpush(p2); }
332 else if (bp->
h.
elmtype==ELM_POINTER) {
335 for (i=0; i<
s; i++) {
337 if (ispointer(p2))
gcpush(p2); }
344 {
register pointer *oldstack, *stk, *newstack, *newgcsp;
345 long top, oldsize, newsize;
352 fprintf(stderr,
"\n;; extending gcstack 0x%x[%d] --> 0x%x[%d] top=%x\n",
353 oldstack, oldsize, newstack, newsize, top);
354 while (stk<oldsp) *newgcsp++= *stk++;
356 gcsplimit= &gcstack[newsize-10];
373 for (i=0; i<MAXTHREAD; i++) {
377 for (p=ctx->
stack; p<ctx->vsp; p++) {
379 if ((((
int)(*p) & 3)==0) &&
385 for (j=1; j<MAXTHRBUDDY; j++) {
391 for (i=0; i<MAXCLASS; i++) {
398 {
register int rbix,stat;
401 if (pisfilestream(s)) {
404 fprintf(stderr,
";; gc! bogus stream at %x fd=%d\n",
405 (
int)s,
intval(s->c.fstream.fd));}
407 fprintf(stderr,
";; gc: dangling stream(address=%x fd=%d) is closed\n",
408 (
int)s,
intval(s->c.fstream.fd)); } }
412 buddy[rbix].
bp=p; buddy[rbix].
count++;
422 while (p->
h.
b==0 && (
int)p->
h.
bix<cbix) {
423 if (marked(np))
return(np);
436 register struct chunk *cp;
445 if (marked(p)) { markoff(p); p=nextbuddy(p);}
458 register struct chunk *chp;
464 for (i=0; i<MAXBUDDY-1; i++) {
469 for (chp=chunklist; chp!=0; chp=chp->
nextchunk)
sweep(chp,gcmerge);
474 {
if (debug) fprintf(stderr,
"\n;; gc:");
480 fprintf(stderr,
" free/total=%d/%d stack=%d ",
489 {
struct tms tbuf1,tbuf2,tbuf3;
491 if (debug) fprintf(stderr,
"\n;; gc: thread=%d ",
thr_self());
503 marktime+=(tbuf2.tms_utime-tbuf1.tms_utime);
506 sweeptime+=(tbuf3.tms_utime-tbuf2.tms_utime);
508 fprintf(stderr,
" free/total=%d/%d stack=%d ",
context * euscontexts[MAXTHREAD]
struct filestream fstream
pointer alloc(int s, int e, int cid, int nils)
long alloccount[MAXBUDDY]
newgcstack(pointer *oldsp)
long buddysize[MAXBUDDY+1]
static bpointer mergecell(bpointer p, int cbix)
pointer error(enum errorcode ec,...) pointer error(va_alist) va_dcl
pointer halloc(int req, int e, int cid)
static void sweep(struct chunk *cp, int gcmerge)
struct buddyfree buddy[MAXBUDDY+1]
struct buddyfree * thr_buddy
struct class_desc classtab[MAXCLASS]
bpointer root_alloc_big(context *ctx, int req)
root_alloc_small(context *ctx, int req)
static void splitheap(int k, struct buddyfree *buddy)
pointer allocx(int s, int e, int cid, int nils)