예제 #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));
 //       assert(!PageProperty(p));
        p->flags = 0;
        set_page_ref(p, 0);
    }
    base->property = n;//设置空闲块大小为n
    SetPageProperty(base);//property为置为1表明为空闲的
    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;
            SetPageProperty(p);
            list_del(&(p->page_link));
        }
        else if (p + p->property == base) {
            p->property += base->property;
            SetPageProperty(base);
            base = p;
            list_del(&(p->page_link));
        }
    }
    nr_free += n;
    list_add_before(&free_list, &(base->page_link));

}
예제 #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);

    // 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且无法合并的块之前
}
예제 #3
0
static struct Page* default_alloc_pages(size_t n) {
    assert(0 < n);
    if (nr_free < n) {
        return 0;
    }
    struct Page* page = 0;
    list_entry_t* le = &free_list;
    while ((le = list_next(le)) != &free_list) {
        struct Page* p = le2page(le, page_link);
        if (n <= p->property) {
            page = p;
            break;
        }
    }
    if (page) {
        list_entry_t* prevLe = list_prev(&(page->page_link));
        list_del_init(&(page->page_link));
        if (n < page->property) {
            struct Page* p = page + n;
            p->property = page->property - n;
            SetPageProperty(p);
            list_add(prevLe, &(p->page_link));
        }
        nr_free -= n;
        ClearPageProperty(page);
    }
    return page;
}
//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;
    }
}
예제 #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);
	list_entry_t *insert_loc = &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 ((unsigned int)p < (unsigned int)base) {
			insert_loc = &(p->page_link);
		}
    }
    nr_free += n;	
	list_add_after(insert_loc, &(base->page_link));
}
예제 #6
0
static struct Page *
default_alloc_pages(size_t n) {
    assert(n > 0);
    if (n > nr_free) {
        return NULL;
    }
    struct Page *found = NULL;
    list_entry_t *e;
    for(e = list_next(&free_list);
        e != &free_list;
        e = list_next(e)) {

        struct Page *p = le2page(e, page_link);
        if(p->property >= n) {
            found = p;
            break;
        }
    }
    if(found != NULL) {
        if(found->property > n) {
            struct Page *more = found + n;
            more->property = found->property - n;
            SetPageProperty(more);
            list_add_after(&found->page_link, &more->page_link);
        }
        list_del(&found->page_link);
        found->property = 0;
        ClearPageProperty(found);
        nr_free -= n;
    }
    return found;
}
예제 #7
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));
}
예제 #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 (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;
            SetPageProperty(p);
            list_add(&free_list, &(p->page_link));
        }
        nr_free -= n;
        ClearPageProperty(page);
    }
    return page;
}
예제 #9
0
/*buddy_alloc_pages - alloc n page from free area and return the first page.
 *	                  The header page should set page property flag, and the
 *					  property field should assign to n which means next 
 *					  follow n pages has been allocated.
 */
struct Page* buddy_alloc_pages(size_t n){
	assert(n > 0);
	if(n > nr_free){
		return NULL;
	}
	struct Page* page = NULL;
	uint8_t o = get_ord(n * MIN_BLOCK);
	uint32_t i = 0;
	while(1){
		if( lft(mem[i]) >= o )
			i = lc(i);
		else if( rht(mem[i]) >= o )
			i = rc(i);
		else
			break;
	}	
	if( o == ord(mem[i]) ){
		set_rht(mem[i], 0);
		set_lft(mem[i], 0);
		page = buddy2page(mem[i], i);
		assert(!PageReserved(page));
		SetPageProperty(page);
		nr_free -= page->property = 1 << (ord(mem[i]) - 2);
		update(i);
	}
	return page;
}
예제 #10
0
//buddy_alloc_pages_sub - the actual allocation implimentation, return a page whose size >=n,
//                      - the remaining free parts insert to other free list
static inline struct Page *buddy_alloc_pages_sub(uint32_t numa_id, size_t order)
{
	assert(order <= MAX_ORDER);
	size_t cur_order;
	for (cur_order = order; cur_order <= MAX_ORDER; cur_order++) {
		if (!list_empty(&free_list(numa_id, cur_order))) {
			list_entry_t *le = list_next(&free_list(numa_id, cur_order));
			struct Page *page = le2page(le, page_link);
			nr_free(numa_id, cur_order)--;
			list_del(le);
			size_t size = 1 << cur_order;
			while (cur_order > order) {
				cur_order--;
				size >>= 1;
				struct Page *buddy = page + size;
				buddy->property = cur_order;
				SetPageProperty(buddy);
				nr_free(numa_id, cur_order)++;
				list_add(&free_list(numa_id, cur_order),
					 &(buddy->page_link));
			}
			ClearPageProperty(page);
			return page;
		}
	}
예제 #11
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;
	}
}
예제 #12
0
파일: buddy.c 프로젝트: f0rward/xv6-change
// implement the buddy system strategy for freeing page frames
void
free_pages_bulk(struct Page * page, int order)
{
  int size = 1 << order;
  unsigned long page_idx = page - mem_map, buddy_idx;
  struct Page * buddy, * coalesced;
  while (order < 10) {
    // calculate the buddy index, by xor operation
    // if 1 << order bit was previously zero, buddy 
    // index is equal to page_idx + size, conversely,
    // if the bit was previously one, buddy index is
    // equal to page_idx - size
    buddy_idx = page_idx ^ size;
    buddy = &mem_map[buddy_idx];
    if (!page_is_buddy(buddy, order))
      break;
    LIST_REMOVE(buddy, lru);
    free_area[order].nr_free --;
    buddy->property = 0;
    ClearPageProperty(buddy);
    page_idx &= buddy_idx;
    order ++;
  }
  coalesced = &mem_map[page_idx];
  dbmsg("free order %x, page %x\n", order, coalesced - pages);
  coalesced->property = order;
  SetPageProperty(coalesced);
  LIST_INSERT_HEAD(&(free_area[order].free_list), coalesced, lru);
  free_area[order].nr_free ++;
}
예제 #13
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 = p->property = 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);
	}

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

	p = le2page(le, page_link);
	if(le != &free_list && base + base->property == p) {
		base->property += p->property;
		ClearPageProperty(p);
		list_del(&(p->page_link));
	}

	le = list_prev(&(base->page_link));
	p = le2page(le, page_link);

	if (le != &free_list && p + p->property == base) {
		p->property += base->property;
		ClearPageProperty(base);
		list_del(&(base->page_link));
	}
	nr_free += n;

    /**
    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));
    */
}
예제 #14
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的头部
}
예제 #15
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;
}
예제 #16
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));
}
예제 #17
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));
}
예제 #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 = p->property = 0;
		set_page_ref(p, 0);
	}
	base->property = n;
	SetPageProperty(base);
	nr_free += n;
	list_add(&free_list, &(base->page_link));
}
예제 #19
0
static void
default_init_memmap(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));
        p->flags = p->property = p->ref = 0;
    }
    SetPageProperty(base);
    base->property = n;
    list_add(&free_list, &(base->page_link));
    nr_free += n;
}
예제 #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 *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;
}
예제 #21
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;
}
예제 #22
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
}
예제 #23
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;
}
예제 #24
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 ;
}
예제 #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->property = 0;
        set_page_ref(p, 0);
        list_add_before(&free_list, &(p->page_link));
    }
    nr_free += n;
    //first block
    base->property = n;
}
예제 #26
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));
}
예제 #27
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 ;
}
예제 #28
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;
}
예제 #29
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;
}
예제 #30
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;
}