home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <malloc.h>
-
- /* Each memory block has 8 extra 32-bit values associated with it. If malloc
- returns the pointer p to you, the state really looks like:
-
- jmal(p)------> |------------------------------------------------------------|
- | flink (next malloc block in absolute order) |
- |------------------------------------------------------------|
- | blink (prev malloc block in absolute order) |
- |------------------------------------------------------------|
- | nextfree (next free malloc block - no particular order) |
- |------------------------------------------------------------|
- | prevfree (next free malloc block - no particular order) |
- |------------------------------------------------------------|
- | size (size of memory allocated) |
- |------------------------------------------------------------|
- | cs2 (pointer to the second checksum, which is right after |
- | the mem block) |
- |------------------------------------------------------------|
- | cs (checksum right before mem block. used to determine if |
- | there is an error of writing around the memory block) |
- p------------> |------------------------------------------------------------|
- | space: the memory block |
- | ... |
- | ... |
- |------------------------------------------------------------|
- | the second checksum |
- |------------------------------------------------------------|
- */
-
-
- typedef struct jmalloc {
- struct jmalloc *flink;
- struct jmalloc *blink;
- struct jmalloc *nextfree;
- struct jmalloc *prevfree;
- int size;
- int *cs2;
- int cs;
- char *space;
- } *Jmalloc;
-
- #define JMSZ (sizeof(struct jmalloc))
- #define PTSZ (sizeof(char *)) /* Also assuming its > sizeof int */
- #define CHUNK_SIZE (16384 - JMSZ) /* 16K */
- #define MASK 0x17826a9b
- #define JNULL ((Jmalloc) 0)
-
- static struct jmalloc j_head;
- static Jmalloc memlist;
- static int nfree = 0;
- static int nblocks = 0;
- static int init = 0;
- static Jmalloc start;
- static int free_called = 0;
- static int malloc_called = 0;
- static int used_mem = 0;
- static int free_mem = 0;
- static int used_blocks = 0;
- static int free_blocks = 0;
-
- #define cksum(p) (((int) &(p->cs)) - 1)
- #define jloc(l) ((char *) (&l->space))
- #define jmal(l) ((Jmalloc) (((char *)l) - JMSZ + PTSZ))
- #define isfree(l) (l->nextfree != JNULL)
-
- #define do_init() \
- if (!init) {\
- memlist = &j_head;\
- memlist->flink = memlist;\
- memlist->blink = memlist;\
- memlist->nextfree = memlist;\
- memlist->prevfree = memlist;\
- memlist->size = 0;\
- memlist->cs = cksum(memlist);\
- memlist->cs2 = &memlist->cs;\
- memlist->space = (char *) 0;\
- start = memlist;\
- init = 1;\
- }
-
- dump_core()
- {
- memlist->space[0] = 0;
- }
-
- char *set_used(l)
- Jmalloc l;
- {
- start = l->nextfree;
- l->prevfree->nextfree = l->nextfree;
- l->nextfree->prevfree = l->prevfree;
- l->prevfree = JNULL;
- l->nextfree = JNULL;
- used_mem += l->size;
- free_mem -= l->size;
- used_blocks++;
- free_blocks--;
-
- return jloc(l);
- }
-
- void *malloc(size)
- int size;
- {
- int redo;
- int done;
- Jmalloc l;
- char *tmp;
- Jmalloc newl;
- int newsize;
-
- do_init();
- malloc_called++;
- if (size <= 0) {
- fprintf(stderr, "Error: Malloc(%d) called\n", size);
- /* Dump core */
- dump_core();
- }
-
- if (size % PTSZ != 0) size += PTSZ - (size % PTSZ);
-
- done = 0;
- l = start;
- while(!done) {
- if (l->size >= size) {
- done = 1;
- redo = 0;
- } else {
- l = l->nextfree;
- done = (l == start);
- redo = done;
- }
- }
-
- if (redo) {
- if (size > CHUNK_SIZE)
- newsize = size + JMSZ;
- else newsize = CHUNK_SIZE + JMSZ;
- newl = (Jmalloc) sbrk(newsize);
- while (newl == (Jmalloc) -1 && newsize > size + JMSZ) {
- newsize /= 2;
- if (newsize < size + JMSZ) newsize = size + JMSZ;
- newl = (Jmalloc) sbrk(newsize);
- }
-
- if (newl == (Jmalloc) -1) {
- /* fprintf(stderr, "Jmalloc: out of memory\n"); */
- /* fprintf(stderr, "Used bytes = %d, Free bytes = %d\n", */
- /* used_mem, free_mem); */
- /* fprintf(stderr, "Trying to get %d bytes (chunk of %d)\n", */
- /* size, newsize); */
- return NULL;
- }
- newl->flink = memlist;
- newl->blink = memlist->blink;
- newl->flink->blink = newl;
- newl->blink->flink = newl;
- newl->nextfree = memlist;
- newl->prevfree = memlist->prevfree;
- newl->nextfree->prevfree = newl;
- newl->prevfree->nextfree = newl;
- newl->size = ((char *) sbrk(0)) - jloc(newl) - PTSZ;
- free_mem += newl->size;
- newl->cs = cksum(newl);
- newl->cs2 = ((int *) (jloc(newl) + newl->size));
- *(newl->cs2) = cksum(newl);
- if(newl->size < size) {
- fprintf(stderr, "Newl->size(%d) < size(%d)\n", newl->size, size);
- exit(1);
- }
- free_blocks++;
- l = newl;
- }
-
- if (l->size - size < JMSZ) {
- return set_used(l);
- } else {
- tmp = jloc(l);
- newl = (Jmalloc) (tmp + size + PTSZ);
- newl->flink = l->flink;
- newl->blink = l;
- newl->flink->blink = newl;
- newl->blink->flink = newl;
- newl->nextfree = l->nextfree;
- newl->prevfree = l;
- newl->nextfree->prevfree = newl;
- newl->prevfree->nextfree = newl;
- newl->size = l->size - size - JMSZ;
- newl->cs = cksum(newl);
- newl->cs2 = (int *) (jloc(newl) + newl->size);
- *(newl->cs2) = cksum(newl);
- free_mem += size + newl->size - l->size;
- free_blocks++;
- l->size = size;
- l->cs2 = ((int *) (jloc(l) + l->size));
- *(l->cs2) = cksum(l);
- return set_used(l);
- }
- }
-
- jmalloc_print_mem()
- {
- Jmalloc l;
- int done;
- char *bufs[100];
- int sizes[100];
- int mc;
- int fc;
- int i, j;
-
- do_init();
- mc = malloc_called;
- fc = free_called;
- if (jmal(jloc(memlist)) != memlist) {
- fprintf(stderr, "TROUBLE: memlist=0x%x, jmal(jloc(memlist))=0x%x)\n",
- memlist, jmal(jloc(memlist)));
- exit(1);
- }
- done = 0;
- l = start;
- i = 0;
- while (!done) {
- if (cksum(l) != l->cs) {
- printf("Memory location 0x%x corrupted\n", jloc(l));
- exit(1);
- } else if (cksum(l) != *(l->cs2)) {
- printf("Memory location 0x%x corrupted\n", jloc(l));
- exit(1);
- }
-
- bufs[i] = jloc(l);
- sizes[i] = l->size;
- if (l->nextfree == 0) sizes[i] = -sizes[i];
- i++;
- l = l->flink;
- done = ((l == start) || i >= 100);
- }
- printf("Malloc called %d times\n", mc);
- printf("Free called %d times\n", fc);
- for (j = 0; j < i; j++) {
- printf("Loc = 0x%x, size = %d, free = %d\n", bufs[j],
- (sizes[j] > 0) ? sizes[j] : -sizes[j], (sizes[j] >= 0));
- }
- }
-
- jmalloc_check_mem()
- {
- Jmalloc l;
- int done;
-
- done = 0;
-
- l = start;
-
- while (!done) {
- if (cksum(l) != l->cs) {
- fprintf(stderr, "Memory chunk violated: 0x%x: %s 0x%x. %s 0x%x\n",
- jloc(l), "Checksum 1 is ", l->cs, "It should be", cksum(l));
- dump_core();
- } else if (cksum(l) != *(l->cs2)) {
- fprintf(stderr, "Memory chunk violated: 0x%x: %s 0x%x. %s 0x%x\n",
- jloc(l), "Checksum 2 is ", *(l->cs2), "It should be", cksum(l));
- dump_core();
- }
- l = l->flink;
- done = (l == start);
- }
- }
-
-
- void free(loc)
- char *loc;
- {
- Jmalloc l;
- Jmalloc pl, nl;
-
- do_init();
- free_called++;
- l = jmal(loc);
-
- if (cksum(l) != l->cs) {
- fprintf(stderr, "Error on free: memory chunk violated: 0x%x\n", loc);
- dump_core();
- } else if (cksum(l) != *(l->cs2)) {
- fprintf(stderr, "Error on free: memory chunk violated: 0x%x\n", loc);
- dump_core();
- }
-
- used_mem -= l->size;
- free_mem += l->size;
- free_blocks++;
- used_blocks--;
-
- pl = l->blink;
- nl = l->flink;
- if (isfree(pl) && (jloc(pl)+pl->size + PTSZ == (char *) l)) {
- free_mem += JMSZ;
- pl->size += l->size + JMSZ;
- pl->flink = nl;
- pl->flink->blink = pl;
- l = pl;
- free_blocks--;
- } else {
- l->prevfree = start;
- l->nextfree = start->nextfree;
- l->nextfree->prevfree = l;
- l->prevfree->nextfree = l;
- }
-
- if (isfree(nl) && jloc(l)+l->size + PTSZ == (char *) nl) {
- free_mem += JMSZ;
- l->size += nl->size + JMSZ;
- l->flink = nl->flink;
- l->flink->blink = l;
- free_blocks--;
- nl->nextfree->prevfree = nl->prevfree;
- nl->prevfree->nextfree = nl->nextfree;
- }
- start = l;
- }
-
- void *realloc(loc, size)
- char *loc;
- int size;
- {
- Jmalloc l;
- Jmalloc l2, nl;
- char *loc2;
- int i;
- Jmalloc newl;
-
-
- do_init();
-
- if (size <= 0) {
- fprintf(stderr, "Error: Malloc(%d) called\n", size);
- /* Dump core */
- dump_core();
- }
-
- if (size % PTSZ != 0) size += PTSZ - (size % PTSZ);
-
- l = jmal(loc);
-
- if (cksum(l) != l->cs) {
- fprintf(stderr, "Error on realloc: memory chunk violated: 0x%x\n", loc);
- dump_core();
- } else if (cksum(l) != *(l->cs2)) {
- fprintf(stderr, "Error on realloc: memory chunk violated: 0x%x\n", loc);
- dump_core();
- }
-
- if (size < l->size) {
- if (l->size - size < JMSZ + 4) return loc;
- newl = (Jmalloc) (loc + size + PTSZ);
- newl->flink = l->flink;
- newl->blink = l;
- newl->flink->blink = newl;
- newl->blink->flink = newl;
- newl->nextfree = start->nextfree;
- newl->prevfree = start;
- newl->nextfree->prevfree = newl;
- newl->prevfree->nextfree = newl;
- newl->size = l->size - size - JMSZ;
- newl->cs = cksum(newl);
- newl->cs2 = (int *) (jloc(newl) + newl->size);
- *(newl->cs2) = cksum(newl);
- used_mem += size - l->size;
- free_mem += newl->size;
- free_blocks++;
- l->size = size;
- l->cs2 = ((int *) (jloc(l) + l->size));
- *(l->cs2) = cksum(l);
- start = newl;
- return loc;
- }
-
-
- nl = l->flink;
-
- if (isfree(nl) && (jloc(l)+l->size + PTSZ == (char *) nl) &&
- l->size + JMSZ + nl->size >= size) {
- start = nl;
- i = size - l->size - JMSZ;
- if (i < 0) i = 4;
- loc2 = malloc(i);
- l2 = jmal(loc2);
- if (l2 != nl) {
- fprintf(stderr, "Realloc internal error: l2 != nl\n");
- dump_core();
- }
-
- nl->flink->blink = nl->blink;
- nl->blink->flink = nl->flink;
- free_mem -= nl->size;
- used_mem += nl->size + JMSZ;
- free_blocks--;
- l->size += nl->size + JMSZ;
- l->cs2 = ((int *) (jloc(l) + l->size));
- *(l->cs2) = cksum(l);
- return loc;
- } else {
- loc2 = malloc(size);
- for (i = 0; i < l->size; i++) loc2[i] = loc[i];
- free(loc);
- return loc2;
- }
- }
-
- char *calloc(nelem, elsize)
- int nelem, elsize;
- {
- int *iptr;
- char *ptr;
- int sz;
- int i;
-
- sz = nelem*elsize;
- ptr = malloc(sz);
- iptr = (int *) ptr;
-
- for (i = 0; i < sz/sizeof(int); i++) iptr[i] = 0;
- for (i = i * sizeof(int); i < sz; i++) ptr[i] = 0;
- return ptr;
- }
-
- int mallopt(cmd, value)
- int cmd, value;
- {
- fprintf(stderr, "Mallopt is not defined...\n");
- exit(1);
- }
-
-
- jmalloc_usage()
- {
- fprintf(stderr, "Jmalloc: %d %s %d block%s. %d %s %d block%s\n",
- used_mem, "bytes used in", used_blocks,
- (used_blocks == 1) ? "" : "s",
- free_mem, "bytes free in", free_blocks,
- (free_blocks == 1) ? "" : "s");
- }
-