ucore lab2 练习1

为了实现First-Fit算法,应该用一些列表来管理空闲的内存块;
free_area_t 这个结构是用来管理空闲内存块的,列表结构都定义在了 lib/list.h 文件中;

list.h

struct list_entry {
    struct list_entry *prev, *next;			//这是一个双链表结构
};

memlayout.h

typedef struct {
    list_entry_t free_list;         // the list header
    unsigned int nr_free;           // # 空闲列里的空闲页
} free_area_t;
  1. 所以default_init()应该写成:
free_area_t free_area;

#define free_list (free_area.free_list)
#define nr_free (free_area.nr_free)

static void
default_init(void) {
	list_init(&free_list);
	nr_free = 0;		//初始化时空闲页为0
}

其中list_init()函数长这个样子:

static inline void
list_init(list_entry_t *elm) {
    elm->prev = elm->next = elm;		//双向链表初始化,头尾都指向头节点
}
  1. default_init_memmap()

首先Page的结构体:

struct Page {
    int ref;                        // page frame's reference counter
    uint32_t flags;                 // array of flags that describe the status of the page frame
    unsigned int property;          //空闲块的数量
    list_entry_t page_link;         // 空闲页链接
};

default_init_memmap() 函数:

static void default_init_memmap(struct Page *base, size_t n) {		//该函数用来初始化一个空闲块
    assert(n > 0);
    struct Page *p = base;		//首先将基址base赋给p
    for (; p != base + n; p ++) {		//n为页数,遍历n页直到结束
        assert(PageReserved(p));
        p->flags = p->property = 0;		//如果该页空闲且不是空闲块的第一页,则 p->property = 0;
        set_page_ref(p, 0);				//因为p空闲且没有被引用
    }
    base->property = n;				//如果该页空闲且是空闲块的第一页,则 p->property 等于所有块的数量;
    SetPageProperty(base);
    nr_free += n;		//最后加上空闲块的数量
    list_add(&free_list, &(base->page_link));	//起始页加入空闲页链表
}
  1. default_alloc_pages() 函数:
static struct Page *
default_alloc_pages(size_t n) {		//寻找第一个空闲的页
    assert(n > 0);
    if (n > nr_free) {		//若n大于连续空闲页数量,则退出
        return NULL;
    }
    struct Page *page = NULL;
    list_entry_t *le = &free_list;
    while ((le = list_next(le)) != &free_list) {	//遍历空闲链表,在空闲链表free_list中查找第一个符合条件的空闲页
        struct Page *p = le2page(le, page_link);
        if (p->property >= n) {	//若当前页的连续空闲页数量大于等于n,则可以分配
            page = p;
            break;
        }
    }
    if (page != NULL) {
        list_del(&(page->page_link));	//从空闲页中删除该页,表明该页已被使用
        if (page->property > n) {	//如果该页的空闲大小比n大,则只分配n个空间
            struct Page *p = page + n;	//分配了n个空间,将偏移指针移到第n个的后一位
            p->property = page->property - n;	//p的容量减小n,表明p被占用了n个空间	
            list_add(&free_list, &(p->page_link));	// 将p剩下的空间加入空闲列表
    }
        nr_free -= n;	//空闲链表总容量减小n
        ClearPageProperty(page);
    }
    return page;
}

list_next函数:

list_next(list_entry_t *listelm) {
    return listelm->next;
}
  1. default_free_pages 函数
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;	//空闲页总数量加上n
    list_add(&free_list, &(base->page_link));	//加上当前页
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值