清华大学操作系统-物理内存管理实验报告

时间:2024.4.20

练习0把实验1的代码填入本实验中代码有lab1的注释相应的部分。

         用understand中的merge工具将实验1中填写代码部分复制到实验2中,如图1。

图1

练习1实现firstfit连续物理内存分配算法。

       对于lab2代码首先对其make,之后在虚拟机中运行查看其错误所在位置如图2。

       可以发现其错误出现在default_check(void)这个函数之中,该函数为检查firstfit算法的函数。继续分析错误出现的原因:

      

       struct Page *p0 = alloc_pages(5), *p1, *p2;

    assert(p0 != NULL);

    assert(!PageProperty(p0));

    list_entry_t free_list_store = free_list;

    list_init(&free_list);

    assert(list_empty(&free_list));

    assert(alloc_page() == NULL);

    unsigned int nr_free_store = nr_free;

    nr_free = 0;

    free_pages(p0 + 2, 3);

    assert(alloc_pages(4) == NULL);

    assert(PageProperty(p0 + 2) && p0[2].property == 3);

    assert((p1 = alloc_pages(3)) != NULL);

    assert(alloc_page() == NULL);

    assert(p0 + 2 == p1);

    p2 = p0 + 1;

    free_page(p0);

    free_pages(p1, 3);

    assert(PageProperty(p0) && p0->property == 1);

    assert(PageProperty(p1) && p1->property == 3);

assert((p0 = alloc_page()) == p2 - 1); //错误出现的位置

分析源码后可知,在其对内存进行一些列分配释放操作后,再次申请一页内存后出现错误,可知其在最后一次p0 = alloc_page()申请中得到内存页的位置与算法规则不相符,回到default_alloc_pages(size_t n)、default_free_pages(struct Page *base, size_t n)函数中可以分析得到,在分配函数和释放函数中都出现错误:

list_add(&free_list, &(p->page_link));

分配函数中若分得的块大小大于申请页数,则需要将多余的页形成一个块,按照从低地址到高地址的顺序挂回free_list中,而不是直接挂到free_list的后面。

list_add(&free_list, &(base->page_link));

将释放页与空闲页合并操作之后,只是将新的空闲区域挂到了free_list的后面,并没有按照从低地址到高地址的顺序将其挂到free_list之中,导致后面check函数中出现错误。对源代码做如下修改(红色为修改部分):

static struct Page *

default_alloc_pages(size_t n) {

    assert(n > 0);   //出错判断

    if (n > nr_free) { //申请页大小与现有空闲页比较

        return NULL;

    }

    struct Page *page = NULL;

    list_entry_t *le = &free_list;

    while ((le = list_next(le)) != &free_list) {

//从free_list的头开始寻找符合条件的空闲块

        struct Page *p = le2page(le, page_link);

        if (p->property >= n) {

            page = p;

            break;

        }

    }

    if (page != NULL) {

        list_del(&(page->page_link));

        if (page->property > n) { //若分配成功的块总页数比申请页数大

            struct Page *p = page + n;

            p->property = page->property - n;

            list_add(list_prev(le), &(p->page_link));

    }

        nr_free -= n;

        ClearPageProperty(page);

    }

    return page;

}

释放内存与申请内存思路大致相同:

default_free_pages(struct Page *base, size_t n) {

    int flag = 0;  //设置标志位

    assert(n > 0);

    struct Page *p = base;

    for (; p != base + n; p ++) {

        assert(!PageReserved(p) && !PageProperty(p));

        p->flags = 0;

        set_page_ref(p, 0);

    }

    base->property = n;

    SetPageProperty(base);

    list_entry_t *le = list_next(&free_list);

    while (le != &free_list) {

        p = le2page(le, page_link);

        le = list_next(le);

        if (base + base->property == p) {

            base->property += p->property;

            ClearPageProperty(p);

            list_del(&(p->page_link));

        }

        else if (p + p->property == base) {

            p->property += base->property;

            ClearPageProperty(base);

            base = p;

            list_del(&(p->page_link));

        }

    }

    nr_free += n;

    le = list_next(&free_list);

    while (le != &free_list) {

        p = le2page(le, page_link);

        le = list_next(le);

      struct Page *q = le2page(le, page_link);

      if(p>base){      //判断插入位置在头部

             list_add(&free_list, &(base->page_link));

             flag = 1;

             break;

      }

      if(p<base & base<q){ //判断插入位置在中间

             list_add_before(le, &(base->page_link));

             flag = 1;

             break;

      }

     }

       //判断插入位置在尾部

    if(flag == 0)list_add_before(&free_list, &(base->page_link));

}

