contributed by < ztex
>
typeof
(GNU extension)Referring to a Type with typeof
[quote]
大意:
如果是ISO C programs 請用 __typeof__
而不要用 typeof
詳情請見: Alternate Keywords
下面教了一些好用的用法:
大意大概是… 想宣告一個跟*x
一樣型態的變數y嗎?這樣搞就行了
我以前真的不知道可以這樣用, 讀document真的好重要喔…
Ztex
offsetof
http://man7.org/linux/man-pages/man3/offsetof.3.html
DESCRIPTION
The macro offsetof() returns the offset of the field member from the
start of the structure type.
This macro is useful because the sizes of the fields that compose a
structure can vary across implementations, and compilers may insert
different numbers of padding bytes between fields. Consequently, an
element's offset is not necessarily given by the sum of the sizes of
the previous elements.
A compiler error will result if member is not aligned to a byte
boundary (i.e., it is a bit field).
RETURN VALUE
offsetof()
returns the offset of the given member within the given
type, in units of bytes.
如果member 不是 a bytpe boundary, compiler error
Ztex
__extension__
GCC uses the __extension__
attribute when using the -ansi flag to avoid warnings in headers with GCC extensions. This is mostly used in glibc with function declartions using long long
用來告訴gcc 不用warnings了(使用
-ansi
flag 情況下)
Ztex
container_of
((type *) 0)->member
型態的 pointer __pmember
, 並且把 ptr
assign 給這個pointeroffsetof
計算出這個member對於目標address的偏移量__pmember
減掉這個偏移量就是目標address了https://www.geeksforgeeks.org/macros-vs-functions/
include/linux/fs.h
(block_device
)struct list_head bd_list
:
https://elixir.bootlin.com/linux/v4.15/source/drivers/usb/gadget/udc/bdc/bdc.h#L301
block_device:
Experient:
Block Device Drivers
揣摩:
block_device
是一個描述塊裝備
的結構, 他可以用來表示一個磁區或一個分區, 透過一系列的API進行I/O(上面的實驗)
而每個endpoint
都有一個 bd_list
(buffer descriptor list)(結構如上) 含有一個以上的 bd_table
, 軟體藉此找到特定的bd
.
我覺得他的設計考量可能考慮到一個特定的block_device
在進行操作時需要對其他block_device
進行I/O, 透過這個設計可以輕易traverse.
我對於這部分揣摩十分沒有把握
Ztex
除了「舉燭」,試著將核心程式碼抽離出來,轉寫獨立的程式來測試,一如本例的示範。
只是「看了再幻想」,終究不符合科學精神
Copy that. Working on it.
Ztex
include/linux/fs.h
(inode
)https://zh.wikipedia.org/wiki/Inode
https://blog.csdn.net/yf210yf/article/details/12138921
大意是在Unix-style 的檔案系統中的一種資料結構, 代表一個檔案或者目錄
甚麼是inode
POSIX inode description
The POSIX standard mandates file-system behavior that is strongly influenced by traditional UNIX file systems. An inode is denoted by the phrase "file serial number", defined as a per-file system unique identifier for a file.[8] That file serial number, together with the device ID of the device containing the file, uniquely identify the file within the whole system[9].
Within a POSIX system, a file has the following attributes[9] which may be retrieved by the stat system call:
POSIX 規檔案系統行為, inode 的定義是 pre-file system unique identifier
在 POSIX 系統中 一個檔案有上述屬性
list_head
的應用
揣摩: 在文件系統中所有inode
都在linked list
裡面, i_list
是使用中狀態的linked list, i_sb_list
是super block linked list, i_dentry
記錄了目錄上的連結.
當新增inode,會將i_list加在所有的已使用的inode linked list,然後加到super block,最後加到 i_dentry.
使用 list_head
的考量大概是因為新增刪除inodes 比較有效率.
include/linux/sched.h
(task_struct
)太長了, 我就不整個寫出了.
Ztex
揣摩: task_struct
是linux kernel中描述process 的 structure.
children
代表子行程, sibling
代表… 兄弟姊妹行程?
總之出現新的行程就會有個task_struct
新增進linked list.
關於這個部分我之前實作過一個小小的linux kernel module, 可以traverse一個process的所有childs, siblings, parents.
https://github.com/tony2037/simple-pstree
以下是其中一個function, children_to_end
.
利用Linux庫的 list_empty
, list_for_each
, recursively traverse all children.
在linux-list
repo裡的unit tests, 使用定義在assert.h
的function assert
實作unit test.
unit test的好處之一就是在於以比人工測試更有效率地對單一模組進行測試.
比如我在實作merge_sort
時, 必須先實作一個function合併兩個已排序的lists, (sortedqueue_splice). 此時為了驗證這個function的正確性, 我在/tests
中寫了一個merge_sort.c
來驗證這個funcion的正確性
總之就是兩條已排序的queue合併起來看一看結果正不正確. (q_new … 等已經通過測試)
Makefile
https://en.wikipedia.org/wiki/Merge_sort
了解merge sort的運作原理, 並且實作 project qtest
支援的merge sort.
為了達成實作了三個functions: sortedqueue_splice
, merge_sort
, q_split_half
並且學習在 project
linux-list
裡面的unit test
, 在 tests
directory 中新增三個對應的測試: merge_sort.c, q_split_half.c, sortedqueue_splice.c.
其中使用 assert
函式確定測資通過測試.
eg. merge_sort.c:
並且在Makefile
中新增對應的rules
因為方便就把所有dependencies 全部當作參數.
應該有更好的方法, 但還在思考
看個 merge_sort
這個演算法主要分三個部分
其中我的程式就存在memory leak issue
以下是使用valgrind 分析的結果 (這東西真D好用)
這代表這隻糟糕的程式如果遇到長度很長的資料, memory leak issue 就會凸顯我的無能.
接下來想試試看使用
phone_book
的測資測試一下
以下是通過unit test的結果: