From dce49e442087a0d373f3668bce54ade2b4714c18 Mon Sep 17 00:00:00 2001 From: 423A35C7 <609514299@qq.com> Date: Tue, 16 Apr 2024 13:48:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=AE=9E=E9=AA=8C2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复了测试代码中的bug。 --- .../lab2_result/kern/mm/default_pmm.c | 58 ++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/labcodes_answer/lab2_result/kern/mm/default_pmm.c b/labcodes_answer/lab2_result/kern/mm/default_pmm.c index 2940b12..825740b 100644 --- a/labcodes_answer/lab2_result/kern/mm/default_pmm.c +++ b/labcodes_answer/lab2_result/kern/mm/default_pmm.c @@ -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;iproperty>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,