在linux核心list.h中包含了關於lru鍊錶的很多操作,可以方便呼叫。在此總結如下。(linux版本為4.3)
一、初始化
1. 初始化煉表頭:
a) list_head(name)
b) init_list_head(struct list_head *list)
二、新增
1. 在煉表頭新增:
list_add(struct list_head *new, struct list_head *head)b)
2. 在鍊錶尾新增:
list_add_tail(struct list_head *new, struct list_head*head)
三、刪除
1. 刪除某元素:
list_del(struct list_head *entry)
2. 刪除某元素,並初始化:
list_del_init(struct list_head *entry)
四、替換
1. 替換某舊元素為新元素:
list_replace(struct list_head *old,
structlist_head *new)
2. 替換某舊元素為新元素,並初始化舊元素:
list_replace_init(struct list_head *old,
struct list_head *new)
五、遷移
1. 將某舊元素從舊鍊錶加到新煉表頭,舊鍊錶中將其刪除:
list_move(struct list_head *list, struct list_head*head)
2. 將某舊元素從舊鍊錶加到新鍊錶尾,舊鍊錶中將其刪除:
list_move_tail(struct list_head *list,
struct list_head *head)
六、判斷
1. 是否某元素在鍊錶尾:
list_is_last(conststruct list_head *list,
const struct list_head *head)
2. 是否鍊錶為空:
list_empty(const struct list_head *head)
3. 雙重判斷是否鍊錶為空:
list_empty_careful(const struct list_head *head)
4. 是否鍊錶只有乙個元素:
list_is_singular(const struct list_head *head)
七、特殊
1. 將煉表頭元素放到鍊錶尾:
list_rotate_left(struct list_head *head)
2. 將鍊錶按某元素分為兩個鍊錶:
list_cut_position(struct list_head *list,
structlist_head *head, struct list_head *entry)
3. 將兩個鍊錶合併為乙個鍊錶(插入到head與head->next之間位置):
a) list_splice(const struct list_head *list,
struct list_head *head)
b) list_splice_init(struct list_head *list,
struct list_head *head)
4. 將兩個鍊錶合併為乙個鍊錶(插入到head->prev與head之間位置):
a) list_splice_tail(struct list_head *list,
structlist_head *head)
b) list_splice_tail_init(struct list_head *list,
struct list_head *head)
5. 鍊錶遍歷(尾到頭)for迴圈:
a) list_for_each(pos, head)
b) list_for_each_safe(pos, n, head)
6. 鍊錶遍歷(頭到尾)for迴圈:
a) list_for_each_prev(pos, head)
b) list_for_each_prev_safe(pos, n, head)
7. 鍊錶遍歷(頭到尾)for迴圈,獲取每乙個元素:
a) list_for_each_entry(pos, head, member)
b) list_for_each_entry_safe(pos, n, head, member)
8. 鍊錶遍歷(尾到頭)for迴圈,獲取每乙個元素:
a) list_for_each_entry_reverse(pos, head, member)
b) list_for_each_entry_safe_reverse(pos, n, head, member)
9. 鍊錶遍歷(從某元素之後開始向尾)for迴圈,獲取每乙個元素:
a) list_for_each_entry_continue(pos, head, member)
b) list_for_each_entry_safe_continue(pos, n, head, member)
10. 鍊錶遍歷(從某元素之前開始向頭)for迴圈,獲取每乙個元素:
list_for_each_entry_continue_reverse(pos, head, member)
11. 為上面兩個遍歷,準備乙個元素:
list_prepare_entry(pos, head, member)
12. 鍊錶遍歷(從某元素開始向尾)for迴圈,獲取每乙個元素:
a) list_for_each_entry_from(pos, head, member)
b) list_for_each_entry_safe_from(pos, n, head, member)
13. 鍊錶遍歷(從某元素開始向頭)for迴圈,獲取每乙個元素:
list_for_each_entry_safe(pos, n, head, member)
八、查詢
1. 查詢該元素:
list_entry(ptr, type, member)
2. 查詢鍊錶第乙個元素:
a) list_first_entry(ptr, type, member)
b) list_first_entry_or_null(ptr, type, member)
3. 查詢鍊錶最後乙個元素:
list_last_entry(ptr, type, member)
list_next_entry(pos, member)
list_prev_entry(pos, member)
這裡只列出了對應kernel版本常用的list函式,對於新版本可到對應list.h進行檢視。
Linux kernel 關於keyboard部分
linux kernel 關於keyboard部分 keyboard.c 用於處理和鍵盤相關的input handler。其中包括後續的鍵碼轉換和輸出 atkbd.c 常用的鍵盤布局,用於獲得掃瞄碼,並將其傳送到input handler 鍊錶中 struct input handler kbd h...
Linux kernel併發處理
理解好併發處理,有幾個小概念是相關的。1.由於圖靈機本身是依賴side effect來工作,故同步互斥機制便有了必要性。角度來看,如果依賴了共享的變數,便意味著可能需要同步保護。如果是lamada演算的函式式程式設計,是不需要同步保護滴。2.死鎖dead lock的必要4條件。1.資源的獨占性 不可...
單步執行linux kernel
如果能給linux kernel打log,如果能單步執行,如果能像普通應用程式那樣,step by step的檢視程式跑 了.該多好?這是乙個夢想,但從未實現過 因為那是kernel,不是應用程式。kernel一閃而過,我有什麼能力讓它駐足停留,為自己看個夠?雖然,也知道kernel是人寫的 廢話 ...