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