修改思路:将合并后的空闲页按照从低到高的地址顺序插入到free_list之中,注意边界条件。

修改后再次运行代码如图3:

3

可以看到check_alloc_page() succeeded,修改成功,分配函数成功运行。

Lab2中的分配代码、释放代码都是以空闲块为一个整体单位,此外在labcode_result中分配与释放都是以页为单位,将所有的空闲页按照从低地址到高地址全部挂到free_list上。

分析上述两种方式,我认为第一种方式更加合理。将所有的空闲页全部挂到free_list链表上开销过大,同时在进行分配时需要将符合条件区域内的所有页进行操作,但是在以块为单位的算法中,只需要将每一块的第一页作为该块的代表挂到free_list上即可,方便操作同时减少开销。

练习2:实现寻找虚拟地址对应的页表项

      pde_t *pdep = &pgdir[PDX(la)];

    if (!(*pdep & PTE_P)) {   //如果不存在

        struct Page *page;

        if (!create || (page = alloc_page()) == NULL) {  //判断是否建立

            return NULL;

        }

              //设置参数,初始化

        set_page_ref(page, 1);

        uintptr_t pa = page2pa(page);

        memset(KADDR(pa), 0, PGSIZE);

        *pdep = pa | PTE_U | PTE_W | PTE_P;

    }

    return &((pte_t *)KADDR(PDE_ADDR(*pdep)))[PTX(la)]; //返回入口

练习3:释放某虚拟地址所在的页并取消对应的二级页表项的映射

if (*ptep & PTE_P) {  //判断是否存在

        struct Page *page = pte2page(*ptep);

        if (page_ref_dec(page) == 0) { //判断是否需要释放

            free_page(page);

        }

        *ptep = 0;  //初始化二级页表项

        tlb_invalidate(pgdir, la); //更新tlb

             }

   


第二篇:计算机操作系统实验报告(共享内存管理)


数学与计算机科学系实验报告

课程:计算机操作系统     地点:软件实验室二时间: 2013 5 17  

更多相关推荐:
操作系统 内存管理实验报告

同组同学学号同组同学姓名注实验内容及步骤项目的内容如果较多可以加附页

《操作系统》存储管理实验报告

《操作系统》存储管理实验报告____大学____学院实验报告

操作系统内存管理实验报告

实验报告12345678910111213

操作系统“内存管理”实验报告

洛阳理工学院实验报告1828384858687888

操作系统存储管理实验报告

北京邮电大学操作系统实验实验报告实验日期20xx1220实验名称存储管理一实验目的2二实验内容2三实验分析2对于伙伴算法2对于虚拟存储区和内存工作区的不同算法3四编程实现3伙伴算法3原理3伙伴的概念3内存的释放...

西安邮电大学操作系统内存管理实验报告含源码

西安邮电大学计算机学院课内实验报告实验名称内存管理专业名称班级1201班学生姓名学号8指导教师实验日期20xx年11月25日一实验目的及实验环境一实验环境1硬件1主机PentiumIII以上2内存128MB以上...

北理工操作系统内存管理实验报告

班级学号实验三内存管理姓名一实验目的1通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解2熟悉虚存管理的页面淘汰算法3通过编写和调试地址转换过程的模拟程序以加强对地址转换过程的了解二实验要求1设计一个请...

济南大学操作系统实验报告3内存管理

操作系统实验三内存管理学院信息科学与工程学院班级学号姓名实验目的设计一个请求页式存储管理方案为简单起见页面淘汰算法采用FIFO页面淘汰算法并且在淘汰一页时只将该页在页表中修改状态位而不再判断它是否被改写过也不将...

西安邮电大学操作系统内存管理实验报告

西安邮电大学计算机学院课内实验报告实验名称内存管理专业名称班级1101班学生姓名武妍娜学号8指导教师舒新峰实验日期20xx年12月15日一实验目的及实验环境一实验环境Ubuntu1310shellVimGCC编...

操作系统内存管理

西安邮电大学计算机学院课内实验报告实验名称内存管理专业名称班级学生姓名学号8指导教师西安邮电大学计算机学院课内实验报告实验名称内存管理专业名称班级软件工程软件1203段文雅舒新峰20xx年12月5日学生姓名学号...

操作系统实验报告十一

系统内存统计使用实验报告实验序号十实验项目名称系统内存统计使用

计算机操作系统实验报告(共享内存管理)

数学与计算机科学系实验报告课程计算机操作系统地点软件实验室二时间20xx年5月17日includeltsysipchgtincludeltsyssemhgtincludeltsysshmhgtincludelt...

操作系统内存管理实验报告(40篇)