|
|
1.1 root 1: /* allocate and free routines
2: * all blocks are allocated in multiples of 2
3: * with the first word as the true length
4: * the lo order bit is 1 if the block is free.
5: * A word of zero marks the end of an arena and points
6: * to the start of the next arena. Arenas point in a circle.
7: */
8:
9: #include <stdio.h>
10: #include <malloc.h>
11:
12: struct mblock *_a_scanp = NULL; /* search starts here */
13:
14: static unsigned depth = 0; /* depth of malloc recursion */
15:
16: static char msg[] = "Bad pointer in free.\n";
17:
18: /* get a new arena from sbrk and hook it to the old */
19:
20: static void
21: newarea( len)
22: register unsigned len;
23: {
24: register struct mblock *newa, *newb, *prev;
25:
26: char *passbug = BADSBRK; /* beat large model c bug */
27:
28: static struct mblock *_a_topar = NULL;
29:
30: unsigned cbrk = (unsigned)sbrk( 0);
31:
32: if( len > 65500L)
33: return;
34: len += sizeof(struct mblock);
35: if( len < 512)
36: if( cbrk < 65536L - 511)
37: len = 512;
38: else
39: len = -cbrk;
40: #if Z8001
41: else if( (unsigned long)cbrk+len > 65536L)
42: newarea( - cbrk - sizeof( struct mblock));
43: #endif
44: if( passbug == (newa = sbrk(len)))
45: return;
46:
47: if(_a_topar == NULL) /* first time through */
48: _a_scanp = prev = newa;
49:
50: else if(_a_topar == newa) { /* new over old */
51: --newa;
52: len += sizeof(struct mblock);
53: prev = newa->uval.next;
54:
55: } else { /* discontigous arenas */
56: newb = _a_topar;
57: prev = (--newb)->uval.next; /* save old ptr */
58: newb->uval.next = newa; /* old pts to new */
59: }
60: newa->blksize = (len - sizeof(struct mblock)) | FREE;
61: newb = _a_topar = adr(newa) + len;
62: (--newb)->blksize = 0;
63: newb->uval.next = prev;
64: return;
65: }
66:
67: char *
68: malloc( size)
69: unsigned size;
70: {
71: register struct mblock *ptr, *optr;
72: register unsigned len, siz;
73:
74: siz = roundup(size + sizeof(unsigned), POW2);
75: if(siz < size)
76: return(NULL);
77: optr = NULL;
78: if((ptr = _a_scanp) != NULL) {
79: do {
80: if(isfree(len = ptr->blksize)) { /* free block */
81: if(optr != NULL) { /* consolidate free */
82: len = (optr->blksize += realsize(len));
83: ptr = optr;
84: }
85: optr = ptr;
86: if(len > siz) { /* got one big enough */
87: if((len -= siz)<LEASTFREE) /* close enough */
88: ptr->blksize = realsize(ptr->blksize);
89: else {
90: ptr->blksize = siz;
91: _a_scanp = siz + adr(ptr);
92: _a_scanp->blksize = len;
93: }
94: return(ptr->uval.usera);
95: }
96: } else /* used block or area ptr */
97: optr = NULL;
98:
99: if(len)
100: ptr = realsize(len) + adr(ptr);
101: else
102: ptr = ptr->uval.next; /* new arena */
103: } while(ptr != _a_scanp);
104: }
105:
106: if(optr != NULL)
107: _a_scanp = optr;
108:
109: /* no room in the arena or first time */
110: if(++depth >= 2) {
111: depth--;
112: return(NULL);
113: }
114: newarea(siz);
115: ptr = malloc(size);
116: depth--;
117: return(ptr);
118: }
119:
120: /* free a block */
121: free(cp)
122: char *cp;
123: {
124: register struct mblock *ap;
125:
126: ap = cp - sizeof(unsigned);
127: if(!ap->blksize) {
128: write(2, msg, strlen(msg));
129: abort();
130: }
131: ap->blksize |= FREE; /* mark free even if free */
132: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.