1 /****************************************************************
2 Copyright 1990, 1994 by AT&T, Lucent Technologies 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,
10 Lucent or Bellcore or any of their entities not be used in
11 advertising or publicity pertaining to distribution of the
12 software without specific, written prior permission.
13
14 AT&T, Lucent and Bellcore disclaim all warranties with regard to
15 this software, including all implied warranties of
16 merchantability and fitness. In no event shall AT&T, Lucent or
17 Bellcore be liable for any special, indirect or consequential
18 damages or any damages whatsoever resulting from loss of use,
19 data or profits, whether in an action of contract, negligence or
20 other tortious action, arising out of or in connection with the
21 use or performance of this software.
22 ****************************************************************/
23
24 #ifndef CRAY
25 #define STACKMIN 512
26 #define MINBLK (2*sizeof(struct mem) + 16)
27 #define F _malloc_free_
28 #define SBGULP 8192
29 #include "string.h" /* for memcpy */
30
31 #ifdef KR_headers
32 #define Char char
33 #define Unsigned unsigned
34 #define Int /*int*/
35 #else
36 #define Char void
37 #define Unsigned size_t
38 #define Int int
39 #endif
40
41 typedef struct mem {
42 struct mem *next;
43 Unsigned len;
44 } mem;
45
46 mem *F;
47
48 Char *
49 #ifdef KR_headers
malloc(size)50 malloc(size)
51 register Unsigned size;
52 #else
53 malloc(register Unsigned size)
54 #endif
55 {
56 register mem *p, *q, *r, *s;
57 unsigned register k, m;
58 extern Char *sbrk(Int);
59 char *top, *top1;
60
61 size = (size+7) & ~7;
62 r = (mem *) &F;
63 for (p = F, q = 0; p; r = p, p = p->next) {
64 if ((k = p->len) >= size && (!q || m > k)) {
65 m = k;
66 q = p;
67 s = r;
68 }
69 }
70 if (q) {
71 if (q->len - size >= MINBLK) { /* split block */
72 p = (mem *) (((char *) (q+1)) + size);
73 p->next = q->next;
74 p->len = q->len - size - sizeof(mem);
75 s->next = p;
76 q->len = size;
77 }
78 else
79 s->next = q->next;
80 }
81 else {
82 top = (Char *)(((long)sbrk(0) + 7) & ~7);
83 if (F && (char *)(F+1) + F->len == top) {
84 q = F;
85 F = F->next;
86 }
87 else
88 q = (mem *) top;
89 top1 = (char *)(q+1) + size;
90 if (sbrk((int)(top1-top+SBGULP)) == (Char *) -1)
91 return 0;
92 r = (mem *)top1;
93 r->len = SBGULP - sizeof(mem);
94 r->next = F;
95 F = r;
96 q->len = size;
97 }
98 return (Char *) (q+1);
99 }
100
101 void
102 #ifdef KR_headers
free(f)103 free(f)
104 Char *f;
105 #else
106 free(Char *f)
107 #endif
108 {
109 mem *p, *q, *r;
110 char *pn, *qn;
111
112 if (!f) return;
113 q = (mem *) ((char *)f - sizeof(mem));
114 qn = (char *)f + q->len;
115 for (p = F, r = (mem *) &F; ; r = p, p = p->next) {
116 if (qn == (Char *) p) {
117 q->len += p->len + sizeof(mem);
118 p = p->next;
119 }
120 pn = p ? ((char *) (p+1)) + p->len : 0;
121 if (pn == (Char *) q) {
122 p->len += sizeof(mem) + q->len;
123 q->len = 0;
124 q->next = p;
125 r->next = p;
126 break;
127 }
128 if (pn < (char *) q) {
129 r->next = q;
130 q->next = p;
131 break;
132 }
133 }
134 }
135
136 Char *
137 #ifdef KR_headers
realloc(f,size)138 realloc(f, size)
139 Char *f;
140 Unsigned size;
141 #else
142 realloc(Char *f, Unsigned size)
143 #endif
144 {
145 mem *p;
146 Char *q, *f1;
147 Unsigned s1;
148
149 if (!f) return malloc(size);
150 p = (mem *) ((char *)f - sizeof(mem));
151 s1 = p->len;
152 free(f);
153 if (s1 > size)
154 s1 = size + 7 & ~7;
155 if (!p->len) {
156 f1 = (Char *)(p->next + 1);
157 memcpy(f1, f, s1);
158 f = f1;
159 }
160 q = malloc(size);
161 if (q && q != f)
162 memcpy(q, f, s1);
163 return q;
164 }
165 #endif
166