Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4973 | right-hear | 1 | #include |
2 | #include |
||
3 | #include |
||
4 | |||
5 | static void * ___brk_addr = 0; |
||
6 | extern char end[]; |
||
7 | static unsigned long min_brk,max_brk,cur_brk; |
||
8 | extern unsigned long __menuet__memsize; |
||
9 | static void* cur_dynamic_area; |
||
10 | static unsigned cur_total_size; |
||
11 | |||
12 | static inline void heap_init(void) |
||
13 | { |
||
14 | __asm__("int $0x40" :: "a"(68),"b"(11)); |
||
15 | } |
||
16 | |||
17 | static inline void* heap_alloc(unsigned size) |
||
18 | { |
||
19 | void* res; |
||
20 | __asm__("int $0x40" : "=a"(res) : "a"(68),"b"(12),"c"(size)); |
||
21 | return res; |
||
22 | } |
||
23 | |||
24 | static inline void heap_free(void* ptr) |
||
25 | { |
||
26 | __asm__("int $0x40" :: "a"(68),"b"(13),"c"(ptr)); |
||
27 | } |
||
28 | |||
29 | void init_brk(void) |
||
30 | { |
||
31 | cur_brk=min_brk=(((unsigned long)&end)+0xfff)&~0xfff; |
||
32 | max_brk=(__menuet__memsize-32768)&~0xfff; |
||
33 | ___brk_addr=(void *)min_brk; |
||
34 | cur_dynamic_area = NULL; |
||
35 | cur_total_size = max_brk; |
||
36 | heap_init(); |
||
37 | } |
||
38 | |||
39 | /*static int sys_brk(unsigned long end_data_seg) |
||
40 | { |
||
41 | if(!end_data_seg) return cur_brk; |
||
42 | if (end_data_seg >= min_brk && |
||
43 | end_data_seg < max_brk) |
||
44 | cur_brk = end_data_seg; |
||
45 | return cur_brk; |
||
46 | }*/ |
||
47 | |||
48 | /*int brk(void *_heaptop) |
||
49 | { |
||
50 | return sys_brk((unsigned long)_heaptop); |
||
51 | } |
||
52 | |||
53 | static int __init_brk (void) |
||
54 | { |
||
55 | if (___brk_addr == 0) |
||
56 | { |
||
57 | ___brk_addr=(void *)sys_brk(0); |
||
58 | if (___brk_addr == 0) |
||
59 | { |
||
60 | errno = ENOMEM; |
||
61 | return -1; |
||
62 | } |
||
63 | } |
||
64 | return 0; |
||
65 | }*/ |
||
66 | |||
67 | void * sbrk(int increment) |
||
68 | { |
||
69 | /* if (__init_brk () == 0) |
||
70 | { |
||
71 | void * tmp = ___brk_addr+increment; |
||
72 | ___brk_addr=(void *)sys_brk((unsigned long)tmp); |
||
73 | if (___brk_addr == tmp) return tmp-increment; |
||
74 | errno = ENOMEM; |
||
75 | return ((void *) -1); |
||
76 | } |
||
77 | return ((void *) -1);*/ |
||
78 | void* res; |
||
79 | unsigned long tmp; |
||
80 | if (increment <= 0) |
||
81 | { |
||
82 | /* release memory */ |
||
83 | while (cur_dynamic_area && increment) |
||
84 | { |
||
85 | tmp = cur_brk - (unsigned long)cur_dynamic_area - |
||
86 | 3*sizeof(void*); |
||
87 | if (tmp > increment) |
||
88 | tmp = increment; |
||
89 | cur_brk -= tmp; |
||
90 | increment -= tmp; |
||
91 | if (cur_brk == (unsigned long)cur_dynamic_area + 3*sizeof(void*)) |
||
92 | { |
||
93 | cur_brk = (unsigned long)((void**)cur_dynamic_area)[1]; |
||
94 | max_brk = (unsigned long)((void**)cur_dynamic_area)[2]; |
||
95 | res = cur_dynamic_area; |
||
96 | cur_dynamic_area = ((void**)cur_dynamic_area)[0]; |
||
97 | heap_free(res); |
||
98 | } |
||
99 | } |
||
100 | if (!cur_dynamic_area) |
||
101 | { |
||
102 | cur_brk += increment; |
||
103 | if (cur_brk < min_brk) |
||
104 | cur_brk = min_brk; |
||
105 | } |
||
106 | return (void*)cur_brk; |
||
107 | } |
||
108 | /* allocate memory */ |
||
109 | if (cur_brk + increment <= max_brk) |
||
110 | { |
||
111 | /* We have memory in current block, so use it */ |
||
112 | res = (void*)cur_brk; |
||
113 | cur_brk += increment; |
||
114 | return res; |
||
115 | } |
||
116 | tmp = 65536; |
||
117 | /* We do not have memory in current block, so allocate new one */ |
||
118 | if (increment > 65536 - 3*sizeof(void*)) |
||
119 | tmp = (increment + 3*sizeof(void*) + 0xFFF) & ~0xFFF; |
||
120 | res = heap_alloc(tmp); |
||
121 | if (!res) |
||
122 | { |
||
123 | errno = ENOMEM; |
||
124 | return (void*)-1; |
||
125 | } |
||
126 | ((void**)res)[0] = cur_dynamic_area; |
||
127 | ((void**)res)[1] = (void*)cur_brk; |
||
128 | ((void**)res)[2] = (void*)max_brk; |
||
129 | cur_dynamic_area = res; |
||
130 | cur_brk = (unsigned long)res + 3*sizeof(void*); |
||
131 | max_brk = (unsigned long)res + tmp; |
||
132 | res = (void*)cur_brk; |
||
133 | cur_brk += increment; |
||
134 | return (void*)res; |
||
135 | }=>>=>> |