[自制操作系统] 连续页分配释放&kmalloc/kfree

本文将在JOS上实现连续内存、释放,提供内核的kmallockfree,并在分配frambuffer的时候进行测试。
Github : https://github.com/He11oLiu/MOS

lab2中实现的内存管理只是针对单页建立freelistlist中用链表连接起来的都是代表单页的结构体struct PageInfo。且每次释放页,都是丢在这个free_list的头。这样有几个问题:

  • 不能分配大于4k的连续空间(后面做frambuf的时候要用到)
  • 不断地加到空闲列表的头会使内存空间十分的混乱。不利于内存管理。

所以先要设计一种能够支持分配连续空间的机制。

一种简单的实现

最简单的想法就是保持现有的不动,freelist保证从高地址到低地址。

这要求在page_free的时候做一下手脚,放到合适的位置。

npages_alloc的时候,找到连续的空闲的页即可。

Free

既然最主要的是在free的时候需要维护freelist按照地址的大小排列,那么就先简单将page_free重新写一下,找到合适的位置再进行插入操作。

特别要注意是否刚好应该插入到free list的头的情况:

如果刚好是最高的地址,那么就需要修改page_free_list

    if (page2pa(page_free_list) < page2pa(pp))
    {
        cur = page_free_list;
        page_free_list = pp;
        pp->pp_link = cur;
        return;
    }

否则需要遍历来查找位置插入

    cur = page_free_list;
    prev = page_free_list;
    while (page2pa(cur) > page2pa(pp))
    {
        prev = cur;
        if ((cur = cur->pp_link) == NULL)
            break;
    }
    prev->pp_link = pp;
    pp->pp_link = cur;

写完简单的free之后,我们可以确保freelist的顺序问题了。

npages_alloc

再来看主要的alloc,其核心思想则是检查是否刚好有连续的空间能够分配出去,这里用consecutive来记录累计连续的页数。

通过pageInfopages的数组的偏移即可知道其对应的地址,如果这个偏移是连续的,则代表着一块连续的空间:

(int)(cur - pages) == (int)(prev - pages) - 1

其中cur为当前遍历到的pageInfo,而prev是上次遍历的,通过上面的表达式可以判断是否为连续。

如果找到了合适的一块空间,则需要

  • 维护freelist,将这块空间前的最后一页连接到分配走的后面一页。

    同样注意是否有存在需要换头的情况

        if (pp == page_free_list)
            page_free_list = cur;
        else
            pp_prev->pp_link = cur;
  • 初始化页属性与空间

        if (alloc_flags & ALLOC_ZERO)
            memset(page2kva(prev), 0, n * PGSIZE);
        // clear pp link
        
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值