|
|
1.1 root 1: /****************************************************************
2: Copyright 1990, 1991 by AT&T Bell Laboratories and Bellcore.
3:
4: Permission to use, copy, modify, and distribute this software
5: and its documentation for any purpose and without fee is hereby
6: granted, provided that the above copyright notice appear in all
7: copies and that both that the copyright notice and this
8: permission notice and warranty disclaimer appear in supporting
9: documentation, and that the names of AT&T Bell Laboratories or
10: Bellcore or any of their entities not be used in advertising or
11: publicity pertaining to distribution of the software without
12: specific, written prior permission.
13:
14: AT&T and Bellcore disclaim all warranties with regard to this
15: software, including all implied warranties of merchantability
16: and fitness. In no event shall AT&T or Bellcore be liable for
17: any special, indirect or consequential damages or any damages
18: whatsoever resulting from loss of use, data or profits, whether
19: in an action of contract, negligence or other tortious action,
20: arising out of or in connection with the use or performance of
21: this software.
22: ****************************************************************/
23:
24: #ifndef CRAY
25: #define STACKMIN 512
26: #define MINBLK (2*sizeof(struct mem) + 16)
27: #define MSTUFF _malloc_stuff_
28: #define F MSTUFF.free
29: #define B MSTUFF.busy
30: #define SBGULP 8192
31: char *memcpy();
32: #define Malloc_debug
33:
34: #include "stdio.h"
35: static void mcheck();
36:
37: struct mem {
38: struct mem *next;
39: unsigned len;
40: };
41:
42: struct {
43: struct mem *free;
44: char *busy;
45: } MSTUFF;
46:
47: #define Zap -1
48:
49: #ifdef M1check
50: static void
51: m1check()
52: {
53: register struct mem *p;
54: register long *x, *xe;
55: for(p = F; p; p = p->next) {
56: x = (long *)(p+1);
57: xe = (long *)((char *)x + p->len);
58: for(; x < xe; x++)
59: if (*x != -1) {
60: fprintf(stderr, "0x%lx scrogged!\n", x);
61: exit(1);
62: }
63: }
64: }
65: #else
66: #define m1check() /* nothing */
67: #endif
68:
69: char *
70: malloc(size)
71: register unsigned size;
72: {
73: register struct mem *p, *q, *r, *s;
74: unsigned register k, m;
75: extern char *sbrk();
76: char *top, *top1;
77:
78: m1check();
79: size = (size+7) & ~7;
80: r = (struct mem *) &F;
81: for (p = F, q = 0; p; r = p, p = p->next) {
82: if ((k = p->len) >= size && (!q || m > k)) { m = k; q = p; s = r; }
83: }
84: if (q) {
85: if (q->len - size >= MINBLK) { /* split block */
86: p = (struct mem *) (((char *) (q+1)) + size);
87: p->next = q->next;
88: p->len = q->len - size - sizeof(struct mem);
89: s->next = p;
90: q->len = size;
91: }
92: else s->next = q->next;
93: }
94: else {
95: top = B ? B : (char *)(((long)sbrk(0) + 7) & ~7);
96: if (F && (char *)(F+1) + F->len == B)
97: { q = F; F = F->next; }
98: else q = (struct mem *) top;
99: top1 = (char *)(q+1) + size;
100: if (top1 > top) {
101: if (sbrk((int)(top1-top+SBGULP)) == (char *) -1)
102: return 0;
103: r = (struct mem *)top1;
104: r->len = SBGULP - sizeof(struct mem);
105: memset((char *)(r+1), Zap, r->len);
106: r->next = F;
107: F = r;
108: top1 += SBGULP;
109: }
110: q->len = size;
111: B = top1;
112: }
113: ++q;
114: mcheck((char *)q, 0);
115: return (char *) q;
116: }
117:
118: static void
119: free1(f, rallocing)
120: char *f;
121: {
122: struct mem *p, *q, *r;
123: char *pn, *qn;
124:
125: if (!f) return;
126: mcheck(f, 1);
127: q = (struct mem *) (f - sizeof(struct mem));
128: if (!rallocing)
129: memset(f, Zap, q->len);
130: qn = f + q->len;
131: for (p = F, r = (struct mem *) &F; ; r = p, p = p->next) {
132: if (qn == (char *) p) {
133: q->len += p->len + sizeof(struct mem);
134: p = p->next;
135: memset(qn, Zap, sizeof(struct mem));
136: }
137: pn = p ? ((char *) (p+1)) + p->len : 0;
138: if (pn == (char *) q) {
139: p->len += sizeof(struct mem) + q->len;
140: if (rallocing) {
141: q->len = 0;
142: q->next = p;
143: }
144: else
145: memset((char *)q, Zap, sizeof(struct mem));
146: r->next = p;
147: break;
148: }
149: if (pn < (char *) q) {
150: r->next = q;
151: q->next = p;
152: break;
153: }
154: }
155: }
156:
157: void
158: free(f)
159: char *f;
160: {
161: m1check();
162: free1(f,0);
163: }
164:
165: char *
166: realloc(f, size)
167: char *f;
168: unsigned size;
169: {
170: struct mem *p;
171: char *q, *f1;
172: unsigned s1;
173:
174: if (!f) return malloc(size);
175: p = (struct mem *) (f - sizeof(struct mem));
176: s1 = p->len;
177: free1(f,1);
178: if (s1 > size) {
179: memset(f+size, Zap, s1-size);
180: s1 = size + 7 & ~7;
181: }
182: if (!p->len) {
183: f1 = (char *)(p->next + 1);
184: memcpy(f1, f, s1);
185: memset(f1+s1, Zap, f-f1);
186: f = f1;
187: }
188: q = malloc(size);
189: if (q && q != f) {
190: memcpy(q, f, s1);
191: memset(f, Zap, s1);
192: }
193: return q;
194: }
195:
196: struct mchk;
197: typedef struct mchk mchk;
198: struct
199: mchk {
200: mchk *next;
201: char *mem;
202: int busy;
203: };
204:
205: #define Mhash 131
206: #define Mcgulp 1000
207:
208: static mchk *buckets[Mhash];
209: char * zork_mc;
210: int zork_mck;
211:
212: static void
213: mcheck(x, freeing)
214: register char *x;
215: int freeing;
216: {
217: register mchk *mc, **mc0;
218: static int in_mcheck, nzork;
219: static mchk *mnext, *mlast;
220:
221: if (x == zork_mc && ++nzork >= zork_mck)
222: printf("");
223:
224: mc0 = &buckets[((unsigned long)x>>3) % Mhash];
225: for(mc = *mc0; mc; mc = mc->next)
226: if (mc->mem == x) {
227: if (freeing) {
228: if (mc->busy) {
229: mc->busy = 0;
230: return;
231: }
232: free_error:
233: fprintf(stderr, "free error! x = 0x%lx\n", x);
234: exit(1);
235: }
236: if (mc->busy) {
237: fprintf(stderr, "malloc errof! x = 0x%lx\n", x);
238: exit(2);
239: }
240: mc->busy = 1;
241: return;
242: }
243: if (freeing)
244: goto free_error;
245: if (mnext >= mlast) {
246: if (in_mcheck)
247: return;
248: in_mcheck = 1;
249: mnext = (mchk *)malloc(Mcgulp*sizeof(mchk));
250: in_mcheck = 0;
251: if (!mnext) {
252: fprintf(stderr, "malloc failure in mcheck!\n");
253: exit(3);
254: }
255: mlast = mnext + Mcgulp;
256: }
257: mc = mnext++;
258: mc->next = *mc0;
259: *mc0 = mc;
260: mc->mem = x;
261: mc->busy = 1;
262: }
263: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.