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
|
#include <stdlib.h>
#define XSIZE(x) ((*x)>>1)
#define FREE_P(x) (!((*x)&1))
#define MARK_BUSY(x) ((*x)|=1)
#define MARK_FREE(x) ((*x)&=0xfffe)
extern size_t __bss_end;
#define GET_HEAP_BOTTOM(h) asm volatile ("in %A0, __SP_L__\n\t" \
"in %B0, __SP_H__" : "=r" (h) :)
void *malloc (size_t size)
{
static char once;
size_t * heap_bottom;
size_t * heap_top = &__bss_end;
char f = 0;
if (!once) {
once = 1;
*heap_top = 0xFFFE;
}
GET_HEAP_BOTTOM (heap_bottom);
heap_bottom -= 20;
size = (size+1) >> 1; /* round to 2 */
do
{
size_t xsize = XSIZE (heap_top);
size_t * heap_next = &heap_top[xsize + 1];
if ((xsize<<1)+2 == 0)
{
f = 1;
}
if (FREE_P (heap_top))
{
if (f)
{
xsize = heap_bottom - heap_top - 1;
}
else if (FREE_P(heap_next))
{
*heap_top = ( (XSIZE(heap_next)<<1) + 2 == 0
? 0xfffe
: (xsize + XSIZE(heap_next) + 1)<<1);
continue;
}
if (xsize >= size)
{
if (f)
heap_top[size + 1] = 0xfffe;
else if (xsize != size)
heap_top[size + 1] = (xsize - size - 1) << 1;
*heap_top = size << 1;
MARK_BUSY (heap_top);
return heap_top+1;
}
}
heap_top += xsize + 1;
} while (!f);
return NULL;
}
void free (void *p)
{
size_t *t = (size_t*)p - 1;
MARK_FREE (t);
}
|