Esempio n. 1
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));
}
Esempio n. 2
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;
}
Esempio n. 3
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);
    int is_empty_or_last = 1;
    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));
            if (le != &free_list) {
                p = le2page(le, page_link);
                is_empty_or_last = 0;
            }
            break;
        }
        else if (p + p->property == base) {
            p->property += base->property;
            ClearPageProperty(base);
            base = p;
            list_del(&(p->page_link));
        }
        if (p > base){
            is_empty_or_last = 0;
            break;
        }
    }
    nr_free += n;
    if (is_empty_or_last) {
        list_add_before(&free_list, &(base->page_link));
    } else {
        list_add_before(&(p->page_link), &(base->page_link));
    }
}
Esempio n. 4
0
static void
default_free_pages(struct Page *base, size_t n) {
    assert(n > 0);

    struct Page *p, *p_end = base + n;
    for (p = base; p < p_end; p++) {
        assert(!PageReserved(p) && !PageProperty(p));
        p->flags = p->property = p->ref = 0;
    }

    base->property = n;

    list_entry_t *e;
    list_entry_t *target = &free_list;
    for(e = list_next(&free_list);
        e != &free_list;
        ) {

        p = le2page(e, page_link);
        if(p + p->property == base) {
            p->property += base->property;
            base->property = base->flags = 0;
            base = p;
            e = list_next(e);
            list_del(&p->page_link);
        }else if(base + base->property == p) {
            base->property += p->property;
            p->property = p->flags = 0;
            e = list_next(e);
            list_del(&p->page_link);
        }else if(base < p) {
            target = e;
            break;
        }else{
            e = list_next(e);
        }
    }

    SetPageProperty(base);
    list_add_before(target, &base->page_link);
    nr_free += n;
}
Esempio n. 5
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;
    //list_add(&free_list, &(base->page_link));
	list_entry_t *curr=&free_list;
	while((curr=list_next(curr))!=&free_list){
		struct Page *currp=le2page(curr,page_link);
		if(p<currp){
			list_add_before(curr,&(base->page_link));
			break;
		}
	}
	if(curr==&free_list){
		list_add_before(curr,&(base->page_link));
	}
}
Esempio n. 6
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);
    struct Page* tempPG = base;
    for (; tempPG != base + n; tempPG++) {
        ClearPageReserved(tempPG);
        SetPageProperty(tempPG);
    }
    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;
            p->property = 0;
            list_del(&(p->page_link));
        }
        else if (p + p->property == base) {
            p->property += base->property;
            base->property = 0;
            list_del(&(p->page_link));
            base = p;
        }
    }
    nr_free += n;
    list_entry_t* rank = &free_list;
    while((rank=list_next(rank)) != &free_list) {
        if(le2page(rank, page_link) > base)
            break;
    }
    list_add_before(rank, &(base->page_link));
}
Esempio n. 7
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;
}
Esempio n. 8
0
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) {
        struct Page *p = le2page(le, page_link);
        if (PageProperty(p) && !PageReserved(p) && p->property >= n) {
            page = p;
            break;
        }
    }
    if (page != NULL) {
	le = page->page_link.prev;        
	list_del(&(page->page_link));
        if (page->property > n) {
            struct Page *p = page + n;
	    ClearPageReserved(p);
            SetPageProperty(p);            p->property = page->property - n;
            list_add(le, &(p->page_link));
    }
        struct Page *p = page;
        for (; p < page + n; ++p) {

            SetPageReserved(p);
            ClearPageProperty(p);
            p->property = 0;

            list_init(&(p->page_link));
        }        
	nr_free -= n;
        
    }
    return page;
}
Esempio n. 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);
    while (le != &free_list)	{
    	p = le2page(le, page_link);
    	if (p > base)
    		break ;
    	le = list_next(le);
    }

    p = le2page(le, page_link);
	list_add_before(le, &(base->page_link));
	le = list_prev(&(base->page_link));
	struct Page* pp = le2page(le, page_link);
	if (base + base->property == p) {
		base->property += p->property;
		ClearPageProperty(p);
		list_del(&(p->page_link));
	}
	if (pp + pp->property == base) {
		pp->property += base->property;
		ClearPageProperty(base);
		list_del(&(base->page_link));
	}

	nr_free += n;
}
Esempio n. 10
0
// LAB2: below code is used to check the first fit allocation algorithm (your EXERCISE 1) 
// NOTICE: You SHOULD NOT CHANGE basic_check, default_check functions!
static void
default_check(void) {
    int count = 0, total = 0;
    list_entry_t *le = &free_list;
    while ((le = list_next(le)) != &free_list) {
        struct Page *p = le2page(le, page_link);
        assert(PageProperty(p));
        count ++, total += p->property;
    }
    assert(total == nr_free_pages());

    basic_check();

    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);
    free_page(p0);
    assert((p0 = alloc_pages(2)) == p2 + 1);

    free_pages(p0, 2);
    free_page(p2);

    assert((p0 = alloc_pages(5)) != NULL);
    assert(alloc_page() == NULL);

    assert(nr_free == 0);
    nr_free = nr_free_store;

    free_list = free_list_store;
    free_pages(p0, 5);

    le = &free_list;
    while ((le = list_next(le)) != &free_list) {
        struct Page *p = le2page(le, page_link);
        count --, total -= p->property;
    }
    assert(count == 0);
    assert(total == 0);
}
Esempio n. 11
0
static void check_swap(void)
{
	//backup mem env
	int ret, count = 0, total = 0, i;
	list_entry_t *le = &free_list;
	while ((le = list_next(le)) != &free_list)
	{
		struct Page *p = le2page(le, page_link);
		assert(PageProperty(p));
		count++, total += p->property;
	}
	assert(total == nr_free_pages());
	cprintf("BEGIN check_swap: count %d, total %d\n", count, total);

	//now we set the phy pages env
	struct mm_struct *mm = mm_create();
	assert(mm != NULL);

	extern struct mm_struct *check_mm_struct;
	assert(check_mm_struct == NULL);

	check_mm_struct = mm;

	pde_t *pgdir = mm->pgdir = boot_pgdir;
	assert(pgdir[0] == 0);

	struct vma_struct *vma = vma_create(BEING_CHECK_VALID_VADDR,
			CHECK_VALID_VADDR, VM_WRITE | VM_READ);
	assert(vma != NULL);

	insert_vma_struct(mm, vma);

	//setup the temp Page Table vaddr 0~4MB
	cprintf("setup Page Table for vaddr 0X1000, so alloc a page\n");
	pte_t *temp_ptep = NULL;
	temp_ptep = get_pte(mm->pgdir, BEING_CHECK_VALID_VADDR, 1);
	assert(temp_ptep!= NULL);
	cprintf("setup Page Table vaddr 0~4MB OVER!\n");

	for (i = 0; i < CHECK_VALID_PHY_PAGE_NUM; i++)
	{
		check_rp[i] = alloc_page();
		assert(check_rp[i] != NULL);
		assert(!PageProperty(check_rp[i]));
	}
	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;
	for (i = 0; i < CHECK_VALID_PHY_PAGE_NUM; i++)
	{
		free_pages(check_rp[i], 1);
	}
	assert(nr_free==CHECK_VALID_PHY_PAGE_NUM);

	cprintf("set up init env for check_swap begin!\n");
	//setup initial vir_page<->phy_page environment for page relpacement algorithm

	pgfault_num = 0;

	check_content_set();
	assert(nr_free == 0);
	for (i = 0; i < MAX_SEQ_NO; i++)
		swap_out_seq_no[i] = swap_in_seq_no[i] = -1;

	for (i = 0; i < CHECK_VALID_PHY_PAGE_NUM; i++)
	{
		check_ptep[i] = 0;
		check_ptep[i] = get_pte(pgdir, (i + 1) * 0x1000, 0);
		//cprintf("i %d, check_ptep addr %x, value %x\n", i, check_ptep[i], *check_ptep[i]);
		assert(check_ptep[i] != NULL);
		assert(pte2page(*check_ptep[i]) == check_rp[i]);
		assert((*check_ptep[i] & PTE_P));
	}
	cprintf("set up init env for check_swap over!\n");
	// now access the virt pages to test  page relpacement algorithm
	ret = check_content_access();
	assert(ret == 0);

	//restore kernel mem env
	for (i = 0; i < CHECK_VALID_PHY_PAGE_NUM; i++)
	{
		free_pages(check_rp[i], 1);
	}

	//free_page(pte2page(*temp_ptep));
	free_page(pde2page(pgdir[0]));
	pgdir[0] = 0;
	mm->pgdir = NULL;
	mm_destroy(mm);
	check_mm_struct = NULL;

	nr_free = nr_free_store;
	free_list = free_list_store;

	le = &free_list;
	while ((le = list_next(le)) != &free_list)
	{
		struct Page *p = le2page(le, page_link);
		count--, total -= p->property;
	}
	cprintf("count is %d, total is %d\n", count, total);
	//assert(count == 0);

	cprintf("check_swap() succeeded!\n");
}
Esempio n. 12
0
// LAB2: below code is used to check the first fit allocation algorithm (your EXERCISE 1) 
// NOTICE: You SHOULD NOT CHANGE basic_check, default_check functions!
static void
default_check(void) {
	// 好吧,我们现在来看一下默认的测试吧!
    int count = 0, total = 0;
    list_entry_t *le = &free_list; // free_list应该是一个文件头吧!
    while ((le = list_next(le)) != &free_list) { // 开始遍历
        struct Page *p = le2page(le, page_link);
        assert(PageProperty(p));
        count ++, total += p->property; // counter表示一个有多少个page,total表示一共有多少个空闲页
    }
    assert(total == nr_free_pages());

    basic_check();

    struct Page *p0 = alloc_pages(5), *p1, *p2; // 分配5个页面给p0
    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; // 然后将他们全部变为0

    free_pages(p0 + 2, 3); // 这个玩意能free吗?
    assert(alloc_pages(4) == NULL); // 因为nr_free=3
    assert(PageProperty(p0 + 2) && p0[2].property == 3);
    assert((p1 = alloc_pages(3)) != NULL); // 给p1分配3块,现在nr_free=0
    assert(alloc_page() == NULL);
    assert(p0 + 2 == p1); 

    p2 = p0 + 1;
    free_page(p0); // 好吧,释放一个页面, nr_free=1
    free_pages(p1, 3); // 现在nr_free = 4
    assert(PageProperty(p0) && p0->property == 1);
    assert(PageProperty(p1) && p1->property == 3);
	/**   p0    p2    p1				end
	 *     |     |     |     |     |     |       
	 *     -------------------------------
 	 *     |  N           N     N     N  |
	 *	   |                             |
	 *     -------------------------------
	 */
    assert((p0 = alloc_page()) == p2 - 1); // 这里出错了。我倒是要看一看啦!这里应该不会出错啊,参照上面的图,重新分配的话,会分配p0,恰好是p2-1
    free_page(p0);
    assert((p0 = alloc_pages(2)) == p2 + 1); // 这里是测试first fit的
	/** start  p2    p0     		   end
	*     |     |     |     |     |     |
	*     -------------------------------
	*     |  N                       N  |
	*	  |                             |
	*     -------------------------------
	*/

    free_pages(p0, 2);
    free_page(p2);
	/** start  p2    p0     		   end
	*     |     |     |     |     |     |
	*     -------------------------------
	*     |  N     N     N     N     N  |
	*	  |                             |
	*     -------------------------------
	*/

    assert((p0 = alloc_pages(5)) != NULL);
    assert(alloc_page() == NULL);

    assert(nr_free == 0);
    nr_free = nr_free_store; // 恢复原来的样子

    free_list = free_list_store;
    free_pages(p0, 5);

    le = &free_list;
    while ((le = list_next(le)) != &free_list) { // 又要开始遍历了,这里主要是测试经过这么折腾之后,没有出现页丢失的情况
        struct Page *p = le2page(le, page_link);
        count --, total -= p->property;
    }
    assert(count == 0);
    assert(total == 0);
}
Esempio n. 13
0
/*buddy_check - Validate the correctness of buddy system.
 */
