寫一個 API 包住 Buddy System 與 Object Allocator,當想要 allocate 的 memory 超過一個 PAGE_SIZE 時,使用 Buddy System,當小於 PAGE_SIZE 時使用 Object Allocator。
在有了 kmalloc 後,一些之前使用 static allocation 的變數,可以改用 kmalloc 進行 dynamic allocation
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
| void* kmalloc(uint64_t size) {
// size too large
if (size >= PAGE_SIZE) {
uart_printf("kmalloc using buddy\n");
int order;
for (int i = 0; i < MAX_BUDDY_ORDER; i++) {
if (size <= (uint64_t)((1 << i) * PAGE_SIZE)) {
order = i;
break;
}
}
return buddy_alloc(order);
}
else {
uart_printf("kmalloc using object allocator\n");
// check exist object allocator
for (int i = 0; i < MAX_OBJ_ALLOCTOR_NUM; i++) {
if ((uint64_t)obj_allocator[i].obj_size == size) {
return (void*) obj_alloc_kernel(i);
}
}
// register new obj allocator
int token = obj_alloc_register(size);
return obj_alloc_kernel(token);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| void kfree(void* addr) {
for (int i = 0; i < MAX_OBJ_ALLOCTOR_NUM; i++) {
struct pool_t pool = obj_allocator[i];
for (int j = 0; j < pool.page_used; j++) {
int addr_pfn = phy_to_pfn(virtual_to_physical((uint64_t)addr));
int page_pfn = phy_to_pfn(virtual_to_physical(pool.page_addr[j]));
if (addr_pfn == page_pfn) {
uart_printf("free using obj allocator\n");
obj_free(i, addr);
return;
}
}
}
uart_printf("free using buddy\n");
buddy_free(addr);
}
|