Exemple #1
0
static struct Page *
default_alloc_pages(size_t n) {
	// 我们来仔细分析一下究竟是如何来实现页面的分配的吧!n是请求的页面数
    assert(n > 0);
    if (n > nr_free) { // nr_free是空闲页面的总数
        return NULL;
    }
    struct Page *page = NULL;
    list_entry_t *le = &free_list;
	list_entry_t *len;
    while ((le = list_next(le)) != &free_list) { // 从现在开始遍历
        struct Page *p = le2page(le, page_link);
        if (p->property >= n) { // 如果空闲块的个数大于请求的个数n,这其实就是首次适应算法,是吧!
            //page = p;
            //break;
			int i;
			for (i = 0; i < n; ++i) {
				len = list_next(le); // list entry next
				struct Page *pp = le2page(le, page_link);
				SetPageReserved(pp); // setPageReserved主要是设置这个页面已经被占用了
				ClearPageProperty(pp); // 表示这个页面已经不是头表了
				list_del(le); 
				le = len;
			} // 一共分配n块嘛
			if (p->property > n) {
				(le2page(le, page_link))->property = p->property - n;
			}
			ClearPageProperty(p);
			SetPageReserved(p);
			nr_free -= n;
			return p;
        }
    }
	return NULL;
}
Exemple #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 (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));
}
Exemple #3
0
static struct Page *
default_alloc_pages(size_t n) {
    assert(n > 0);
    if (n > nr_free) {
        return NULL;
    }
    list_entry_t *le, *len;
    le = &free_list;

    while((le=list_next(le)) != &free_list) {
      struct Page *p = le2page(le, page_link);
      if(p->property >= n){
        int i;
        for(i=0;i<n;i++){
          len = list_next(le);
          struct Page *pp = le2page(le, page_link);
          SetPageReserved(pp);
          ClearPageProperty(pp);
          list_del(le);
          le = len;
        }
        if(p->property>n){
          (le2page(le,page_link))->property = p->property - n;
        }
        ClearPageProperty(p);
        SetPageReserved(p);
        nr_free -= n;
        return p;
      }
    }
    return NULL;
}
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且无法合并的块之前
}
Exemple #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 = &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));
}
Exemple #6
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;
		}
	}
Exemple #7
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_entry_t *next_le = list_next(&(page->page_link));
        list_del(&(page->page_link));
        if (page->property > n) {
            struct Page *p = page + n;
            p->property = page->property - n;
			SetPageProperty(p);
			if(list_empty(&free_list))
            list_add(&free_list, &(p->page_link));
			else
				list_add_before(next_le, &(p->page_link));
    }
        nr_free -= n;
        ClearPageProperty(page);
    }
    return page;
}
Exemple #8
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;
}
Exemple #9
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) {
//		le = list_prev(&(page->page_link));
//		list_del(&(page->page_link));
//		if (page->property > n) {
//			struct Page *p = page + n;
//			p->property = page->property-n;
//			list_add(le, &(p->page_link));
//		}
//		nr_free-= n;                        
//		ClearPageProperty(page);
//	}
//	return page;
//}
//static void
//default_free_pages(struct Page *base, size_t n) {
//	assert(n > 0);
//	struct Page *p = base, *p1;
//	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), *pre, *cur;
//	/*
//	   while (le != &free_list) {         
//	// 算法大致分析:
//	p = le2page(le, page_link);
//	// 遍历双向链表中的 page,如果该 page 可以和
//	// base+n 合并的话,就将这两个空闲快合并。
//	// 否则插入头指针后面。
//	le = list_next(le);
//	// 评价:
//	if (base + base­>property == p) {
//	// 1.没有维护双向链表的有序性。
//	base­>property += p­>property;
//	// 2.实现了空闲块的合并。
//	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));
//	 */
//	// MY CODE
//	while (1){
//		// 实现空闲页的插入
//		if(le == &free_list){
//			list_add_before(le, &(base->page_link)); break;
//		}
//		p = le2page(le, page_link);
//		if(&(p->page_link) > &(base->page_link)){
//			list_add_before(le, &(base->page_link)); break;
//		}
//		le = list_next(le);
//	}
//	pre = list_next(&free_list);
//	cur = list_next(pre);
//	// 遍历链表,合并连续的空闲块
//	while (cur != &free_list && pre != &free_list){
//		p = le2page(pre, page_link);
//		p1 =le2page(cur, page_link);
//		if(p + p->property == p1){
//			p->property += p1->property;
//			ClearPageProperty(p1);
//			list_del(&(p1->page_link));
//		}
//		else{
//			pre = cur;       
//		}
//		cur = list_next(cur);
//	}
//	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;
    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_entry_t* pr=list_prev(&page->page_link);//增添代码
        list_del(&(page->page_link));
        if (page->property > n) {
            struct Page *p = page + n;
            p->property = page->property - n;
			list_add(pr,&(p->page_link));//增添代码
            //list_add(&free_list, &(p->page_link));
		}
		nr_free -= n;
		ClearPageProperty(page); 
	}
	return page;
}
Exemple #10
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;
}
Exemple #11
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;  // (4.1)
    list_entry_t *le1;
    while ((le = list_next(le)) != &free_list) {
        struct Page *p = le2page(le, page_link); // (4.1.1)
        if (p->property >= n) { // (4.1.2) find
            int i;
            for (i = 0, le1 = le; i < n; i++, le1 = list_next(le1)) { // allocate page from p until p + n
                struct Page *p1 = le2page(le1, page_link);
                SetPageReserved(p1);   // (4.1.2) set PG_reserved
                ClearPageProperty(p1); // (4.1.2) clear PG_property
                list_del(le1);         // (4.1.2) unlink this page from free_list
            }
            page = p;
            break;
        }
    }
    if (page != NULL) {
        if (page->property > n) {
            (le2page(le1, page_link))->property = page->property - n; // (4.1.2.1)
        }
        nr_free -= n; // (4.1.3)
    }
    return page; // (4.1.4) or (4.2)
}
Exemple #12
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) {
        if (page->property > n) {
            //TODO: set property and reserve bits
            struct Page *p = page + n;
            p->property = page->property - n;
            list_add(le, &(p->page_link));
            SetPageProperty(p);
        }
        list_del(&(page->page_link));
        nr_free -= n;
        ClearPageProperty(page);
    }
    return page;
}
Exemple #13
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);
		// cprintf("%d ", (unsigned int)p / sizeof(struct Page));
        if (p->property >= n) {
            page = p;
            break;
        }
    }
	// cprintf("\n");
    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;
}
Exemple #14
0
static struct Page *
default_alloc_pages(size_t n) {
    assert(n > 0);
    if (n > nr_free) {
        return NULL;
    }
    list_entry_t *le = &free_list;
    while ((le = list_next(le)) != &free_list) {
        struct Page *page = le2page(le, page_link);
        // Finds a free block.
        if (page->property >= n) {
            // Malloc the first n pages.
            ClearPageProperty(page);
			SetPageReserved(page);
			list_del(le);

            if (page->property > n) {
                // Updates the remained space size.
                struct Page* new_page = page + n;
                new_page->property = page->property - n;
                list_add_before(list_next(le), &(new_page->page_link));
            }
            page->property = 0;
            nr_free -= n;
            return page;
        }
    }
    return NULL;
}
Exemple #15
0
// 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 ++;
}
Exemple #16
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));
}
Exemple #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 = 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));
}
Exemple #18
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;
}
Exemple #19
0
/*buddy_free_pages - Free continous pages start with page.The header page's
					 property flag should be unset, and the property field 
					 should assign to zero.
 */
