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