lab2-1-Extra——一个可能的解决思路
题目要求对物理空间的高32MB地址空间建立伙伴关系,我在这里简单梳理一下我基于数组的实现,由于课上构思比较紧张,代码有些写的不妥的地方请海涵。
首先建立用于存储区间信息的结构体:
1 | typedef struct Buddy{ |
其中,$start$代表该区间的起始位置;
$size$代表区间大小;
$time$是一个比较特殊的量,记录该区间是第几次分裂而来,初始化为0;
$mode$代表区间状态,1代表已分配,0代表未分配,还有-1会表示一个比较特殊的状态(已分裂),后续会详细解释;
$f$也是一个比较特殊的量,记录着该区间是由数组中那个元素分裂而来,初始化为-1;
$tot$记录目前$boddy$的个数,初始化为0。
这里buddy数组我预留了100000,比较保守。
buddy_init
的思路:
只需要从 $0x2000000$以起始位置实现8个buddy并存入数组中即可。
1 | void buddy_init(void) { |
buddy_alloc
的思路:
大体分为3步:
- 寻找符合要求的地址最低的区间
- 针对该区间进行分裂操作
- 获取各种需要的信息并返回
1 | int buddy_alloc(u_int size, u_int *pa, u_char *pi) { |
可以看到,上述比较关键的是进行分裂操作的函数,此处我写的是一个findMin
递归函数,核心就是将区间分裂,但不删除旧的区间,仅在数组最后添加新的子区间,并标记旧区间的状态为-1,新子区间的$f$记为旧区间的下标,更新time并标记到新增子区间。
1 | int findMin(int i, u_int size) { |
buddy_free
的思路:
分两步:
1.寻找满足起始地址为pa的区间并改变其状态为未分配
2.合并可能合并的区间
1 | void buddy_free(u_int pa) { |
上述的关键也是merge
函数,本处我是递归实现的:
1 | void merge(u_int time) { |
总结:
对于本题,我采用了数组实现的方法,为了避免TLE,想到了分裂时并不删除区间的方法,其实是以空间换时间,或许可以尝试链表实现的方法,可能更优雅和高效。
This is copyright.