|
|
@ -59,6 +59,8 @@ free_area_t free_area; |
|
|
|
#define free_list (free_area.free_list) |
|
|
|
#define nr_free (free_area.nr_free) |
|
|
|
|
|
|
|
list_entry_t *alloc_le = &free_list; |
|
|
|
|
|
|
|
static void |
|
|
|
default_init(void) { |
|
|
|
list_init(&free_list); |
|
|
@ -184,6 +186,7 @@ basic_check(void) { |
|
|
|
list_entry_t free_list_store = free_list; |
|
|
|
list_init(&free_list); |
|
|
|
assert(list_empty(&free_list)); |
|
|
|
alloc_le = &free_list; // 这里也得保存 |
|
|
|
|
|
|
|
unsigned int nr_free_store = nr_free; |
|
|
|
nr_free = 0; |
|
|
@ -211,6 +214,7 @@ basic_check(void) { |
|
|
|
assert(nr_free == 0); |
|
|
|
free_list = free_list_store; |
|
|
|
nr_free = nr_free_store; |
|
|
|
alloc_le = &free_list; // 这里也得恢复 |
|
|
|
|
|
|
|
free_page(p); |
|
|
|
free_page(p1); |
|
|
@ -239,6 +243,7 @@ default_check(void) { |
|
|
|
list_entry_t free_list_store = free_list; |
|
|
|
list_init(&free_list); |
|
|
|
assert(list_empty(&free_list)); |
|
|
|
alloc_le = &free_list; // 这里模拟的是未经过分配就直接把空闲页面链表情况的情况?也就是说这个时候nr_free是不正常的?那就不能循环nr_free次了。 |
|
|
|
assert(alloc_page() == NULL); |
|
|
|
|
|
|
|
unsigned int nr_free_store = nr_free; |
|
|
@ -271,6 +276,9 @@ default_check(void) { |
|
|
|
nr_free = nr_free_store; |
|
|
|
|
|
|
|
free_list = free_list_store; |
|
|
|
alloc_le = &free_list; |
|
|
|
// 这里恢复了之后要把default_alloc_pages里的le也恢复。 |
|
|
|
// 所以没事为什么要乱把页链表清空啊??? |
|
|
|
free_pages(p0, 5); |
|
|
|
|
|
|
|
le = &free_list; |
|
|
@ -282,11 +290,57 @@ default_check(void) { |
|
|
|
assert(total == 0); |
|
|
|
} |
|
|
|
|
|
|
|
static struct Page * |
|
|
|
next_fit_alloc_pages(size_t n) { |
|
|
|
assert(n > 0); |
|
|
|
if (n > nr_free) { |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
list_entry_t *len; |
|
|
|
if (alloc_le == &free_list) |
|
|
|
alloc_le = list_next(&free_list); |
|
|
|
list_entry_t *start = alloc_le; |
|
|
|
// 这里有两个方案,一个是固定循环nr_free次,一个是记录下循环前的le,循环直到再次碰到这个le,但是后面会看到前一个方案不行 |
|
|
|
list_entry_t *end = &free_list; |
|
|
|
|
|
|
|
while(1) { |
|
|
|
if (alloc_le == end) { // 最多两次触发此条件 |
|
|
|
if (end != start) { // 第二次触发le == end的时候这里就不满足了 |
|
|
|
end = start; // 如果循环到链表末尾了就把结束的指针改成循环开始的位置 |
|
|
|
alloc_le = list_next(alloc_le); // 并且这个&free_list不应该被分配 |
|
|
|
continue; |
|
|
|
} |
|
|
|
break; // 这时候就是真正的循环完了也没有剩余空间 |
|
|
|
} |
|
|
|
struct Page *p = le2page(alloc_le, page_link); |
|
|
|
if(p->property >= n){ |
|
|
|
int i; |
|
|
|
for(i=0;i<n;i++){ |
|
|
|
len = list_next(alloc_le); // 原来这个len是list_entry_next的意思不是length的意思 |
|
|
|
struct Page *pp = le2page(alloc_le, page_link); |
|
|
|
SetPageReserved(pp); |
|
|
|
ClearPageProperty(pp); |
|
|
|
list_del(alloc_le); |
|
|
|
alloc_le = len; |
|
|
|
} |
|
|
|
if(p->property>n){ |
|
|
|
(le2page(alloc_le,page_link))->property = p->property - n; |
|
|
|
} |
|
|
|
ClearPageProperty(p); |
|
|
|
SetPageReserved(p); |
|
|
|
nr_free -= n; |
|
|
|
return p; |
|
|
|
} |
|
|
|
alloc_le = list_next(alloc_le); |
|
|
|
} |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
const struct pmm_manager default_pmm_manager = { |
|
|
|
.name = "default_pmm_manager", |
|
|
|
.name = "next_fit_pmm_manager", |
|
|
|
.init = default_init, |
|
|
|
.init_memmap = default_init_memmap, |
|
|
|
.alloc_pages = default_alloc_pages, |
|
|
|
.alloc_pages = next_fit_alloc_pages, |
|
|
|
.free_pages = default_free_pages, |
|
|
|
.nr_free_pages = default_nr_free_pages, |
|
|
|
.check = default_check, |
|
|
|