1: #define ASSERT(p) if(!(p))botch("p");else
2: botch(s)
3: char *s;
4: {
5: printf("assertion botched: %s\n",s);
6: abort();
7: }
8: /* C storage allocator
9: * circular first-fit strategy
10: * works with noncontiguous, but monotonically linked, arena
11: * each block is preceded by a ptr to the (pointer of)
12: * the next following block
13: * blocks are exact number of words long; BUSY
14: * bit in ptr is 1 for busy, 0 for idle
15: * gaps in arena are merely noted as busy blocks
16: * last block of arena (pointed to by alloct) is empty and
17: * has a pointer to first
18: * idle blocks are coalesced during space search
19: */
20: /* all these defines must be powers of 2 */
21: #define WORD sizeof(struct store)
22: #define BLOCK 1024
23: #define BUSY 1
24: #define NULL 0
25: #define testbusy(p) ((int)(p)&BUSY)
26: #define setbusy(p) ((int)(p)+BUSY)
27: #define clearbusy(p) ((int)(p)&~BUSY)
28:
29: struct store { struct store *ptr; };
30:
31: struct store allocs[] = { /*initial arena*/
32: setbusy(&allocs[1].ptr),
33: setbusy(&allocs[0].ptr)
34: };
35: struct store *allocp = &allocs[1]; /*search ptr*/
36: struct store *alloct = &allocs[1]; /*arena top*/
37: struct store *allocx; /*for benefit of realloc*/
38: struct store *sbrk();
39:
40: struct store *
41: malloc(nbytes)
42: unsigned nbytes;
43: {
44: register struct store *p, *q;
45: register nw;
46: static temp; /*coroutines assume no auto*/
47:
48: nw = (nbytes+2*WORD-1)/WORD;
49: ASSERT(allocp>allocs && allocp<=alloct);
50: for(p=allocp; ; ) {
51: for(temp=0; ; ) {
52: if(!testbusy(p->ptr)) {
53: while(!testbusy((q=p->ptr)->ptr)) {
54: ASSERT(q>p&&q<alloct);
55: p->ptr = q->ptr;
56: }
57: if(q>=p+nw && p+nw>=p)
58: goto found;
59: }
60: q = p;
61: p = clearbusy(p->ptr);
62: if(p>q)
63: ASSERT(p<=alloct);
64: else if(q!=alloct || p!=allocs) {
65: write(2,"corrupt arena\n",14);
66: exit(0175);
67: } else if(++temp>1)
68: break;
69: }
70: temp = (nw+BLOCK/WORD)&~(BLOCK/WORD-1);
71: q = sbrk(0);
72: if(q+temp < q)
73: return(NULL);
74: q = sbrk(temp*WORD);
75: if((int)q == -1)
76: return(NULL);
77: ASSERT(q>alloct);
78: alloct->ptr = q;
79: if(q!=alloct+1)
80: alloct->ptr = setbusy(alloct->ptr);
81: alloct = q->ptr = q+temp-1;
82: alloct->ptr = setbusy(allocs);
83: }
84: found:
85: allocp = p + nw;
86: ASSERT(allocp<=alloct);
87: if(q>allocp) {
88: allocx = allocp->ptr;
89: allocp->ptr = p->ptr;
90: }
91: p->ptr = setbusy(allocp);
92: return(p+1);
93: }
94: /* freeing strategy tuned for LIFO allocation
95: */
96: free(p)
97: register struct store *p;
98: {
99: ASSERT(p>clearbusy(allocs[1].ptr)&&p<=alloct);
100: allocp = --p;
101: ASSERT(testbusy(p->ptr));
102: p->ptr = clearbusy(p->ptr);
103: ASSERT(p->ptr > allocp && p->ptr <= alloct);
104: }
105: struct { unsigned tag:4, vtype:4;};
106:
107:
108: prbusy()
109: {
110: register struct store *p, *q;
111:
112: ASSERT(allocp>allocs && allocp<=alloct);
113: for(p=allocs; ; ) {
114: if(testbusy(p->ptr))
115: {
116: printf("busy 0%o, tag %d, type %d, length %d\n",
117: p, p[1].tag, p[1].vtype,
118: clearbusy(p->ptr) - (int) p - 2 );
119: }
120: q = p;
121: p = clearbusy(p->ptr);
122: if(p>q)
123: ASSERT(p<=alloct);
124: else if(q!=alloct || p!=allocs)
125: {
126: write(2,"corrupt arena\n",14);
127: exit(0175);
128: }
129: else return;
130: }
131: }
Defined functions
botch
defined in line
2; used 1 times
free
defined in line
96; used 52 times
- in /usr/src/cmd/f77/data.c line
310
- in /usr/src/cmd/f77/equiv.c line
228,
244
- in /usr/src/cmd/f77/exec.c line
188
- in /usr/src/cmd/f77/expr.c line
292,
335,
424,
511,
761,
787,
842,
926,
1383,
1416,
1430,
1439,
1449,
2140,
2172
- in /usr/src/cmd/f77/init.c line
189-191(2),
199
- in /usr/src/cmd/f77/intr.c line
417,
440,
467
- in /usr/src/cmd/f77/io.c line
453
- in /usr/src/cmd/f77/lex.c line
147-151(2),
168
- in /usr/src/cmd/f77/misc.c line
486,
500
- in /usr/src/cmd/f77/proc.c line
612
- in /usr/src/cmd/f77/putdmr.c line
185,
205,
214,
291,
353,
420,
435,
458,
561,
724,
750-752(3),
840,
857,
919,
1039,
1128,
1146-1147(2)
Defined variables
allocp
defined in line
35; used 13 times
allocs
defined in line
31; used 11 times
alloct
defined in line
36; used 17 times
Defined struct's
store
defined in line
29; used 20 times
Defined macros
ASSERT
defined in line
1; used 10 times
BLOCK
defined in line
22; used 2 times
BUSY
defined in line
23; used 3 times
NULL
defined in line
24; used 2 times
WORD
defined in line
21; used 5 times