2 * The malloc stuff taken from fstk project
4 * ------------ from fstk ---------------
5 * The malloc lib for fstk.
7 * Copyright (C) 2009, 2010 Liu Aleaxander -- All rights reserved.
8 * This file may be redistributed under the terms of the GNU Public License.
17 /* First, assume we just need 1M memory */
18 #define MEM_SIZE 0x100000
21 * Allocat memory from mem adrress 8M
23 * I will make this much more stable and robust when I'm going to
24 * implement the whole memory managerment thing
26 #define memory 0x800000
28 //static char memory[MEM_SIZE];
30 /* Next free memory address */
31 static struct mem_struct
*next_start
= (struct mem_struct
*)memory
;
32 static uint32_t mem_end
= (uint32_t)(memory
+ MEM_SIZE
);
35 static inline struct mem_struct
*get_next(struct mem_struct
*mm
)
37 uint32_t next
= (uint32_t)mm
+ mm
->size
;
42 return (struct mem_struct
*)next
;
46 * Here are the _merge_ functions, that merges a adjacent memory region,
47 * from front, or from back, or even merges both. It returns the headest
52 static struct mem_struct
* merge_front(struct mem_struct
*mm
,
53 struct mem_struct
*prev
)
55 struct mem_struct
*next
= get_next(mm
);
57 prev
->size
+= mm
->size
;
63 static struct mem_struct
* merge_back(struct mem_struct
*mm
,
64 struct mem_struct
*next
)
66 mm
->free
= 1; /* Mark it free first */
67 mm
->size
+= next
->size
;
69 next
= get_next(next
);
75 static struct mem_struct
* merge_both(struct mem_struct
*mm
,
76 struct mem_struct
*prev
,
77 struct mem_struct
*next
)
79 prev
->size
+= mm
->size
+ next
->size
;
81 next
= get_next(next
);
87 static inline struct mem_struct
* try_merge_front(struct mem_struct
*mm
)
91 mm
= merge_front(mm
, mm
->prev
);
95 static inline struct mem_struct
* try_merge_back(struct mem_struct
*mm
)
97 struct mem_struct
*next
= get_next(mm
);
101 merge_back(mm
, next
);
106 * Here's the main function, malloc, which allocates a memory rigon
107 * of size _size_. Returns NULL if failed, or the address newly allocated.
110 void *malloc(int size
)
112 struct mem_struct
*next
= next_start
;
113 struct mem_struct
*good
= next
, *prev
;
114 int size_needed
= (size
+ sizeof(struct mem_struct
) + 3) & ~3;
117 if (next
->free
&& next
->size
>= size_needed
) {
121 next
= get_next(next
);
123 if (good
->size
< size_needed
) {
124 printk("Out of memory, maybe we need append it\n");
126 } else if (good
->size
== size_needed
) {
128 * We just found a right memory that with the exact
129 * size we want. So we just Mark it _not_free_ here,
130 * and move on the _next_start_ pointer, even though
131 * the next may not be a right next start.
134 next_start
= get_next(good
);
137 size
= good
->size
; /* save the total size */
140 * Note: allocate a new memory region will not change
141 * it's prev memory, so we don't need change it here.
143 good
->free
= 0; /* Mark it not free any more */
144 good
->size
= size_needed
;
146 next
= get_next(good
);
148 next
->size
= size
- size_needed
;
149 /* check if it can contain 1 byte allocation at least */
150 if (next
->size
<= (int)sizeof(struct mem_struct
)) {
151 good
->size
= size
; /* restore the original size */
152 next_start
= get_next(good
);
158 next_start
= next
; /* Update next_start */
161 next
= get_next(next
);
165 next_start
= (struct mem_struct
*)memory
;
167 return (void *)((uint32_t)good
+ sizeof(struct mem_struct
));
172 struct mem_struct
*mm
= ptr
- sizeof(*mm
);
173 struct mem_struct
*prev
= mm
->prev
;
174 struct mem_struct
*next
= get_next(mm
);
177 mm
= try_merge_back(mm
);
179 mm
= try_merge_front(mm
);
180 else if (prev
->free
&& !next
->free
)
181 merge_front(mm
, prev
);
182 else if (!prev
->free
&& next
->free
)
183 merge_back(mm
, next
);
184 else if (prev
->free
&& next
->free
)
185 merge_both(mm
, prev
, next
);
198 struct mem_struct
*next
= (struct mem_struct
*)memory
;
200 printk("____________\n");
202 printk("%-6d %s\n", next
->size
, next
->free
? "Free" : "Notf");
203 next
= get_next(next
);
214 printk("malloc returned: %p\n", buf
);
215 floppy_reads(0, buf
, 2);
216 hexdump(buf
+ 512, 128);
220 void malloc_init(void)
223 struct mem_struct
*first
= (struct mem_struct
*)memory
;
226 first
->size
= MEM_SIZE
;