contributed by < fateyan
>
Problem Source
q_new
q_free
q_insert_head
s
是 NULL 的時候該怎麼辦,我就視同 q == NULL
處理了,插尾也一樣q_insert_tail
q_remove_head
q_size
q_reverse
scripts/driver.py
於是繼續追蹤scripts/driver.py
裡面,進入點是 run
,主要都在處理參數,然後功能幾乎都在 Tracer
裡面實現,那接下來簡介 Tracer
Tracer
維護了一些 trace
的 dictionary,還有 Base Directory 之類的環境資訊和參數,還有跑測試的一些 method
run
是 Tracer
的主要工作進入點,是把跑 trace
需要的資訊準備好,然後把 trace
一個一個丟進 runTrace
跑追蹤qtest
和 valgrind
,又或者是在 command line interface 上和兩種兼容的測試工具
這部份有些讓我不太知道為何這麼實作的點:
- 57 行的測試感覺很冗餘
- trace 用 dictionary 維護也有點奇怪,直覺上在這裡不管是 Hash Table 還是 RBTree 都不太可能比裸的 Array 快,而且這個場景也沒有真的需要用到 Dictionary 優勢的地方
- console.c
裡 L481 為什麼是 RIO_BUFSIZE - 2,不是 - 1,應該就只是留一個 NULL Terminator 吧?
qtest.c
report.c
console.c
harness.c
queue.o
,那我們就繼續追蹤 qtestqtest.c
console.c
裡的 add_cmd 來把 CLI 指令和操作 queue 的函數掛進 cmd_list
queue_init
console.c
push_file
開啟了一個檔案之後會用 struct RIO_ELE
(Buffered I/O 結構)來記錄它的一些東西,例如 FD 或 buffer 之類的。select
所以翻了一下資料
fd
:雖然不知道怎麼實作的,但被開啟的檔案會被統一整理在 file table
裡面,而 fd
就是 file table
的 entry(講的簡單一點的話可能就像 T file_table[MAX_FDS]
)select
和 blocking read 的差別在於它不會浪費 CPU cyclenfds
是現在用到的 fd
的最大值 + 1,我在想原因會不會是所有會創造/給出 fd 的函數都會給沒被佔用的最小的那個,那麼就算有新的 fd
出現了,它也會是 nfds
,但所有的 fd 都該/會被僅有的一個 select 監視嗎?有沒有可能有 multi-select 而且還 multithreadedcmd_select
就是 select
的再包裝,主要是迎合 RIO_ELE
實作了 buffered I/Oconsole.c
整個都在做 console 的 IO, parsing 還有實作基本的 CLI 指令,對外比較重要的 function 大概就 add_cmd
吧harness.c
一開始看到 harness 這個字愣了很久,後來發現原來是專有名詞,我覺得前面連結的 Wiki 把 harness 解釋的很好就不多解釋了,那比較特別的部分就是會用 Linked List 把 malloc 出來的資料串起來,而且資料的前後都會加 magic header 和 footer,0xdeadbeef 和 0xbeefdead。