contributed by < kuihao
>
輸出呢?
jserv
queue.[ch]
和連帶的檔案,測試後用 Git 管理各項修改,要能滿足 $ make test
自動評分系統的所有項目。
queue.[ch]
需修改的項目:
lab0-c
專案,比較你自己實作的 merge sort 和 Linux 核心程式碼之間效能落差qtest
提供新的命令 shuffle
,允許藉由 Fisher–Yates shuffle 演算法,對佇列中所有節點進行洗牌 (shuffle) 操作qtest
提供新的命令 web
,提供 web 伺服器功能,注意: web 伺服器運作過程中,qtest
仍可接受其他命令
qtest
執行過程中的錯誤
qtest
再於命令提示列輸入 help
命令,會使 開啟 Address Sanitizer 觸發錯誤,應予以排除qtest
實作的記憶體錯誤,並透過 Massif 視覺化 "simulation" 過程中的記憶體使用量,需要設計對應的實驗v1.90
,執行方語法檢視目前版本:
顯示結果符合要求
list (Circular doubly-linked list) 的關鍵概念是,將結構體 list_head 嵌入到所需的結構體中,再藉由稍後會提及的 container_of 巨集得知 list 個別節點的地址。示意如下圖:
(原文: "你所不知道的 C 語言: linked list 和非連續記憶體")
Jim Huang2018
graphviz playground (線上繪圖編輯器)
協助繪製Function | Description |
---|---|
INIT_LIST_HEAD() | 產生一個指向自己的 Head_ptr |
list_add | 於 head 向前插入一個新 node 可用於實作 Stacks (like liunx kernel api document descriped, "This is good for implementing stacks.") |
list_add_tail | 於 head 向後插入一個新 node 可用於實作 Queues (like liunx kernel api document descriped, "This is useful for implementing queues.") |
list_del | 將其他指向此 node 的鍵斷開,並重新相連時跳過此 node |
list_del_init | 此 node 不但被斷鍵 (list_del) 同時也將本身的鍵初始化 |
list_empty | 向前為空:next 指向 head |
list_is_singular | next, prev 指向 head |
list_splice | head 向前插入一條新的 linked list |
list_splice_tail | head 向後插入一條新的 linked list (方向維持正確,舊鏈的尾巴接新鏈的尾巴) |
list_splice_init | 執行 list_splice() 並順便把新鏈的 head 給初始化 (變成空鏈) |
list_splice_tail_init | 執行 list_splice_tail() 並順便把新鏈的 head 給初始化 (變成空鏈) |
list_cut_position | 將一個環切成兩個環 |
list_move | 將目標 Node 移動至 Head->next |
list_move_tail | 將目標 Node 移動至 Head->prev |
git commit -a 時會被偵測出 memory leak 問題,原因 2022 年系統軟體系列課程討論區: commit 的時候出現 memory leak ,並學習使用 valgrind 動態檢測。
後來參考同學們的實作方式才發現我當初誤會 head 的意義,head 不必實作成 element_t,只需生成 list_head (*) 指標作為新生成的空 Queue。
Indirect pointer 風格的實作方式,每次先判斷 next pointer 是否指向 q_head (),若否,表示還有 node 可以 free,先將 indirect pointer 指向下一個 node 的 next pointer,並將前一顆 node 釋放掉;反之,將 q_head 釋放。
然而,此寫法再執行時會指向並釋放 Null Address,主要問題發生在第 7 至 9 行,凸顯出我這個寫法不適合使用 indirect pointer。第 7 行,indirect 先指向 head 的 next 指標的位址,但並非直接指向 next node 的位址,當第 9 行釋放 head 的記憶體位置,便會連帶 head 的 next 指標一起釋放,因此 indirect 就指向非法記憶體位址。並且另一個問題是通常 head 所指的位置一開始不應該被釋放掉,這會導致演算法設計上不易追蹤 queue 的所在位置。 後來仔細研讀 list.h 發現 list_for_each_entry_safe,可以預先存取下下顆 node 的位址,如此一來即使釋放掉下顆 node,也能將指標指向下下顆位址。
核心想法:設置一個回收桶存放暫存的副本,最後再一次清空回收桶。
參考 「你所不知道的 C 語言: linked list 和非連續記憶體」的 indirect pointer 版本 mergeTwoLists、Mergesort_list
如何運用原本用於普通非環狀 linked list 的 Merge sort?
環狀 list
從 tail 切開 (head->prev->next = NULL) 變成非環狀 linked list,套用 Mergesort_list(),排序完成後再將尾端上鏈並順時針將每個 node 的 prev pointer 重新上鏈xrandr shows you the names of different outputs available on your system (LVDS, VGA-0, etc.) and resolutions available on each. For more details
Discription | Keymap |
---|---|
複製前一行並向下新增 | Shift + Ctrl + D |
整行向上移動 | Shift + Ctrl + Up |
整行向下移動 | Shift + Ctrl + Down |
選取下一個相同的 Occurrence | Ctrl + D |
選取所有相同的 Occurrence | Alt + F3 |
git push
時出現以下警告:
表示本地端的 Remote's URL 尚未設定成 SSH 模式,git push
linux2022