1 | #include <stdio.h>
|
---|
2 | #include <malloc.h>
|
---|
3 |
|
---|
4 | /* Each memory block has 8 extra 32-bit values associated with it. If malloc
|
---|
5 | returns the pointer p to you, the state really looks like:
|
---|
6 |
|
---|
7 | jmal(p)------> |------------------------------------------------------------|
|
---|
8 | | flink (next malloc block in absolute order) |
|
---|
9 | |------------------------------------------------------------|
|
---|
10 | | blink (prev malloc block in absolute order) |
|
---|
11 | |------------------------------------------------------------|
|
---|
12 | | nextfree (next free malloc block - no particular order) |
|
---|
13 | |------------------------------------------------------------|
|
---|
14 | | prevfree (next free malloc block - no particular order) |
|
---|
15 | |------------------------------------------------------------|
|
---|
16 | | size (size of memory allocated) |
|
---|
17 | |------------------------------------------------------------|
|
---|
18 | | cs2 (pointer to the second checksum, which is right after |
|
---|
19 | | the mem block) |
|
---|
20 | |------------------------------------------------------------|
|
---|
21 | | cs (checksum right before mem block. used to determine if |
|
---|
22 | | there is an error of writing around the memory block) |
|
---|
23 | p------------> |------------------------------------------------------------|
|
---|
24 | | space: the memory block |
|
---|
25 | | ... |
|
---|
26 | | ... |
|
---|
27 | |------------------------------------------------------------|
|
---|
28 | | the second checksum |
|
---|
29 | |------------------------------------------------------------|
|
---|
30 | */
|
---|
31 |
|
---|
32 |
|
---|
33 | typedef struct jmalloc {
|
---|
34 | struct jmalloc *flink;
|
---|
35 | struct jmalloc *blink;
|
---|
36 | struct jmalloc *nextfree;
|
---|
37 | struct jmalloc *prevfree;
|
---|
38 | int size;
|
---|
39 | int *cs2;
|
---|
40 | int cs;
|
---|
41 | char *space;
|
---|
42 | } *Jmalloc;
|
---|
43 |
|
---|
44 | #define JMSZ (sizeof(struct jmalloc))
|
---|
45 | #define PTSZ (sizeof(char *)) /* Also assuming its > sizeof int */
|
---|
46 | #define CHUNK_SIZE (16384 - JMSZ) /* 16K */
|
---|
47 | #define MASK 0x17826a9b
|
---|
48 | #define JNULL ((Jmalloc) 0)
|
---|
49 |
|
---|
50 | static struct jmalloc j_head;
|
---|
51 | static Jmalloc memlist;
|
---|
52 | static int nfree = 0;
|
---|
53 | static int nblocks = 0;
|
---|
54 | static int init = 0;
|
---|
55 | static Jmalloc start;
|
---|
56 | static int free_called = 0;
|
---|
57 | static int malloc_called = 0;
|
---|
58 | static int used_mem = 0;
|
---|
59 | static int free_mem = 0;
|
---|
60 | static int used_blocks = 0;
|
---|
61 | static int free_blocks = 0;
|
---|
62 |
|
---|
63 | #define cksum(p) (((int) &(p->cs)) - 1)
|
---|
64 | #define jloc(l) ((char *) (&l->space))
|
---|
65 | #define jmal(l) ((Jmalloc) (((char *)l) - JMSZ + PTSZ))
|
---|
66 | #define isfree(l) (l->nextfree != JNULL)
|
---|
67 |
|
---|
68 | #define do_init() \
|
---|
69 | if (!init) {\
|
---|
70 | memlist = &j_head;\
|
---|
71 | memlist->flink = memlist;\
|
---|
72 | memlist->blink = memlist;\
|
---|
73 | memlist->nextfree = memlist;\
|
---|
74 | memlist->prevfree = memlist;\
|
---|
75 | memlist->size = 0;\
|
---|
76 | memlist->cs = cksum(memlist);\
|
---|
77 | memlist->cs2 = &memlist->cs;\
|
---|
78 | memlist->space = (char *) 0;\
|
---|
79 | start = memlist;\
|
---|
80 | init = 1;\
|
---|
81 | }
|
---|
82 |
|
---|
83 | dump_core()
|
---|
84 | {
|
---|
85 | memlist->space[0] = 0;
|
---|
86 | }
|
---|
87 |
|
---|
88 | char *set_used(l)
|
---|
89 | Jmalloc l;
|
---|
90 | {
|
---|
91 | start = l->nextfree;
|
---|
92 | l->prevfree->nextfree = l->nextfree;
|
---|
93 | l->nextfree->prevfree = l->prevfree;
|
---|
94 | l->prevfree = JNULL;
|
---|
95 | l->nextfree = JNULL;
|
---|
96 | used_mem += l->size;
|
---|
97 | free_mem -= l->size;
|
---|
98 | used_blocks++;
|
---|
99 | free_blocks--;
|
---|
100 |
|
---|
101 | return jloc(l);
|
---|
102 | }
|
---|
103 |
|
---|
104 | void *malloc(size)
|
---|
105 | int size;
|
---|
106 | {
|
---|
107 | int redo;
|
---|
108 | int done;
|
---|
109 | Jmalloc l;
|
---|
110 | char *tmp;
|
---|
111 | Jmalloc newl;
|
---|
112 | int newsize;
|
---|
113 |
|
---|
114 | do_init();
|
---|
115 | malloc_called++;
|
---|
116 | if (size <= 0) {
|
---|
117 | fprintf(stderr, "Error: Malloc(%d) called\n", size);
|
---|
118 | /* Dump core */
|
---|
119 | dump_core();
|
---|
120 | }
|
---|
121 |
|
---|
122 | if (size % PTSZ != 0) size += PTSZ - (size % PTSZ);
|
---|
123 |
|
---|
124 | done = 0;
|
---|
125 | l = start;
|
---|
126 | while(!done) {
|
---|
127 | if (l->size >= size) {
|
---|
128 | done = 1;
|
---|
129 | redo = 0;
|
---|
130 | } else {
|
---|
131 | l = l->nextfree;
|
---|
132 | done = (l == start);
|
---|
133 | redo = done;
|
---|
134 | }
|
---|
135 | }
|
---|
136 |
|
---|
137 | if (redo) {
|
---|
138 | if (size > CHUNK_SIZE)
|
---|
139 | newsize = size + JMSZ;
|
---|
140 | else newsize = CHUNK_SIZE + JMSZ;
|
---|
141 | newl = (Jmalloc) sbrk(newsize);
|
---|
142 | while (newl == (Jmalloc) -1 && newsize > size + JMSZ) {
|
---|
143 | newsize /= 2;
|
---|
144 | if (newsize < size + JMSZ) newsize = size + JMSZ;
|
---|
145 | newl = (Jmalloc) sbrk(newsize);
|
---|
146 | }
|
---|
147 |
|
---|
148 | if (newl == (Jmalloc) -1) {
|
---|
149 | /* fprintf(stderr, "Jmalloc: out of memory\n"); */
|
---|
150 | /* fprintf(stderr, "Used bytes = %d, Free bytes = %d\n", */
|
---|
151 | /* used_mem, free_mem); */
|
---|
152 | /* fprintf(stderr, "Trying to get %d bytes (chunk of %d)\n", */
|
---|
153 | /* size, newsize); */
|
---|
154 | return NULL;
|
---|
155 | }
|
---|
156 | newl->flink = memlist;
|
---|
157 | newl->blink = memlist->blink;
|
---|
158 | newl->flink->blink = newl;
|
---|
159 | newl->blink->flink = newl;
|
---|
160 | newl->nextfree = memlist;
|
---|
161 | newl->prevfree = memlist->prevfree;
|
---|
162 | newl->nextfree->prevfree = newl;
|
---|
163 | newl->prevfree->nextfree = newl;
|
---|
164 | newl->size = ((char *) sbrk(0)) - jloc(newl) - PTSZ;
|
---|
165 | free_mem += newl->size;
|
---|
166 | newl->cs = cksum(newl);
|
---|
167 | newl->cs2 = ((int *) (jloc(newl) + newl->size));
|
---|
168 | *(newl->cs2) = cksum(newl);
|
---|
169 | if(newl->size < size) {
|
---|
170 | fprintf(stderr, "Newl->size(%d) < size(%d)\n", newl->size, size);
|
---|
171 | exit(1);
|
---|
172 | }
|
---|
173 | free_blocks++;
|
---|
174 | l = newl;
|
---|
175 | }
|
---|
176 |
|
---|
177 | if (l->size - size < JMSZ) {
|
---|
178 | return set_used(l);
|
---|
179 | } else {
|
---|
180 | tmp = jloc(l);
|
---|
181 | newl = (Jmalloc) (tmp + size + PTSZ);
|
---|
182 | newl->flink = l->flink;
|
---|
183 | newl->blink = l;
|
---|
184 | newl->flink->blink = newl;
|
---|
185 | newl->blink->flink = newl;
|
---|
186 | newl->nextfree = l->nextfree;
|
---|
187 | newl->prevfree = l;
|
---|
188 | newl->nextfree->prevfree = newl;
|
---|
189 | newl->prevfree->nextfree = newl;
|
---|
190 | newl->size = l->size - size - JMSZ;
|
---|
191 | newl->cs = cksum(newl);
|
---|
192 | newl->cs2 = (int *) (jloc(newl) + newl->size);
|
---|
193 | *(newl->cs2) = cksum(newl);
|
---|
194 | free_mem += size + newl->size - l->size;
|
---|
195 | free_blocks++;
|
---|
196 | l->size = size;
|
---|
197 | l->cs2 = ((int *) (jloc(l) + l->size));
|
---|
198 | *(l->cs2) = cksum(l);
|
---|
199 | return set_used(l);
|
---|
200 | }
|
---|
201 | }
|
---|
202 |
|
---|
203 | jmalloc_print_mem()
|
---|
204 | {
|
---|
205 | Jmalloc l;
|
---|
206 | int done;
|
---|
207 | char *bufs[100];
|
---|
208 | int sizes[100];
|
---|
209 | int mc;
|
---|
210 | int fc;
|
---|
211 | int i, j;
|
---|
212 |
|
---|
213 | do_init();
|
---|
214 | mc = malloc_called;
|
---|
215 | fc = free_called;
|
---|
216 | if (jmal(jloc(memlist)) != memlist) {
|
---|
217 | fprintf(stderr, "TROUBLE: memlist=0x%x, jmal(jloc(memlist))=0x%x)\n",
|
---|
218 | memlist, jmal(jloc(memlist)));
|
---|
219 | exit(1);
|
---|
220 | }
|
---|
221 | done = 0;
|
---|
222 | l = start;
|
---|
223 | i = 0;
|
---|
224 | while (!done) {
|
---|
225 | if (cksum(l) != l->cs) {
|
---|
226 | printf("Memory location 0x%x corrupted\n", jloc(l));
|
---|
227 | exit(1);
|
---|
228 | } else if (cksum(l) != *(l->cs2)) {
|
---|
229 | printf("Memory location 0x%x corrupted\n", jloc(l));
|
---|
230 | exit(1);
|
---|
231 | }
|
---|
232 |
|
---|
233 | bufs[i] = jloc(l);
|
---|
234 | sizes[i] = l->size;
|
---|
235 | if (l->nextfree == 0) sizes[i] = -sizes[i];
|
---|
236 | i++;
|
---|
237 | l = l->flink;
|
---|
238 | done = ((l == start) || i >= 100);
|
---|
239 | }
|
---|
240 | printf("Malloc called %d times\n", mc);
|
---|
241 | printf("Free called %d times\n", fc);
|
---|
242 | for (j = 0; j < i; j++) {
|
---|
243 | printf("Loc = 0x%x, size = %d, free = %d\n", bufs[j],
|
---|
244 | (sizes[j] > 0) ? sizes[j] : -sizes[j], (sizes[j] >= 0));
|
---|
245 | }
|
---|
246 | }
|
---|
247 |
|
---|
248 | jmalloc_check_mem()
|
---|
249 | {
|
---|
250 | Jmalloc l;
|
---|
251 | int done;
|
---|
252 |
|
---|
253 | done = 0;
|
---|
254 |
|
---|
255 | l = start;
|
---|
256 |
|
---|
257 | while (!done) {
|
---|
258 | if (cksum(l) != l->cs) {
|
---|
259 | fprintf(stderr, "Memory chunk violated: 0x%x: %s 0x%x. %s 0x%x\n",
|
---|
260 | jloc(l), "Checksum 1 is ", l->cs, "It should be", cksum(l));
|
---|
261 | dump_core();
|
---|
262 | } else if (cksum(l) != *(l->cs2)) {
|
---|
263 | fprintf(stderr, "Memory chunk violated: 0x%x: %s 0x%x. %s 0x%x\n",
|
---|
264 | jloc(l), "Checksum 2 is ", *(l->cs2), "It should be", cksum(l));
|
---|
265 | dump_core();
|
---|
266 | }
|
---|
267 | l = l->flink;
|
---|
268 | done = (l == start);
|
---|
269 | }
|
---|
270 | }
|
---|
271 |
|
---|
272 |
|
---|
273 | void free(loc)
|
---|
274 | char *loc;
|
---|
275 | {
|
---|
276 | Jmalloc l;
|
---|
277 | Jmalloc pl, nl;
|
---|
278 |
|
---|
279 | do_init();
|
---|
280 | free_called++;
|
---|
281 | l = jmal(loc);
|
---|
282 |
|
---|
283 | if (cksum(l) != l->cs) {
|
---|
284 | fprintf(stderr, "Error on free: memory chunk violated: 0x%x\n", loc);
|
---|
285 | dump_core();
|
---|
286 | } else if (cksum(l) != *(l->cs2)) {
|
---|
287 | fprintf(stderr, "Error on free: memory chunk violated: 0x%x\n", loc);
|
---|
288 | dump_core();
|
---|
289 | }
|
---|
290 |
|
---|
291 | used_mem -= l->size;
|
---|
292 | free_mem += l->size;
|
---|
293 | free_blocks++;
|
---|
294 | used_blocks--;
|
---|
295 |
|
---|
296 | pl = l->blink;
|
---|
297 | nl = l->flink;
|
---|
298 | if (isfree(pl) && (jloc(pl)+pl->size + PTSZ == (char *) l)) {
|
---|
299 | free_mem += JMSZ;
|
---|
300 | pl->size += l->size + JMSZ;
|
---|
301 | pl->flink = nl;
|
---|
302 | pl->flink->blink = pl;
|
---|
303 | l = pl;
|
---|
304 | free_blocks--;
|
---|
305 | } else {
|
---|
306 | l->prevfree = start;
|
---|
307 | l->nextfree = start->nextfree;
|
---|
308 | l->nextfree->prevfree = l;
|
---|
309 | l->prevfree->nextfree = l;
|
---|
310 | }
|
---|
311 |
|
---|
312 | if (isfree(nl) && jloc(l)+l->size + PTSZ == (char *) nl) {
|
---|
313 | free_mem += JMSZ;
|
---|
314 | l->size += nl->size + JMSZ;
|
---|
315 | l->flink = nl->flink;
|
---|
316 | l->flink->blink = l;
|
---|
317 | free_blocks--;
|
---|
318 | nl->nextfree->prevfree = nl->prevfree;
|
---|
319 | nl->prevfree->nextfree = nl->nextfree;
|
---|
320 | }
|
---|
321 | start = l;
|
---|
322 | }
|
---|
323 |
|
---|
324 | void *realloc(loc, size)
|
---|
325 | char *loc;
|
---|
326 | int size;
|
---|
327 | {
|
---|
328 | Jmalloc l;
|
---|
329 | Jmalloc l2, nl;
|
---|
330 | char *loc2;
|
---|
331 | int i;
|
---|
332 | Jmalloc newl;
|
---|
333 |
|
---|
334 |
|
---|
335 | do_init();
|
---|
336 |
|
---|
337 | if (size <= 0) {
|
---|
338 | fprintf(stderr, "Error: Malloc(%d) called\n", size);
|
---|
339 | /* Dump core */
|
---|
340 | dump_core();
|
---|
341 | }
|
---|
342 |
|
---|
343 | if (size % PTSZ != 0) size += PTSZ - (size % PTSZ);
|
---|
344 |
|
---|
345 | l = jmal(loc);
|
---|
346 |
|
---|
347 | if (cksum(l) != l->cs) {
|
---|
348 | fprintf(stderr, "Error on realloc: memory chunk violated: 0x%x\n", loc);
|
---|
349 | dump_core();
|
---|
350 | } else if (cksum(l) != *(l->cs2)) {
|
---|
351 | fprintf(stderr, "Error on realloc: memory chunk violated: 0x%x\n", loc);
|
---|
352 | dump_core();
|
---|
353 | }
|
---|
354 |
|
---|
355 | if (size < l->size) {
|
---|
356 | if (l->size - size < JMSZ + 4) return loc;
|
---|
357 | newl = (Jmalloc) (loc + size + PTSZ);
|
---|
358 | newl->flink = l->flink;
|
---|
359 | newl->blink = l;
|
---|
360 | newl->flink->blink = newl;
|
---|
361 | newl->blink->flink = newl;
|
---|
362 | newl->nextfree = start->nextfree;
|
---|
363 | newl->prevfree = start;
|
---|
364 | newl->nextfree->prevfree = newl;
|
---|
365 | newl->prevfree->nextfree = newl;
|
---|
366 | newl->size = l->size - size - JMSZ;
|
---|
367 | newl->cs = cksum(newl);
|
---|
368 | newl->cs2 = (int *) (jloc(newl) + newl->size);
|
---|
369 | *(newl->cs2) = cksum(newl);
|
---|
370 | used_mem += size - l->size;
|
---|
371 | free_mem += newl->size;
|
---|
372 | free_blocks++;
|
---|
373 | l->size = size;
|
---|
374 | l->cs2 = ((int *) (jloc(l) + l->size));
|
---|
375 | *(l->cs2) = cksum(l);
|
---|
376 | start = newl;
|
---|
377 | return loc;
|
---|
378 | }
|
---|
379 |
|
---|
380 |
|
---|
381 | nl = l->flink;
|
---|
382 |
|
---|
383 | if (isfree(nl) && (jloc(l)+l->size + PTSZ == (char *) nl) &&
|
---|
384 | l->size + JMSZ + nl->size >= size) {
|
---|
385 | start = nl;
|
---|
386 | i = size - l->size - JMSZ;
|
---|
387 | if (i < 0) i = 4;
|
---|
388 | loc2 = malloc(i);
|
---|
389 | l2 = jmal(loc2);
|
---|
390 | if (l2 != nl) {
|
---|
391 | fprintf(stderr, "Realloc internal error: l2 != nl\n");
|
---|
392 | dump_core();
|
---|
393 | }
|
---|
394 |
|
---|
395 | nl->flink->blink = nl->blink;
|
---|
396 | nl->blink->flink = nl->flink;
|
---|
397 | free_mem -= nl->size;
|
---|
398 | used_mem += nl->size + JMSZ;
|
---|
399 | free_blocks--;
|
---|
400 | l->size += nl->size + JMSZ;
|
---|
401 | l->cs2 = ((int *) (jloc(l) + l->size));
|
---|
402 | *(l->cs2) = cksum(l);
|
---|
403 | return loc;
|
---|
404 | } else {
|
---|
405 | loc2 = malloc(size);
|
---|
406 | for (i = 0; i < l->size; i++) loc2[i] = loc[i];
|
---|
407 | free(loc);
|
---|
408 | return loc2;
|
---|
409 | }
|
---|
410 | }
|
---|
411 |
|
---|
412 | char *calloc(nelem, elsize)
|
---|
413 | int nelem, elsize;
|
---|
414 | {
|
---|
415 | int *iptr;
|
---|
416 | char *ptr;
|
---|
417 | int sz;
|
---|
418 | int i;
|
---|
419 |
|
---|
420 | sz = nelem*elsize;
|
---|
421 | ptr = malloc(sz);
|
---|
422 | iptr = (int *) ptr;
|
---|
423 |
|
---|
424 | for (i = 0; i < sz/sizeof(int); i++) iptr[i] = 0;
|
---|
425 | for (i = i * sizeof(int); i < sz; i++) ptr[i] = 0;
|
---|
426 | return ptr;
|
---|
427 | }
|
---|
428 |
|
---|
429 | int mallopt(cmd, value)
|
---|
430 | int cmd, value;
|
---|
431 | {
|
---|
432 | fprintf(stderr, "Mallopt is not defined...\n");
|
---|
433 | exit(1);
|
---|
434 | }
|
---|
435 |
|
---|
436 |
|
---|
437 | jmalloc_usage()
|
---|
438 | {
|
---|
439 | fprintf(stderr, "Jmalloc: %d %s %d block%s. %d %s %d block%s\n",
|
---|
440 | used_mem, "bytes used in", used_blocks,
|
---|
441 | (used_blocks == 1) ? "" : "s",
|
---|
442 | free_mem, "bytes free in", free_blocks,
|
---|
443 | (free_blocks == 1) ? "" : "s");
|
---|
444 | }
|
---|