Beispiel #1
0
static void
default_free_pages(struct Page *base, size_t n) {
	assert(n > 0);
	list_entry_t *le = &free_list;
    struct Page * p;
    while (p <= base && (le = list_next(le)) != &free_list)
	    p = le2page(le, page_link);

	for(p=base;p<base+n;p++)
	{
      list_add_before(le, &(p->page_link));
      p->flags = 0;
      set_page_ref(p, 0);
	}

    base->flags = 0;
    set_page_ref(base, 0);
    ClearPageProperty(base);
    SetPageProperty(base);
    base->property = n;

    while (1)
    {
        p = le2page(le, page_link);
        if (base->page_link.next != &free_list && base+base->property==p)
        {
            base->property += p->property;
            p->property = 0;
        }
        else break;
    }
    le = list_prev(&(base->page_link));
    p = le2page(le, page_link);
    if(le != &free_list && p == base-1)
    {
    	while (1)
    	{
	        if (p->property)
	        {
	        	p->property += base->property;
	        	base->property = 0;
	        	break;
	        }
	        if (le != &free_list)
	        {
	        	le = list_prev(le);
	        	p = le2page(le,page_link);
	        }
	        else break;
	    }
	}
    nr_free += n;
}
Beispiel #2
0
pmd_t *
get_pmd(pgd_t *pgdir, uintptr_t la, bool create) {
#if PMXSHIFT == PUXSHIFT
	return get_pud(pgdir, la, create);
#else /* PMXSHIFT == PUXSHIFT */
    pud_t *pudp;
    if ((pudp = get_pud(pgdir, la, create)) == NULL) {
        return NULL;
    }
    if (! ptep_present(pudp)) {
        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);
		ptep_map(pudp, pa);
		ptep_set_u_write(pudp);
		ptep_set_accessed(pudp);
		ptep_set_dirty(pudp);
    }
    return &((pmd_t *)KADDR(PUD_ADDR(*pudp)))[PMX(la)];
#endif /* PMXSHIFT == PUXSHIFT */
}
Beispiel #3
0
pte_t *
get_pte(pgd_t *pgdir, uintptr_t la, bool create) {
#if PTXSHIFT == PMXSHIFT
	return get_pmd(pgdir, la, create);
#else /* PTXSHIFT == PMXSHIFT */
    pmd_t *pmdp;
    if ((pmdp = get_pmd(pgdir, la, create)) == NULL) {
        return NULL;
    }
    if (! ptep_present(pmdp)) {
        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);
#ifdef ARCH_ARM
    pdep_map(pmdp, pa);
#else
		ptep_map(pmdp, pa);
#endif
#ifndef ARCH_ARM
		ptep_set_u_write(pmdp);
		ptep_set_accessed(pmdp);
		ptep_set_dirty(pmdp);
#else
#warning ARM9 PDE does not have access field
#endif
    }
    return &((pte_t *)KADDR(PMD_ADDR(*pmdp)))[PTX(la)];
