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);
}
|