|
|
1.1 ! root 1: #include <jerq.h> ! 2: #include <setup.h> ! 3: /* ! 4: * Garbage-collecting allocator ! 5: * ! 6: * called as: gcalloc(nbytes, where) ! 7: * nbytes is unsigned long ! 8: * where is a pointer to the location which will point to the area ! 9: * (e.g. base in a Bitmap), to be updated when necessary ! 10: */ ! 11: ! 12: /* ! 13: * The arena is allocated in longs, to speed up compaction ! 14: * Garbage is compacted towards the top (high address end) of the arena, ! 15: * i.e. away from the regular, non-compacting, allocator. ! 16: * A block has a struct header as its top HEADERSIZE longs, and ! 17: * a pointer to the struct header as its bottom long, for use by gcfree. ! 18: * header.caller points to the allocating process so things can be cleaned ! 19: * up when it exits. ! 20: * header.pval points to the USER location where the pointer to the block ! 21: * is stored; this cell must be updated after a compaction. ! 22: * Deallocated blocks have header.pval odd. ! 23: */ ! 24: extern char *allocendp; /* defined in alloc.c */ ! 25: #define STARTAREA (long *)(allocendp) ! 26: long *ENDAREA; ! 27: static long *nextlong; ! 28: struct header{ ! 29: union uuu{ ! 30: long Uival; /* integer value of where */ ! 31: long **Upval; /* where */ ! 32: }u; ! 33: long *caller; /* which process allocated */ ! 34: unsigned long nlongs; /* # of longs in the user's data */ ! 35: }; ! 36: #define ival u.Uival ! 37: #define pval u.Upval ! 38: #define HEADERSIZE sizeof(struct header)/sizeof(long) ! 39: #define hp ((struct header *)p) ! 40: ! 41: gcinit() ! 42: { ! 43: ENDAREA=(long *)(maxaddr[VALMAXADDR]-4); ! 44: nextlong=ENDAREA; /* init; this runs in rom, so .data no good */ ! 45: } ! 46: ! 47: char * ! 48: realgcalloc(nbytes, where, caller) ! 49: register unsigned long nbytes; ! 50: long **where; ! 51: char *caller; /* really a Proc * */ ! 52: { ! 53: register retry = 0, i; ! 54: register long *p, *q; ! 55: if(nextlong==0) ! 56: nextlong=ENDAREA; /* initialization; this runs in rom */ ! 57: if((long)caller&1) /* head off a possible disaster */ ! 58: return 0; ! 59: nbytes+=sizeof(long)-1; ! 60: nbytes>>=2; /* convert bytes to longs */ ! 61: #define Nlongs nbytes ! 62: Nlongs+=HEADERSIZE+1; ! 63: while(nextlong-STARTAREA < Nlongs){ ! 64: if(retry++) ! 65: return 0; ! 66: compact(); ! 67: } ! 68: p=nextlong-HEADERSIZE; ! 69: hp->caller=(long *)caller; ! 70: hp->pval=where; ! 71: hp->nlongs=Nlongs-HEADERSIZE-1; ! 72: nextlong-=Nlongs; ! 73: *nextlong=(long)p; /* so we can find the header when we free */ ! 74: *hp->pval=nextlong+1; ! 75: for(q=*hp->pval, i=0; i<hp->nlongs; i++) ! 76: *q++=0; ! 77: return (char *)(*hp->pval); ! 78: } ! 79: char * ! 80: gcalloc(n, w) ! 81: unsigned long n; ! 82: long **w; ! 83: { ! 84: return realgcalloc(n, w, (char *)0); ! 85: } ! 86: gcfree(cp) ! 87: register char *cp; ! 88: { ! 89: #define p ((long *)cp) ! 90: /* nice and safe */ ! 91: if(p>nextlong && p<ENDAREA){ ! 92: cp=(char *)(p[-1]); /* pointer to the header */ ! 93: if(p>nextlong && p<ENDAREA) ! 94: hp->ival|=1; ! 95: } ! 96: #undef p ! 97: } ! 98: gcfreeall(whichproc) ! 99: char *whichproc; ! 100: { ! 101: register long *p; ! 102: for(p=ENDAREA; p>nextlong; p-=hp->nlongs+1){ ! 103: p-=HEADERSIZE; ! 104: if(hp->caller==(long *)whichproc) ! 105: hp->ival|=1; ! 106: } ! 107: } ! 108: static ! 109: compact() ! 110: { ! 111: register long *w, *p; ! 112: register struct header *header; ! 113: register unsigned long n; ! 114: static Rectangle r={750, 0, 800, 50}; ! 115: ! 116: rectf(&display, r, F_XOR); ! 117: w=ENDAREA; ! 118: p=w; ! 119: while(p>nextlong){ ! 120: header=(struct header *)(p-HEADERSIZE); ! 121: n = header->nlongs; ! 122: if(header->ival&1){ ! 123: p -= n+HEADERSIZE+1; ! 124: continue; ! 125: } ! 126: if(w==p){ ! 127: p -= n+HEADERSIZE+1; ! 128: w -= n+HEADERSIZE+1; ! 129: continue; ! 130: } ! 131: *--w = n; ! 132: *--w = (long)header->caller; ! 133: *--w = header->ival; ! 134: p-=HEADERSIZE; ! 135: header = (struct header *)w; ! 136: *(((struct header *)w)->pval)=w-n; /* update *where */ ! 137: if(n>0) do ! 138: *--w = *--p; ! 139: while(--n); ! 140: --p; ! 141: *--w = (long)header; /* back pointer to header */ ! 142: } ! 143: nextlong=w; ! 144: rectf(&display, r, F_XOR); ! 145: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.