欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ucore lab2

程序员文章站 2022-07-12 16:55:05
...

challange我还是懒得写,不过这个lab2的challange类似于csapp的malloc lab,可以说是很类似,不止challange,我起初没注意他的数据结构形式,写错了,当成fastbin那种写的
整套实验基本就是用提供的函数实现功能,比起之前做的csapp和cs144的lab难度友好太多了

练习一

static void
default_init(void) {
    list_init(&free_list);
    nr_free = 0;
}

static void
default_init_memmap(struct Page *base, size_t n) {
    assert(n > 0);
    struct Page *p = base;
    SetPageProperty(p);
    for (; p != base + n; p ++) {
        assert(PageReserved(p));
        p->flags = p->property = 0;
        SetPageProperty(p);
        set_page_ref(p, 0);
        list_add_before(&free_list, &(p->page_link));
    }
    base->property = n;
    nr_free += n;
}

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;
    list_entry_t *nextle;
    while ((le = list_next(le)) != &free_list) {
        struct Page *p = le2page(le, page_link);
        if (p->property >= n) {
            page = p;
            break;
        }
    }
    if (page != NULL) {
        int temp;
        struct Page *tempPage;
        for(temp=0;temp<n;temp++){
            nextle=list_next(le);
            tempPage=le2page(le, page_link);
            SetPageReserved(tempPage);
            ClearPageProperty(tempPage);
            list_del(le);
            le = nextle;
        }
        if (page->property > n) {
            le2page(le,page_link)->property = page->property - n;
        }
        ClearPageProperty(page);
        SetPageReserved(page);
        nr_free -= n;
    }
    return page;
}

static void
default_free_pages(struct Page *base, size_t n) {
    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);
        if(base+base->property<=p){
            assert(base+base->property!=p);
            break;
        }
        le=list_next(le);
    }
    list_add(&free_list, &(base->page_link));
}

说一下free,记得merge,当我free掉的一个能和他周围的合并的话,那就合并,并且alloc时也能取一部分然后分割合并,做过堆题的pwn对这应该很熟悉了,然后就。。没什么好说的,剩下俩练习注释就跟我自己注解的一样详细,一行一注释,没啥好解释的了,直接代码吧
另外上面free里面对于插入链表的le的位置搜索我起初没有,当时我没有发现问题,这里是看了答案才添上去的

练习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)]; 

练习三

    if (ptep&PTE_P) {                      	//(1) check if this page table entry is present
        struct Page *page = pte2page(*ptep); 	//(2) find corresponding page to pte
        page_ref_dec(page)  			//(3) decrease page reference
        if(page->ref==0) free_page(page);       //(4) and free this page when page reference reachs 0
        *ptep = 0;                              //(5) clear second page table entry
        tlb_invalidate(pgdir,la);               //(6) flush tlb

challange不想写,csapp的lab有类似的实现,继续看书去了