void buddy_free_pages(struct Page* page){
	assert(!PageReserved(page) && PageProperty(page));
	uint32_t i = page2buddy(page, get_ord(page->property * MIN_BLOCK));
	set_rht(mem[i], ord(mem[i])-1);
	set_lft(mem[i], ord(mem[i])-1);
	update(i);
	nr_free += page->property;
	ClearPageProperty(page);
	page->property = 0;
}
Exemple #20
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;
}
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;
}
Exemple #22
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;
}
Exemple #23
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;
}
Exemple #24
0
//在free_list中寻找第一个空闲块(要求块大小>=n),调整该空闲块的大小,并返回分配的内存块的地址
static struct Page *
default_alloc_pages(size_t n) {
    assert(n > 0);
    if (n > nr_free) { //如果所有空闲块的大小都不能满足分配要求,则返回
        return NULL;
    }

    list_entry_t *le = &free_list;
    list_entry_t *pageList;

    //寻找第一个空闲块
    while ((le = list_next(le)) != &free_list) {
        struct Page *block = le2page(le, page_link);
        if (block->property >= n) {
        	int index=0;
        	//如果找到了合适的空闲块,说明该块的前n个页可以被分配出去,此时需要做一些设置
        	for (index=0; index<n; index++) {
        		pageList = list_next(le);
        		struct Page *singlePage = le2page(le, page_link);
        		SetPageReserved(singlePage);    //PG_reserved =1
        		ClearPageProperty(singlePage);  //PG_property =0
        		list_del(le);                   //unlink the pages from free_list
        		le = pageList;
        	}
        	//如果该空闲块过大,需要再重新计算大小
        	if (block->property > n) {
        		(le2page(le,page_link))->property = block->property - n;
        	}
        	ClearPageProperty(block);
        	SetPageReserved(block);
        	nr_free -= n;
            return block;
        }
    }
    //如果没有找到返回NULL
    return NULL;
}
Exemple #25
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 ;
}
Exemple #26
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;
}
Exemple #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 ;
}
Exemple #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;
}
Exemple #29
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) {
        struct Page *p = page;
        for(; p != page + n; p++) {
            ClearPageProperty(p);
            SetPageReserved(p);
        }
        if (page->property > n) {
            p = page + n; //get pointer of left space
            p->property = page->property - n;
            SetPageProperty(p); // set size of left space
            page->property = n;
            list_add(&page->page_link, &(p->page_link));
        }
        list_del(&(page->page_link));
        nr_free -= n;

    	/**
    	list_del(&(page->page_link));
        if (page->property > n) {
            struct Page *p = page + n;
            p->property = page->property - n;
            list_add(&free_list, &(p->page_link));
        }
        nr_free -= n;
        ClearPageProperty(page);
        */
    }
    return page;
}
Exemple #30
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;
        }
    }

    // Given Code
    // if (page != NULL) {
    //     list_del(&(page->page_link));
    //     if (page->property > n) {
    //         struct Page *p = page + n;
    //         p->property = page->property - n;
    //         list_add(&free_list, &(p->page_link));
    //     }
    //     nr_free -= n;
    //     ClearPageProperty(page);
    // }

    if (page != NULL) { //如果找到了足够大的块
        list_entry_t *pre_page = list_prev(&(page->page_link)); //获得链表前一块
        list_del(&(page->page_link));   //链表删除当前块
        if (page->property > n) {   //如果当前块比需要大则分裂
            struct Page *p = page + n;
            p->property = page->property - n;
            SetPageProperty(p);
            list_add(pre_page, &(p->page_link));    //分裂出来的块插在前一块之后,保证按地址排序
        }
        nr_free -= n;   //空闲页数减少
        ClearPageProperty(page);    //property = 0
        // SetPageReserved(page);
    }
    return page;
}