#endif /* PTXSHIFT == PMXSHIFT */
}
Beispiel #4
0
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 = &free_list;
	while ((le = list_next(le)) != &free_list) {
		if (le2page(le, page_link) > base) {
			break;
		}
	}
	list_add_before(le, &(base->page_link));
}
Beispiel #5
0
static void
default_init_memmap(struct Page *base, size_t n) {
    // Given Code
    // assert(n > 0);
    // struct Page *p = base;
    // for (; p != base + n; p ++) {
    //     assert(PageReserved(p));
    //     p->flags = p->property = 0;
    //     set_page_ref(p, 0);
    // }
    // base->property = n;
    // SetPageProperty(base);
    // nr_free += n;
    // list_add(&free_list, &(base->page_link));
    assert(n > 0);
    struct Page *p = base;
    for (; p != base + n; p ++) {
        assert(PageReserved(p));
        p->flags = p->property = 0;
        ClearPageProperty(p);
        set_page_ref(p, 0);
    }
    base->property = n;
    SetPageProperty(base);
    nr_free += n;
    list_add(&free_list, &(base->page_link));
}
Beispiel #6
0
//buddy_init_memmap - build free_list for Page base follow  n continuing pages.
static void buddy_init_memmap(struct numa_mem_zone *zone)
{
	static int zone_num = 0;
	size_t n = zone->n;
	assert(n > 0 && zone_num < MAX_NUMA_MEM_ZONES);
	zone_num ++;
	struct Page *base = zone->page;
	struct Page *p = base;
	for (; p != base + n; p++) {
		assert(PageReserved(p));
		p->flags = p->property = 0;
		p->zone_num = zone->id;
		set_page_ref(p, 0);
	}
	//p = zones[zone_num++].mem_base = base;
	p = base;
	size_t order = MAX_ORDER, order_size = (1 << order);
	uint32_t numa_id = zone->node->id;
	assert(numa_id < sysconf.lnuma_count);
	while (n != 0) {
		while (n >= order_size) {
			p->property = order;
			SetPageProperty(p);
			list_add(&free_list(numa_id, order), &(p->page_link));
			n -= order_size, p += order_size;
			nr_free(numa_id, order)++;
		}
		order--;
		order_size >>= 1;
	}
}
//buddy_init_memmap - build free_list for Page base follow  n continuous pages.
static void
buddy_init_memmap(struct Page *base, size_t n) {
    static int zone_num = 0;
    assert(n > 0 && zone_num < MAX_ZONE_NUM);
    struct Page *p = base;
    for (; p != base + n; p ++) {
        assert(PageReserved(p));
        p->flags = p->property = 0;
        p->zone_num = zone_num;
        set_page_ref(p, 0);
    }
    p = zones[zone_num ++].mem_base = base;
    size_t order = MAX_ORDER, order_size = (1 << order);
    while (n != 0) {
        while (n >= order_size) {
            p->property = order;
            SetPageProperty(p);
            list_add(&free_list(order), &(p->page_link));
            n -= order_size, p += order_size;
            nr_free(order) ++;
        }
        order --;
        order_size >>= 1;
    }
}
Beispiel #8
0
//get_pte - get pte and return the kernel virtual address of this pte for la
//        - if the PT contians this pte didn't exist, alloc a page for PT
// parameter:
//  pgdir:  the kernel virtual base address of PDT
//  la:     the linear address need to map
//  create: a logical value to decide if alloc a page for PT
// return vaule: the kernel virtual address of this pte
pte_t *
get_pte(pde_t *pgdir, uintptr_t la, bool create) {
    /* LAB2 EXERCISE 2: YOUR CODE
     *
     * If you need to visit a physical address, please use KADDR()
     * please read pmm.h for useful macros
     *
     * Maybe you want help comment, BELOW comments can help you finish the code
     *
     * Some Useful MACROs and DEFINEs, you can use them in below implementation.
     * MACROs or Functions:
     *   PDX(la) = the index of page directory entry of VIRTUAL ADDRESS la.
     *   KADDR(pa) : takes a physical address and returns the corresponding kernel virtual address.
     *   set_page_ref(page,1) : means the page be referenced by one time
     *   page2pa(page): get the physical address of memory which this (struct Page *) page  manages
     *   struct Page * alloc_page() : allocation a page
     *   memset(void *s, char c, size_t n) : sets the first n bytes of the memory area pointed by s
     *                                       to the specified value c.
     * DEFINEs:
     *   PTE_V           0x001                   // page table/directory entry flags bit : Present
     *   PTE_W           0x002                   // page table/directory entry flags bit : Writeable
     *   PTE_U           0x004                   // page table/directory entry flags bit : User can access
     */
#if 0
    pde_t *pdep = NULL;   // (1) find page directory entry
    if (0) {              // (2) check if entry is not present
                          // (3) check if creating is needed, then alloc page for page table
                          // CAUTION: this page is used for page table, not for common data page
                          // (4) set page reference
        uintptr_t pa = 0; // (5) get linear address of page
                          // (6) clear page content using memset
                          // (7) set page directory entry's permission
    }
    return NULL;          // (8) return page table entry
#endif
    pde_t *pdep = &pgdir[PDX(la)];			//right!!!
//    if(la==0x50000000)
//    	cprintf("pdep=%08x\n",pdep);
    if (!(*pdep & PTE_V)) {
        struct Page *page;
//        cprintf("haha\n");
       // cprintf("create=%d\n",create);
        if (!create || (page = alloc_page()) == NULL) {
            return NULL;
        }
        //cprintf("hahapaget_pte\n");
        set_page_ref(page, 1);
        uintptr_t pa = page2pa(page);
        memset(KADDR(pa), 0, PGSIZE);
        *pdep = pa | PTE_TYPE_TABLE | PTE_V | PTE_R;
    }
    //cprintf("%08x\n",&((pte_t *)KADDR(PDE_ADDR(*pdep)))[PTX(la)]);
//    if(la==0x50000000)
//    	cprintf("get_pte return=%08x\n",&((pte_t *)KADDR(PDE_ADDR(*pdep)))[PTX(la)]);
    return &((pte_t *)KADDR(PDE_ADDR(*pdep)))[PTX(la)];
}
Beispiel #9
0
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);

    // Given Code
    // 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;
    // list_add(&free_list, &(base->page_link));

    while (le != &free_list) {
        p = le2page(le, page_link);
        if (base + base->property < p)  //已经遍历到第一个地址大于base且无法合并的块,跳出循环
            break;
        le = list_next(le);
        if (p + p->property == base) {  //检查是否是base之前的能合并的块
            p->property += base->property;
            base->flags = base->property = 0;
            ClearPageProperty(base);
            base = p;
            list_del(&(p->page_link));
        }
        else if (base + base->property == p) {  //检查是否是base之后能合并的块
            base->property += p->property;
            p->flags = p->property = 0;
            ClearPageProperty(p);
            list_del(&(p->page_link));
        }
    }
    nr_free += n;   //空闲空间增加
    SetPageProperty(base);  //property = 1
    list_add_before(le, &(base->page_link));    //插入在第一个第一个地址大于base且无法合并的块之前
}
Beispiel #10
0
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 = &free_list;
    while (1) {
        //TODO: set reserve bits and could be faster
        le = list_next(le);
        p = le2page(le, page_link);
        if (le == &free_list || p > base) {
            list_add_before(&(p->page_link), &(base->page_link));
            break;
        }
    }
    int flag = 1;
    //cprintf("Now check merge\n");
    while (flag == 1)
    {
        flag = 0;
        p = le2page((base->page_link.next), page_link);
        //cprintf("base = %08x p = %08x size = %d\n", base, p, base->property);
        //cprintf(" plus = %08x\n", base + base->property);
        if (base->page_link.next != &free_list && base+base->property==p) {
            base->property += p->property;
            //cprintf("merge on the back: %d\n", p->property);
            ClearPageProperty(p);
            list_del(&(p->page_link));
            //cprintf("flag = %d %d\n", base->flags, p->flags);
            flag = 1;
        }
        p = le2page((base->page_link.prev), page_link);
        //cprintf("base = %08x p = %08x size = %d\n", base, p, base->property);
        if (base->page_link.prev != &free_list && p+p->property==base) {
            p->property += base->property;
            //cprintf("merge on the front: %d\n", p->property);
            ClearPageProperty(base);
            list_del(&(base->page_link));
            //cprintf("flag = %d %d\n", base->flags, p->flags);
            base = p;
            flag = 1;
        }
    }
    nr_free += n;
    //list_add(&free_list, &(base->page_link));
}
Beispiel #11
0
static void default_init_memmap(struct Page *base, size_t n) {
	assert(n > 0);
	struct Page *p = base;
	for (; p != base + n; p++) {
		assert(PageReserved(p));
		p->flags = p->property = 0;
		set_page_ref(p, 0);
	}
	base->property = n;
	SetPageProperty(base);
	nr_free += n;
	list_add(&free_list, &(base->page_link));
}
Beispiel #12
0
//static void
default_free_pages(struct Page *base, size_t n) {
    assert(n > 0);
    assert(PageReserved(base));

    //遍历空闲块链表,找到合适的位置插入回收的地址块
    list_entry_t *le = &free_list;
    struct Page *page = NULL;
    //寻找第一个空闲块
    while ((le = list_next(le)) != &free_list) {
    	page = le2page(le, page_link);
        if (page > base) {
            break;
        }
    }
    //插入回收的空闲块:按页插入
    for (page=base; page<(base+n); page++) {
    	list_add_before(le, &(page->page_link));
    }

    //重置该块的字段
    base->flags = 0;
    base->property = n;
    set_page_ref(base, 0);
    ClearPageProperty(base);
    SetPageProperty(base);

    //尝试合并地址相连的空闲地址块
    //先查看后一个空闲块
    page = le2page(le, page_link); //得到后一个空闲块起始地址
    if ((base+n) == page) {
    	base->property += page->property;
    	page->property = 0;
    }
    //后查看前一个空闲块
    le = list_prev(&(base->page_link));
    page = le2page(le, page_link); //此时并不是前一个空闲块,而是前一个page
    if ((le!= &free_list) && page == (base-1)) {
    	while (le!= &free_list) {
    		if (page->property > 0) {
    			page->property += base->property;
    			base->property =0;
    			break;
    		}
    		le = list_prev(le);
    		page = le2page(le, page_link);
    	}
    }
    nr_free += n;
    return;
}
Beispiel #13
0
static void
default_init_memmap(struct Page *base, size_t n) {
    assert(n > 0);
    struct Page *p = base;
    for (; p != base + n; p ++) {
        assert(PageReserved(p));
        p->flags = 0;        // init p->flags as 0
        SetPageProperty(p);  // p->flags should be set bit PG_property
        p->property = 0;     // p->property should be set to 0
        set_page_ref(p, 0);  // p->ref should be 0, because now p is free and no reference
        list_add_before(&free_list, &(p->page_link)); // link this page to free_list
    }
    base->property = n; // for the first page of free block, its property should be set to total num of block
    nr_free += n;       // sum the number of free mem block
}
Beispiel #14
0
static void
default_init_memmap(struct Page *base, size_t n) {
    assert(n > 0);
    struct Page *p = base +1;
    for (; p < base + n; ++ p) {
        assert(PageReserved(p));
        ClearPageReserved(p);
        ClearPageProperty(p);        
	p->property = 0;
        set_page_ref(p, 0);
	list_init(&(p->page_link));
    }
    assert(PageReserved(base));
    ClearPageReserved(base);
    SetPageProperty(base);

    base->property = n;

    set_page_ref(base, 0);

    list_add_before(&free_list, &(base -> page_link)); 
    nr_free += n;

}
Beispiel #15
0
static void
default_init_memmap(struct Page *base, size_t n) {
	assert(n > 0);
	struct Page *p = base;
	for (; p != base + n; p ++) {
		assert(PageReserved(p));
		p->flags = 0;        // Clears the flags.
		p->property = 0;     // Not the first page of free block.
		set_page_ref(p, 0);  // Free and no reference.
	}
	SetPageProperty(base);  // Valid page.
	list_add(&free_list, &(base->page_link));  // Links this page to free_list
	base->property = n;     // First page of n free blocks.
	nr_free += n;
}
Beispiel #16
0
static void
default_free_pages(struct Page *base, size_t n) {
    assert(n > 0);
    assert(PageReserved(base));

    list_entry_t *le = &free_list;
    struct Page * p;
    while((le=list_next(le)) != &free_list) {
      p = le2page(le, page_link);
      if(p>base){
        break;
      }
    }
    // 每个page都加入freelist
    for(p=base;p<base+n;p++){
      list_add_before(le, &(p->page_link));
    }
    // 首个page进行设置
    base->flags = 0;
    set_page_ref(base, 0);
    ClearPageProperty(base);
    SetPageProperty(base);
    base->property = n;
    
    p = le2page(le,page_link);
    // 如果后面需要合并
    if( base+n == p ){
      base->property += p->property;
      p->property = 0;
    }
    le = list_prev(&(base->page_link));
    p = le2page(le, page_link);
    // 如果前面需要合并
    if(le!=&free_list && p==base-1){
      while(le!=&free_list){
        if(p->property){
          p->property += base->property;
          base->property = 0;
          break;
        }
        le = list_prev(le);
        p = le2page(le,page_link);
      }
    }

    nr_free += n;
    return ;
}
Beispiel #17
0
static void
default_free_pages(struct Page *base, size_t n) {
	// 用于释放页
	// 我们来仔细看一下释放page的函数吧!
	assert(n > 0);
	assert(PageReserved(base));

	list_entry_t *le = &free_list; // le指向空闲段链表的头部
	struct Page *p;
	while ((le = list_next(le)) != &free_list) { // 开始遍历
		p = le2page(le, page_link);
		if (p > base) { // free_list里面的数据都是按照地址从小到大排列的吧!
			break;
		}
	}
	// le现在指向一个恰好在base页面之后的page
	for (p = base; p < base + n; p++) { // 不断地在前面插入
		list_add_before(le, &(p->page_link));
	}
	base->flags = 0;
	set_page_ref(base, 0); // 引用计数变为了0
	ClearPageProperty(base); // 
	SetPageProperty(base); // 只需要这句就行了吧!
	base->property = n;

	p = le2page(le, page_link);
	if (base + n == p) { // 也就是说,前后可以连接起来
		base->property += p->property;
		p->property = 0;
	}

	le = list_prev(&(base->page_link));
	p = le2page(le, page_link); // 找到free_list中base之前的那个free page
	if (le != &free_list && p == base - 1) { // 如果两个也可以连起来
		while (le != &free_list) {
			if (p->property) {
				p->property += base->property;
				base->property = 0;
				break;
			}
			le = list_prev(le);
			p = le2page(le, page_link);
		}
	}

	nr_free += n; // 空闲页的计数加n
	return;
}
Beispiel #18
0
static void
default_init_memmap(struct Page *base, size_t n) {
    assert(n > 0);
    struct Page *p = base;
    for (; p != base + n; p ++) {
        assert(PageReserved(p));
        p->flags = 0;
        SetPageProperty(p);
        p->property = 0;
        set_page_ref(p, 0);
        list_add_before(&free_list, &(p->page_link));
    }
    nr_free += n;
    //first block
    base->property = n;
}
Beispiel #19
0
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));
        }else{
			if(base + base->property < p && p->page_link.prev == &free_list){
				list_add(&free_list , &base->page_link);
				nr_free += n;
				return ;
			}else if(le == &free_list && p+p->property < base){
				list_add_before(&free_list , &base->page_link);
				nr_free += n;
				return ;
			}else {
				struct Page *page_next = le2page(le , page_link);
				if(p+p->property < base && base+base->property<page_next){
					list_add(p , &base->page_link);
					nr_free += n;
					return ;			
				}
			}
		}
    }
    nr_free += n;
    list_add(&free_list, &(base->page_link));
}
Beispiel #20
0
static void
default_free_pages(struct Page *base, size_t n) {
    assert(n > 0);
    assert(PageReserved(base));
    list_entry_t *le = &free_list; //获取空闲内存页的起始地址
    struct Page *p;
    while((le = list_next(le))!= &free_list){
        p = le2page(le, page_link);
        if( p > base){
            //说明base应该接到p的前面,也就是le的前面
            break;
        }
    }
    for( p = base; p<base+n; p++){
        list_add_before(le, &(p->page_link));
    }
    base->flags = 0;
    set_page_ref(base, 0);
    ClearPageProperty(base);
    SetPageProperty(base);
    base->property = n;
    //下面是块的合并
    //向后
    p = le2page(le, page_link);
    if(base+n == p){
        base->property += p->property;
        p->property = 0;
    }
    //向前
    le = list_prev(&(base->page_link));
    p = le2page(le, page_link);
    if(le!=&free_list && p == base-1){
        while(le!=&free_list){
            if(p->property){
                p->property += base->property;
                base->property = 0;
                break;
            }
			le = list_prev(le);
			p = le2page(le, page_link);
        }
        
    }
    
    nr_free += n;
    return ;
}
Beispiel #21
0
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(1) {
    	p = le2page(le, page_link);
		if (le == &free_list || p >= base) {
			list_add_before(le, &(base->page_link));
			break;
		}
    	le = list_next(le);
    }

    // Search Next
    le = list_next(&(base->page_link));
    if(le != &free_list) {
    	p = le2page(le, page_link);
    	if(base + n == p) {
			// Link them
			base->property += p->property;
			ClearPageProperty(p);
			list_del(&(p->page_link));
    	}
    }

    // Search Prev
    le = list_prev(&(base->page_link));
    if(le != &free_list) {
    	p = le2page(le, page_link);
    	if(p + p->property == base) {
    		// Link them
    		p->property += base->property;
    		ClearPageProperty(base);
    		list_del(&(base->page_link));
    	}
    }
    nr_free += n;
}
Beispiel #22
0
static void
default_free_pages(struct Page *base, size_t n) {
    assert(n > 0);

    // (5.1)
    list_entry_t *le = &free_list;
    while ((le = list_next(le)) != &free_list) {
        if (le2page(le, page_link) > base) { // the first position higher than base
            break;
        }
    }

    struct Page *p;
    for (p = base; p < base + n; p++) { // insert these pages
        p->property = 0;
        list_add_before(le, &(p->page_link));
    }

    // (5.2) mark base as free page
    base->flags = 0;
    SetPageProperty(base);
    base->property = n;
    set_page_ref(base, 0);

    // (5.3)
    p = le2page(le, page_link);
    if (p == base + n) { // merge forward
        base->property += p->property; // merge p into base
        p->property = 0;
    }

    le = list_prev(&(base->page_link));
    p = le2page(le, page_link); // prev of base
    if (p == base - 1) { // merge backward
        for (; le != &free_list; le = list_prev(le)) {
            p = le2page(le, page_link);
            if (p->property > 0) { // find property, merge base into p
                p->property += base->property;
                base->property = 0;
                break;
            }
        }
    }

    nr_free += n;
}
Beispiel #23
0
static void
default_free_pages(struct Page *base, size_t n) {
    assert(n > 0);
    assert(PageReserved(base));
    struct Page *p = base;
    struct Page * q = NULL;
    list_entry_t * le = &free_list;
    while((le = list_next(le)) != &free_list)
    {
	q = le2page(le,page_link);
	if(q > base)
         break;
    }
    //struct Page * q = 
    for(;p < base + n;p++){
	list_add_before(le,&(p -> page_link));
    }
    base -> flags = 0;
    set_page_ref(base,0);
    ClearPageProperty(base);
    SetPageProperty(base);
    base->property = n;

    if(q == base + n){
	
	base -> property += q -> property;
	q -> property = 0;
    }
    le = list_prev(&(base -> page_link));
    q = le2page(le,page_link);
    if(le != &free_list && q == base -1)
    {
	while(le != &free_list){
	if(q -> property)
        {
		q -> property += base -> property;
		base -> property = 0;
		break;
        }
	le = list_prev(le);
	q = le2page(le,page_link);
	}
    }
   nr_free += n;
   return;
}
static void
default_free_pages(struct Page *base, size_t n) {
    assert(n > 0);

    list_entry_t *le = &free_list;
    list_entry_t *bef;

    struct Page* p;
    while ((le = list_next(le)) != &free_list){
    	p = le2page(le, page_link);
    	if (p > base) break;
    }

    for (p = base; p< base+n; p++){
    	list_add_before(le, &(p->page_link));
    }

    base ->flags = 0;
    set_page_ref(base, 0);
    ClearPageReserved(base);		//
    SetPageProperty(base);
    base->property = n;

    p = le2page(le, page_link);
    if (base + n == p){
    	base->property += p->property;
    	p->property = 0;
    }

    bef = list_prev(&(base->page_link));
    p = le2page(bef, page_link);
    if (bef != &free_list && p == base-1){
    		while (bef != &free_list){
    			if (p -> property != 0){
    				p->property += base->property;
    				base->property = 0;
    				break;
    			}
    			bef = list_prev(bef);
    			p = le2page(bef, page_link);
    		}
    }
    nr_free += n;
    return;
}
Beispiel #25
0
static void
default_init_memmap(struct Page *base, size_t n) {
    assert(n > 0);
    //首先需要初始化该空闲块中的每个页
    struct Page *p = base;
    for (; p != base + n; p++) {
        assert(PageReserved(p));
        p->flags = 0;
        SetPageProperty(p); //设置p->flags
        p->property = 0;    //设置p->property
        set_page_ref(p, 0); //设置 p->ref
        list_add_before(&free_list, &(p->page_link));
    }
    //base是该空闲块中的第一个page,并且是free的,故property赋值为n
    base->property = n;
    //最后更新nf_free的值
    nr_free += n;
}
Beispiel #26
0
static void
default_free_pages(struct Page *base, size_t n) {
    assert(n > 0);
    // Frees the pages;
	base->flags = 0;        // Clears the flags.
	base->property = 0;     // Not the first page of free block.
	set_page_ref(base, 0);  // Free and no reference.
	SetPageProperty(base);
    base->property = n;      // First page of n free blocks.

    // Finds the insertion position.
    list_entry_t *le = &free_list;
    struct Page *prev_page = NULL;
    struct Page *next_page = NULL;
    while ((le = list_next(le)) != &free_list) {
        next_page = le2page(le, page_link);
        if (next_page > base) {
            break;
        }
        prev_page = next_page;
    }

    // Adds freed space to list.
    list_add_before(le, &(base->page_link));

    // If next_p is adjacent, combine them.
    if (next_page && base + base->property == next_page) {
        base->property += next_page->property;
        ClearPageProperty(next_page);
        next_page->property = 0;
        list_del(&(next_page->page_link));
    }

    // If prev_page is adjacent, combine them.
    if (prev_page && prev_page + prev_page->property == base) {
        prev_page->property += base->property;
        ClearPageProperty(base);
        base->property = 0;
        list_del(&(base->page_link));
    }

    nr_free += n;
}
Beispiel #27
0
static void
default_init_memmap(struct Page *base, size_t n) {
    assert(n > 0);
    struct Page *p = base;
    for (; p != base + n; p ++) {
        assert(PageReserved(p));
        p->flags = p->property = 0;
        set_page_ref(p, 0);
    }
    base->property = n;
    SetPageProperty(base);
    nr_free += n;
    list_add(&free_list, &(base->page_link));
    list_entry_t *le = &free_list;
        while ((le = list_next(le)) != &free_list) {
           struct Page *p = le2page(le, page_link);
           cprintf("iiiiiiii %d \n",p->flags);
        }
}
Beispiel #28
0
static void
default_init_memmap(struct Page *base, size_t n) {
    assert(n > 0);
	// n是页数
    struct Page *p = base;
    for (; p != base + n; p ++) {
        assert(PageReserved(p));
        p->flags = p->property = 0;
		SetPageProperty(p);
        set_page_ref(p, 0); // 引用计数设置为0
		// 也就是在free_list的前面插入,不过考虑到这是一个双向链表,所以实际的意思是,插到链表的尾部
		list_add_before(&free_list, &(p->page_link));
    }
	// 因为base是头表
	// property这个玩意只有在free block首地址对应的Page有用,其余都被设置为了0
	// 用于指示这个free block一共有多少个free page
    base->property = n; // 可用的页面数是n
    SetPageProperty(base); // base所在的页面为头表
    nr_free += n; // 空闲的页面数目增加了n
    //list_add(&free_list, &(base->page_link)); // 添加到free_list的头部
}
Beispiel #29
0
pmd_t *
get_pmd(pgd_t *pgdir, uintptr_t la, bool create) {
#if PMXSHIFT == PUXSHIFT
	return get_pud(pgdir, la, create);
#else /* PMXSHIFT == PUXSHIFT */
    pud_t *pudp;
    if ((pudp = get_pud(pgdir, la, create)) == NULL) {
        return NULL;
    }
    if (!(*pudp & PTE_P)) {
        struct Page *page;
        if (!create || (page = alloc_page()) == NULL) {
            return NULL;
        }
        set_page_ref(page, 1);
        uintptr_t pa = page2pa(page);
        memset(VADDR_DIRECT(pa), 0, PGSIZE);
        *pudp = pa | PTE_U | PTE_W | PTE_P;
    }
    return &((pmd_t *)VADDR_DIRECT(PUD_ADDR(*pudp)))[PMX(la)];
#endif /* PMXSHIFT == PUXSHIFT */
}
Beispiel #30
0
static void default_free_pages(struct Page* base, size_t n) {
    assert(0 < n);
    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);
    // Find insertion position
    while (le2page(le, page_link) < base && le != &free_list) {
        le = list_next(le);
    }
    le = list_prev(le);
    // Insert into list
    list_add(le, &(base->page_link));
    // Merge previous one
    p = le2page(le, page_link);
    if (p + p->property == base) {
        p->property += base->property;
        ClearPageProperty(base);
        base->property = 0;
        list_del(&(base->page_link));
        base = p;
    }
    // Merge next one
    if (list_next(&(base->page_link)) != &free_list) {
        p = le2page(list_next(&(base->page_link)), page_link);
        if (base + base->property == p) {
            base->property += p->property;
            ClearPageProperty(p);
            p->property = 0;
            list_del(&(p->page_link));
        }
    }
    nr_free += n;
}