contributed by < yunchi0921
>
linux_kernel
macro 在 compile 之前,preprocessor 會進行文字的替換,執行時不像 function 運用 stack 的 push & pop,是類似空間換取時間的概念。
如何證明macro是使用空間換取時間?
這邊參考 ChiAnLin0607同學的共筆,透過指令分別對macro與function部份進行objdump反組譯,可以看出macro佔用空間較多。
時間部份寫了小程式測試,實測出macro在時間上是稍短於function
typeof是GNU於標準C上的擴充,用於傳回object的type類型。
There are two ways of writing the argument to typeof: with an expression or with a type. Here is an example with an expression:
typeof (x[0](1))
儲存 array of pointer to function 回傳的 type。
typeof (int *)
儲存 type 為 pointer to int 。
typeof is often useful in conjunction with statement expressions . Here is how the two together can be used to define a safe “maximum” macro which operates on any arithmetic type and evaluates each of its arguments exactly once:
這裡使用了typeof得知a與b的type,也解決了macro沒有typechecking的問題。
(type *) 0)
()(type *) 0)->member)
__typeof__(((type *) 0)->member) *__pmember = (ptr);
__pmember
利用typeof取得該type,並餵ptr
給該指標。offsetof(type,member)
(type *) ((char *) __pmember - offsetof(type, member));
以下利用一個例子試試看:
結果
list move
:
移動一個node到一個list的開頭。
list_splice
:
加入一系列的lists nodes 到另一個list上。
LIST_POISONING
這樣的設計有何意義?LIST_POISONING can be enabled during build-time to provoke an invalid memory
access when the memory behind the next/prev pointer is used after a list_del.
This only works on systems which prohibit access to the predefined memory
addresses.
在 linux/poison.h 的註解當中
These are non-NULL pointers that will result in page faults
under normal circumstances, used to verify that nobody uses
non-initialized list entries.
當list_del執行的時候,將會把node的prev&next指向一個特定的位置,當access到這個位置時,會產生pagefault。
至於是為什麼,不曉得是否跟0xDEADBEAF 一樣是magic number有待查證。
環狀的 linked list 可以使每個節點都做一樣的事,不用考慮head及tail的問題。
list_for_each_safe
和 list_for_each
的差異在哪?“safe” 在執行時期的影響為何?list_for_each_safe
額外多儲存一個safe,儲存當前的下下個位置,當如果當前的下個node被移除時,不會找不到當前的node要link哪個位置。
可以增加程式可讀性 。
tests/
目錄底下的 unit test 的作用為何?就軟體工程來說的精神為何?確保每一個function的功能性及邏輯上正確,以減少Debug時,專案過大而不知道錯誤從何開始。
tests/
目錄的 unit test 可如何持續精進和改善呢?在實做mergesort時,因為在list.h
已經有很多function or macro 可以直接使用,所以與其是說要做出一個mergesort,不如說很像是在了解linux kernel circular doubly linked list 的實做方式。
這裡是我的實做code
實作時參考ldotrg的共筆。
它提到使用龜兔賽跑演算法去判斷list的中間值,只要設定兔子跑得速度是烏龜的兩倍就可以在兔子跑完一圈的時候,烏龜正好在中間值,值得注意的是要如何判斷是奇數或是偶數?
A:只要判斷說它離終點也就是head還有一步還是兩步的距離即可。
其中有遇到一些困難是,不知道為什麼要使用&(address of),而不使用*(pointer),因為在unitTest上面測試都是使用&來傳遞參數,所以我就照著做,不過我使用pointer會造成segmentation fault。
後來發現不是不用pointer call,只是要多一步malloc的步驟,所以使用&(address of)可以直接由process配置,不確定是不是只有這個目的,還是有更進一步的行為。