contributed by < Zames-Chang
>
在qtest command指令中加入sort指令
新增trace-16-mysort.cmd
因為qtest中的queue的元素為string,為了測試排序的功能,我假設輸入都是一個char,並根據他們的ascII code做排序。
並在driver.py加入
macro 在編譯前會被 preprocesser 把對應的程式碼貼到macro的地方,而不是一個 function call 的形式。
一個 function call 很麻煩,要把當前暫存器的東西備份一份到暫存器或記憶體,分配空間給 local 變數, Stack 要長上去,中間牽涉到許多記憶體的變化。耗時又費工。
linux/list.h
中的double link list
大概結構會像這樣
(參考來自:https://myao0730.blogspot.com/2016/12/linux.html)
讓我比較疑惑的是,一般來說 doubly linked list不是都是
不要濫用「一般來說」這詞,你到底看了多少軟體設計和實作,才讓你得以「總結」出軟體開發的規律,才有「一般」可言呢?
另外,注意術語寫為 doubly linked list,從細節做好,快去改!
為何它要特別定義一個 list_head裝下兩個 pointer,更重要的是就算我指到 next的 node我也拿不到資料阿?因為指到下一個 list_head中也沒有 Data_A,Data_B,Data_C阿?這邊我猜測應該跟 strcut記憶體是連續的有關吧?也許它可以透過相對位子取得 Data_A,Data_B,Data_C?
後來我看到查到這篇文章
上方連結有標題,為何不清楚書寫呢?
證實了應該我的想法,所以假設我要取的 student的 name
在 linux中process的資訊是由 task_struct管理,譬如說
struct list_head children
,就是這個 process中的有沒有子 process,如果有會以 link list串接在這裡。
struct list_head sibling
,則是存跟當前這個 process同樣 parent的進程
typeof的功能是去回傳一個跟帶入的 instance同樣型別的type, ,它會在你編譯前的預處理時去幫你把 typeof的內容轉換成對應的型別
e.x.
"for example" 縮寫是 e.g.,不是 "ex"
after preprocess
在linux程式碼中,它需要在 complie的時候先去確認某一些變數是不是型別是一樣的,譬如說以下 macro就是用於確認某個instance是否為某個特定型態。
另一個例子是當你希望把兩個 instance的型別作對調的時候,你不太可能在一開使用的時候就知道兩個變數分別的型別,這時候就可以利用typeof來得到兩個人分別的型別,並且對調
const __typeof__(((type *) 0)->member) *__pmember = (ptr)
這段是在製造一個 member的指針,並指向 ptr的位址,我這邊比較不理解的地方是為啥不用const __typeof__(member) __pmember = (ptr)
要大費周章的先用轉成比較上層的struct在去存取下面的member
(type *) ((char *) __pmember - offsetof(type, member))
這行則是透過減掉 member在此 struct中的偏移量,進而得到這個struct的起始位址。
讓使用者可以用更高level的角度來操作 link list,不然的話像原始碼中它如何判斷 link list是到底了呢?一般來講我們自己寫程式的話會判斷它最後一個元素有沒有指到 null,但是linux不是這樣實做,它實做的方式是去比較tail->next == head
,因此不了解 linux link list實做細節的話,會很容易踩到坑
不要 憑感覺 書寫,應該搭配實際程式碼和自行撰寫的分析數據來探討。及早脫離「文組TM」。特別在你撰寫過 merge sort 一類的程式後,針對 linked list 的例外處理就該有所察覺。
比較彈性,在 init時候它會把 tail跟 head都指向 head,因為假設他不是環狀的話你要insert tail就必須要走到最後一個元素才能insert也就需要O(n)
的時間複雜度,然而如果是環狀的話只要head->pre
就是tail了,這樣只要O(1)
。而且假設搜尋link list的某個元素,而且你知道從尾巴往前找比從頭往後找要快的話,環狀的結構就可以滿足這個需求,在linux中這個macro叫做list_for_each_entry_reverse
例如說$ htop
,由於程式會隨著時間加入或刪除,你不太可能用一個 array去 maintain,但是你又常常需要根據 cpu的使用時間去做排序,因此這個時候我們就必須要要對 link list做排序。
請把話說好,難道 "maintain" 是關鍵字嗎?這非得用英文寫嗎?程式寫不好,真的不可恥,但是連話都說不好,如何跟其他 (專業的) 工程人員溝通呢?
譬如說你要在作業系統中找到前三大的使用cpu的程式。
我會使用 merge sort 先把 link list 排序好,再取第k個element出來,這樣所需要的時間複雜度為O(nlogn)
Show me the code!
從 Linux 核心找出實際應用的程式碼出來。
list_for_each 假設你在執行的過程中不會有節點被刪掉,但是safe的版本會幫你檢查這件事情有沒有被發生
for_each 這種開發風格可以讓程式發開者不需要事先知道list的長度,也不會因為改動for loop中的i造成confuse的問題。
e.x.
因為有多 doc 是由程式像是 Doxygen 生成的,透過在原始碼中加入@的註解,可以被這些自動生成 doc 的程式解析,並輸出doc。
測試程式的 robust 程度,甚至測試 worst case, edge case,看要跑多久,對於軟體工程來說,測試非常重要,如果沒有測試你不知道你的程式在怎樣的情況下能夠 handle ,比如說,台灣股票市場曾經因為大力光股票價格太高,導致計算過程中 overflow 造成結果計算錯誤,這就是系統沒有經過單元測試的結果。
暫無