Memory allocator (moderate)
- 修改kernel/kalloc.c,修改kmem声明并定义结构体数组:
- 修改kernel/kalloc.c中的kinit函数,对kmemList进行初始化:
- 修改kernel/kalloc.c中的kfree函数,获取当前的cpuid并将释放的内存添加到对应的freelist:
- 修改kernel/kalloc.c中的kalloc函数,当前cpu的list为空时,从其他cpu的freelist获得:
测试结果如下:
Buffer cache (hard)
1.修改kernel/buf.h,添加时间字段:
2. 修改kernel/bio.c,添加NBUCK宏定义,代表哈希表桶的数量:
3. 修改kernel/bio.c,添加结构体buck并修改binit进行初始化,初始化过程中将当前buffer加入到对应哈希桶的哈希列表中:
4. 修改kernel/bio.c中的struct bcache结构体,删除head(这是因为可以用ticks来判断时间戳大小来释放buffer就不用自己维护lru链表了):
5. 修改kernel/bio.c中的bget函数(前半段逻辑相同,后半段获取当前最小的ticks并将其加入对应的哈希桶的链表当中):
static struct buf*
bget(uint dev, uint blockno)
{struct buf *b;uint64 num = blockno % NBUCK;acquire(&(hashtable[num].lock));// Is the block already cached?for(b = hashtable[num].head.next; b != &hashtable[num].head; b = b->next){if(b->dev == dev && b->blockno == blockno){b->refcnt++;release(&(hashtable[num].lock));acquiresleep(&b->lock);return b;}}release(&(hashtable[num].lock));struct buf* min_buf = 0;for (b = bcache.buf; b < bcache.buf + NBUF; ++b) {if (b->refcnt == 0) {if (min_buf == 0) {min_buf = b;} else {if (b->ticks < min_buf->ticks) {min_buf = b;}}}}acquire(&(hashtable[num].lock));min_buf->dev = dev;min_buf->blockno = blockno;min_buf->valid = 0;min_buf->refcnt = 1;min_buf->ticks = ticks;min_buf->next = hashtable[num].head.next;min_buf->prev = &hashtable[num].head;hashtable[num].head.next->prev = min_buf;hashtable[num].head.next = min_buf;release(&(hashtable[num].lock));acquiresleep(&min_buf->lock);return min_buf;panic("bget: no buffers");
}
-
修改kernel/bio.c中的brelse函数(注意将其在对应的桶中的链表中删除掉):
-
修改kernel/bio.c中的bpin、bunpin函数:
测试结果如下: