contributed by < ICARUSHERALD96500
>
詳閱作業說明,指定的格式中有空白字元,留意各式細節,唯有重視小處並步步為營,方可挑戰原始程式碼規模超越三千七百萬行的 Linux 核心
q_new
原先對 Linux Kernel API 不熟悉,寫出 q_new
malloc
分配sizeof(struct list_head)
大小的記憶體空間。q
失敗,為 NULL
,則直接 return q
,q_new
函式就會回傳 NULL
。後來發現 list.h
當中就有 INIT_LIST_HEAD
故更改為下列
q_free
q_insert_head
使用 git diff
或 diff
命令來產生程式碼之間的差異列表,不要憑感覺填寫,注意位移量。
對於指標是否被成功分配記憶體的條件判斷的寫法,關於 if (head != NULL)
以及 if (head)
二者間的差別,雖然效果相同,後者更為簡潔,但為求可讀與維護性。
q_remove_head
起初對於 *head
意思與題目誤解,導致誤以為是移除對於 head
前一節點的元素,寫出下列的程式碼。
導致於使用 ./qtest
測試時反而產生把 link list tail 移除的效果。
並修正下列錯誤
commit bb0dbb1
熟悉linux kernel API並修正函式中不必要的list
宣告
在當中發現 list_del
q_remove_tail
使用與 q_remove_head
相同邏輯
commit bb0dbb1
同樣修正與函式q_remove_head
中同樣不必要的list
宣告
q_delete_mid
在 make test
中出現 ERROR: Removed value gerbil != expected value bear
。發現是在走訪到中間節點過程中使用 for()
迴圈使用錯誤導致函數輸出不為所求。修正確定其為走訪到 mid point,並改為使用 while
使之更為簡短。
q_swap
首先我嘗試的方法使用,在每兩個節點中進行 next
與 prev
之間的關係互換
但在該方法下會產生的問題是 head 所指向的節點會因為 prev 與 next 關係重組而被排列到最後。效果如下:
熟悉kernel api後改進:
commit b18ff64
q_reverse
閱讀 'qtest命令直譯器的實作',發現其中展示qtest原理,展示在 qtest.c 當中的 init_cmd()
添加:
結果 make
後產生下列錯誤代碼:
將 bool do_hello(int argc, char *argv[])
改為 static bool do_hello(int argc, char *argv[])
後解決。
qtest
命令中參照自動測試程式在qtest新增shuffle功能,在 console.h
的巨集中:
要添加新命令需要透過在 console.c
底下的 console_init
當中使用 add_cmd
函式。該函式需要輸入三個引數 "<instruction>"
、<do_*>
、"<document>"
。以呼叫同樣宣告在console.c
底下命名為 do_<instruction>
的函式(因為在巨集中 do_##cmd
將所要呼叫的函式名稱 concatinate 為 cmd 前加上 do_
)。
以 q_new
函式被呼叫的流程為例。首先 qtest.c
的主函式中, init_cmd()
使用 ADD_COMMAND
將 q_new()
加入。add_cmd
接收的第二項引數是型別為 cmd_func_t
的函式指標。該指標指向 console.c
的 Build-in funciton 或 qtest.c
的 do_*
函式,如 do_new()
,再由該函式中呼叫在 queue.c
中所撰寫的各項 q_*
函式。
將 shuffle
分別新增在 init_cmd
與 console_init
底下的的差別似乎不大,同樣都可以執行。但最後決定添加在 console
底下,因為其他鏈結串列的操作同樣新增在這個類別。
qtest.c
queue.h
queue.c
shuffle
修改檔案: qtest.c
、Makefile
新增檔案: list_sort.c
、list_sort.h
list_sort.c
為了要讓 ./qtest
command line 當中的 time
指令可以執行 linux list_sort
的方法,利用首先在 lab0-c中新增 list_sort.c
,並移除不會用到的部份:
list_sort.h
其中包含 list_sort.c
所需要的定義
Makefile
為了使 make
時連同 list_sort
加入源代碼文件的目標編譯文件,所需更改:
qtest.c
在 qtest.c
中建立函式:
新增一筆測資 trace-sort.cmd
於 trace/
中:
並將 Makefile
中 check 的部份改為下列。執行 make check
時,便會使用自己定義的 trace-sort.cmd
測資。
結果如下:
資料總數 | q_sort() 測試1(s) | q_sort() 測試2(s) | q_sort() 測試3(s) | q_sort() 測試4(s) | q_sort() 測試5(s) |
---|---|---|---|---|---|
100000 | 0.08 | 0.076 | 0.078 | 0.075 | 0.076 |
300000 | 0.302 | 0.309 | 0.316 | 0.309 | 0.313 |
500000 | 0.614 | 0.585 | 0.578 | 0.576 | 0.585 |
資料總數 | list_sort() 測試1(s) | list_sort() 測試2(s) | list_sort() 測試3(s) | list_sort() 測試4(s) | list_sort() 測試5(s) |
---|---|---|---|---|---|
100000 | 0.108 | 0.055 | 0.054 | 0.056 | 0.055 |
300000 | 0.180 | 0.178 | 0.179 | 0.178 | 0.180 |
500000 | 0.303 | 0.311 | 0.305 | 0.304 | 0.308 |
比較 q_sort
、 list_sort
性能差異:
論文提出一種測試程式執行時間是否為 constant time 的工具 dudect,這個方法不需要硬體模型,以消弭不同硬體架構下對測量的影響。目的是驗證理論上時間複雜度為 constant time ,但實則存在 time leakage 的問題,如此可以藉由程式處理不同輸入時的響應時間差,藉此推敲程式內部細節,引發資安疑慮。
文中取 '字串比較' 典型場景。普遍作法為逐字元比較,若一但遇到不相符者即刻中斷比較並回傳false
,如此便可以透過從輸入字元到回傳的時間推敲是第幾個字元錯誤。較佳的作法為,就算遭遇不相符,也同樣比對完剩餘字元,以此避免time leakage。
作者採取 Students' T test 其中 Two-sample T test 進行實驗。使用兩種測資,第一種為全數固定為某值的固定測資、第二種為亂數的隨機測資。在虛無假設下進行 Fix-vs-Random test。