static void buddy_check(void){
	assert((1 << (MAX_ORD-2)) >= KMEMSIZE/MIN_BLOCK && (1 << (MAX_ORD-3)) < KMEMSIZE/MIN_BLOCK);
	uint32_t backup = nr_free;
	struct Page* p1 = buddy_alloc_pages(1);
	assert(backup == nr_free + 1);
	assert(PageProperty(p1));
	assert(p1->property == 1);
	backup = nr_free;
	struct Page* p2 = buddy_alloc_pages(3);
	assert(backup == nr_free + 4);
	assert(PageProperty(p2));
	assert(p2->property == 4);
	backup = nr_free;
	buddy_free_pages(p1);
	assert(backup == nr_free - 1);
	assert(!PageProperty(p1));
	assert(p1->property == 0);
	backup = nr_free;
	buddy_free_pages(p2);
	assert(backup == nr_free - 4);
	backup  = nr_free;
	p1 = buddy_alloc_pages(53);
	assert(backup == nr_free + 64);
	assert(PageProperty(p1));
	assert(p1->property == 64);
	backup = nr_free;
	p2 = buddy_alloc_pages(896);
	assert(backup == nr_free + 1024);
	assert(PageProperty(p2));
	assert(p2->property == 1024);
	backup = nr_free;
	buddy_free_pages(p1);
	assert(backup == nr_free - 64);
	assert(!PageProperty(p1));
	assert(p1->property == 0);
	backup = nr_free;
	buddy_free_pages(p2);
	assert(backup == nr_free - 1024);
	assert(!PageProperty(p2));
	assert(p2->property == 0);
	
	
	backup = nr_free;
	p1 = buddy_alloc_pages((1<<13) - 13);
	assert(backup == nr_free + (1<<13));
	assert(PageProperty(p1));
	assert(p1->property == (1<<13));
	
	backup = nr_free;
	p2 = buddy_alloc_pages((1<<13) - 13);
	assert(backup == nr_free + (1<<13));
	assert(PageProperty(p2));
	assert(p1->property == (1<<13));

	struct Page *p3, *p4;
	backup = nr_free;
	p3 = buddy_alloc_pages((1<<12) - 12);
	assert(backup == nr_free + (1<<12));
	assert(PageProperty(p3));
	assert(p3->property == (1<<12));

	backup = nr_free;
	p4 = buddy_alloc_pages((1<<12) - 12);
	assert(backup == nr_free + (1<<12));
	assert(PageProperty(p4));
	assert(p4->property == (1<<12));
	
	backup = nr_free;
	buddy_free_pages(p1);
	assert(backup == nr_free - (1<<13));
	assert(!PageProperty(p1));
	assert(p1->property == 0);	
	
	backup = nr_free;	
	buddy_free_pages(p2);
	assert(backup == nr_free - (1<<13));
	assert(!PageProperty(p2));
	assert(p2->property == 0);	
	
	backup = nr_free;	
	buddy_free_pages(p3);
	assert(backup == nr_free - (1<<12));
	assert(!PageProperty(p3));
	assert(p3->property == 0);	

	backup = nr_free;	
	buddy_free_pages(p4);
	assert(backup == nr_free - (1<<12));
	assert(!PageProperty(p4));
	assert(p4->property == 0);
	
	struct Page* p[100];
	int i;
	for(i = 0;i<100;i++){
		p[i] = buddy_alloc_pages(1);
		assert(!PageReserved(p[i]));
		assert(PageProperty(p[i]));
		assert(p[i]->property == 1);
	}
	for(i = 0;i<100;i++){
		buddy_free_pages(p[i]);
		assert(!PageProperty(p[i]));
		assert(p[i]->property == 0);
	}
}