|
|
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: char *
48: malloc(size)
49: register unsigned size;
50: {
51: register struct mem *p, *q, *r, *s;
52: unsigned register k, m;
53: extern char *sbrk();
54: char *top, *top1;
55:
56: size = (size+7) & ~7;
57: r = (struct mem *) &F;
58: for (p = F, q = 0; p; r = p, p = p->next) {
59: if ((k = p->len) >= size && (!q || m > k)) { m = k; q = p; s = r; }
60: }
61: if (q) {
62: if (q->len - size >= MINBLK) { /* split block */
63: p = (struct mem *) (((char *) (q+1)) + size);
64: p->next = q->next;
65: p->len = q->len - size - sizeof(struct mem);
66: s->next = p;
67: q->len = size;
68: }
69: else s->next = q->next;
70: }
71: else {
72: top = B ? B : (char *)(((long)sbrk(0) + 7) & ~7);
73: if (F && (char *)(F+1) + F->len == B)
74: { q = F; F = F->next; }
75: else q = (struct mem *) top;
76: top1 = (char *)(q+1) + size;
77: if (top1 > top) {
78: if (sbrk((int)(top1-top+SBGULP)) == (char *) -1)
79: return 0;
80: r = (struct mem *)top1;
81: r->len = SBGULP - sizeof(struct mem);
82: r->next = F;
83: F = r;
84: top1 += SBGULP;
85: }
86: q->len = size;
87: B = top1;
88: }
89: ++q;
90: mcheck((char *)q, 0);
91: return (char *) q;
92: }
93:
94: free(f)
95: char *f;
96: {
97: struct mem *p, *q, *r;
98: char *pn, *qn;
99:
100: if (!f) return;
101: mcheck(f, 1);
102: q = (struct mem *) (f - sizeof(struct mem));
103: qn = f + q->len;
104: for (p = F, r = (struct mem *) &F; ; r = p, p = p->next) {
105: if (qn == (char *) p) {
106: q->len += p->len + sizeof(struct mem);
107: p = p->next;
108: }
109: pn = p ? ((char *) (p+1)) + p->len : 0;
110: if (pn == (char *) q) {
111: p->len += sizeof(struct mem) + q->len;
112: q->len = 0;
113: q->next = p;
114: r->next = p;
115: break;
116: }
117: if (pn < (char *) q) {
118: r->next = q;
119: q->next = p;
120: break;
121: }
122: }
123: }
124:
125: char *
126: realloc(f, size)
127: char *f;
128: unsigned size;
129: {
130: struct mem *p;
131: char *q, *f1;
132: unsigned s1;
133:
134: if (!f) return malloc(size);
135: p = (struct mem *) (f - sizeof(struct mem));
136: s1 = p->len;
137: free(f);
138: if (s1 > size) s1 = size + 7 & ~7;
139: if (!p->len) {
140: f1 = (char *)(p->next + 1);
141: memcpy(f1, f, s1);
142: f = f1;
143: }
144: q = malloc(size);
145: if (q && q != f)
146: memcpy(q, f, s1);
147: return q;
148: }
149:
150: struct mchk;
151: typedef struct mchk mchk;
152: struct
153: mchk {
154: mchk *next;
155: char *mem;
156: int busy;
157: };
158:
159: #define Mhash 131
160: #define Mcgulp 1000
161:
162: static mchk *buckets[Mhash];
163: char * zork_mc;
164: int zork_mck;
165:
166: static void
167: mcheck(x, freeing)
168: register char *x;
169: int freeing;
170: {
171: register mchk *mc, **mc0;
172: static int in_mcheck, nzork;
173: static mchk *mnext, *mlast;
174:
175: if (x == zork_mc && ++nzork >= zork_mck)
176: printf("");
177:
178: mc0 = &buckets[((unsigned long)x>>3) % Mhash];
179: for(mc = *mc0; mc; mc = mc->next)
180: if (mc->mem == x) {
181: if (freeing) {
182: if (mc->busy) {
183: mc->busy = 0;
184: return;
185: }
186: free_error:
187: fprintf(stderr, "free error! x = 0x%lx\n", x);
188: exit(1);
189: }
190: if (mc->busy) {
191: fprintf(stderr, "malloc errof! x = 0x%lx\n", x);
192: exit(2);
193: }
194: mc->busy = 1;
195: return;
196: }
197: if (freeing)
198: goto free_error;
199: if (mnext >= mlast) {
200: if (in_mcheck)
201: return;
202: in_mcheck = 1;
203: mnext = (mchk *)malloc(Mcgulp*sizeof(mchk));
204: in_mcheck = 0;
205: if (!mnext) {
206: fprintf(stderr, "malloc failure in mcheck!\n");
207: exit(3);
208: }
209: mlast = mnext + Mcgulp;
210: }
211: mc = mnext++;
212: mc->next = *mc0;
213: *mc0 = mc;
214: mc->mem = x;
215: mc->busy = 1;
216: }
217: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.