|
|
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.