|
|
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.