contributed by < a1091150
>
實驗機器: Macbook Air 2013 A1466
tmp_block
跨越函式存取current
與部份區域變數同樣名稱pool_malloc
函式經由 get_loc_to_place()
取得定 block,但是之後直接使用 current
round_up()
函式實作錯誤修正的方式:加入 lab0 中的 list.h
檔案時候一併修正所有問題
list_head
這裡移植第一次的作業中 lab0
的 list.h
檔案,方便之後加入至 fibdrv
中,依照原本的程式碼概念重寫函式
struct block
結構體根據註釋, free block 的 prev
與 next
成員會成為 in-use block 的 payload,因此加入一個 union
來描述此結構體
將原本 prev
與 next
修改為 list_head
結構體
以圖片表示其構造
word_size
與 header_size
word_size
原本是對應 __SIZE_WIDTH__ / 8
,但是在程式碼中只描述 block 中的 int
位元組大小,在命名上我認為可以改成 payload_offset
header_size
原本是對應 word_size * 3
,但在程式碼中描述 block 結構體的位元組大小,在命名上我認為可以改成 block_size
因此可以改為以下程式碼,命名維持不變:
round_up
函式未特別設定下log2_word_size
為 2,原本的實作假設為 3,導致實作上不會與 4 位元組對齊。修改成以下函式:
block_head
變數新增一個串列 static LIST_HEAD(block_head);
,將所有 free block 以位址由小至大排列。
pool_init
函式透過 list_head
相關函式將 free block 加入至 block_head
中
pool_malloc
函式在原本的 pool_malloc
函式實作中,必定會有一個 free block ,它的作用類似於 stack pointer,同時表示末端位址的剩餘空間。可以假定一定有一個 free block
get_loc_to_place
函式透過 list_head
相關函式簡化實作,回傳首個符合的 free block (first fit)pool_malloc
函式分裂該 free block 成兩個,其中一個回傳,另一個加回 block_head
中list_replace
函式便是替代該節點pool_free
函式pool_free
函式中,在 block_head
尋找適合的節點位址,將回收的 block 加入,並嘗試合併前後一個的 free blockget_loc_to_free
函式透過 block_head
中的 free block 以位址大小排列的特性,比較位址順序,回傳後一個 free blocklist_insert_before
函式將回收的 block 加入至指定串列位址中block_try_merge
函式嘗試合併前後 free blockmpool_realloc
函式與 pool_calloc
函式函式維持不變
alloc.c 的程式碼與測驗 1 部份實作概念類似
metadata_t
紀錄 block,與測驗 1 的 block_t
概念相同,這一次有紀錄 *prev
與 *next
rbnode_t
紀錄相同大小的 free block
**tab_values
指標的指標陣列,分別指向相同 size
大小的 free blockalloc_tab
一樣透過 get_heap()
函式取得空間,若用 resize_tab_values
增加陣列大小,則原本的空間有機會在 free
函式呼叫時,透過 try_fusion
函式重新加入 red black tree另外程式碼有些怪異的寫法:
rbnode_t
中的 metadata_t *next, *prev
完全沒有使用;但是重新觀察會發現該前三個成員與 metadata_t
完全相同程式碼可以拆成:
metadata_t
與 sbrk
實作於 heap.c
與 heap.h
rbnode_t
實作於 rbtree.h
與 rbtree.c
malloc
, free
函式實作於 xalloc.h
與 xalloc.c