實驗總結
- 本次實驗用時約兩個小時,修改了 xv6 中大量惡臭代碼。
測試結果:html
$ make grade alloctest: OK (7.2s) alloctest: OK (5.8s) usertests: OK (84.3s) Score: 100/100
0. 實驗準備
實驗指導連接git
上來直接:github
$ cd xv6-riscv-fall19 $ git checkout alloc
實驗分爲兩個子任務:bash
- 給 xv6 的 vfs 加上 malloc(以前是靜態內存池)
- 修改 xv6 的 buddy allocator,經過維護一對 buddy 的
B1_is_free XOR B2_is_free
這個佔用狀態,節約了 ~1M 內存。
感受是重在閱讀和理解 xv6 代碼,這兩個 lab 代碼量都很小。函數
1. file.c
把 filealloc()
中遍歷 ftable.file
的代碼和 fileclose()
相應的釋放代碼替換爲 bd_malloc()
便可。工具
個人修改測試
2. buddy.c
這個 buddy allocator 中維護了兩個 bitset ,一個存是否分裂 bd_sizes[k].split
,另外一個存是否已佔用 bd_sizes[k].alloc
。 只須要不斷查找 bit_*
這組工具函數出現的位置而後替換成相應的實現便可。spa
重難點不在於動態 malloc/free
的部分,實際上這些代碼很好改。關鍵在於 bd_initfree()
和 bd_initfree_pair()
部分。code
由於 buddy allocator 管理內存的同時須要在內存區域頭部放一些 metadata,且內核提供內存區域的長度也極可能不是對其 2^k 次方的,故須要把一些區域 mark 爲 allocated 。同時這些區域對應的 buddy 可能須要被加入 free_list (bd_initfree()/bd_initfree_pair()
用來完成此工做)htm
根據 bd_init()
中代碼:
// done allocating; mark the memory range [base, p) as allocated, so // that buddy will not hand out that memory. int meta = bd_mark_data_structures(p); // mark the unavailable memory range [end, HEAP_SIZE) as allocated, // so that buddy will not hand out that memory. int unavailable = bd_mark_unavailable(end, p); void *bd_end = bd_base+BLK_SIZE(MAXSIZE)-unavailable; // initialize free lists for each size k int free = bd_initfree(p, bd_end, p, end);
這些不可用內存對應的內存區間爲 [begin, p)
和 [end, HEAP_SIZE)
。在 bd_initfree_pair()
中特判這些內存範圍,就能夠把他們的 buddy 識別出來,而無需查找 bd_sizes[k].alloc
。