1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
#include <sys/malloc.h>
#include <stdio.h>
pmmalloc_hunk malloc_first;
void debug( char *fun, char *msg )
{
/* return; */
/* printf("%s: %s\n", fun, msg );*/
}
BYTE malloc_init(void)
{
if (malloc_first->magic!=MALLOC_MAGIC) {
/* Init by setting up the first hunk */
debug("malloc_init", "Setting up");
malloc_first = (pmmalloc_hunk)&malloc_heap_start;
malloc_first->next = NULL;
malloc_first->size = 0xDFFFU - 0x200 - sizeof(mmalloc_hunk) - (UWORD)&malloc_heap_start;
malloc_first->status = MALLOC_FREE;
malloc_first->magic = MALLOC_MAGIC;
return 0;
}
return -1;
}
void malloc_gc(void)
{
/* Do a garbage collect on the hunks to create bigger hunks */
/* Note: assumes that hunks are consecutive */
pmmalloc_hunk thisHunk, nextHunk;
UBYTE changed;
changed = 1;
debug("malloc_gc","Running");
while (changed) {
thisHunk = malloc_first;
changed = 0;
while (thisHunk && (thisHunk->magic==MALLOC_MAGIC)) {
if (thisHunk->status == MALLOC_FREE) {
nextHunk = thisHunk->next;
if (nextHunk->status == MALLOC_FREE) {
/* Must be consecutive */
changed = 1;
thisHunk->size+=nextHunk->size+sizeof(mmalloc_hunk);
thisHunk->next = nextHunk->next;
}
}
thisHunk=thisHunk->next;
}
if (thisHunk!=NULL)
debug("malloc_gc", "Corrupted malloc list found.");
}
}
void *malloc( UWORD size )
{
pmmalloc_hunk thisHunk, insertBefore;
pmmalloc_hunk newHunk;
UBYTE firstTry;
if (malloc_first->magic != MALLOC_MAGIC)
malloc_init();
firstTry = 1; /* Allows gc if no big enough hunk is found */
while (firstTry) {
thisHunk = malloc_first;
if (firstTry == 2)
firstTry = 0;
while (thisHunk&&(thisHunk->magic == MALLOC_MAGIC)) {
debug("malloc", "Entering hunk" );
if (thisHunk->status == MALLOC_FREE) {
debug("malloc", "Found free hunk" );
/* Free, is it big enough? */
if (thisHunk->size >= size+sizeof(mmalloc_hunk)) {
debug("malloc","Found a big enough hunk.");
/* Yes, big enough */
insertBefore = thisHunk->next;
newHunk = (pmmalloc_hunk)((UWORD)thisHunk + size + sizeof(mmalloc_hunk));
newHunk->size = thisHunk->size - sizeof(mmalloc_hunk) - size;
newHunk->status = MALLOC_FREE;
newHunk->next = insertBefore;
newHunk->magic = MALLOC_MAGIC;
thisHunk->size = size;
thisHunk->status = MALLOC_USED;
thisHunk->next = newHunk;
return (void *)((UWORD)thisHunk + sizeof(mmalloc_hunk));
}
}
thisHunk = thisHunk->next;
}
if (firstTry) {
/* Try again after a garbage collect */
malloc_gc();
firstTry = 2;
}
}
return NULL;
}
|