国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 操作系統(tǒng) > 正文

Kernel數(shù)據(jù)結(jié)構(gòu)移植(list和rbtree)

2024-06-28 13:25:31
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
Kernel數(shù)據(jù)結(jié)構(gòu)移植(list和rbtree)

主要移植了內(nèi)核中的 list,rbtree。使得這2個(gè)數(shù)據(jù)結(jié)構(gòu)在用戶(hù)態(tài)程序中也能使用。

同時(shí)用 cpputest 對(duì)移植后的代碼進(jìn)行了測(cè)試。(測(cè)試代碼其實(shí)也是使用這2個(gè)數(shù)據(jù)結(jié)構(gòu)的方法)

內(nèi)核代碼的如下文件:(內(nèi)核版本 v3.2 debian 7.5源碼)

  1. include/linux/list.h (刪除了 hlist 相關(guān)內(nèi)容)
  2. include/linux/rbtree.h
  3. lib/rbtree.c

對(duì)上面的代碼進(jìn)行了一些簡(jiǎn)化,只留了常用的函數(shù)。同時(shí)刪除了其中和內(nèi)核相關(guān)的部分。

主要內(nèi)容:

  • list 介紹 (循環(huán)雙向鏈表)
  • rbtree 介紹

1. list 介紹 (循環(huán)雙向鏈表)1.1 簡(jiǎn)介

Linux中的鏈表用法與一般數(shù)據(jù)結(jié)構(gòu)書(shū)中介紹的用法有些不一樣。

Linux內(nèi)核中,為了保證鏈表的通用性,將鏈表的節(jié)點(diǎn)結(jié)構(gòu)單獨(dú)抽取了出來(lái),也就是將鏈表的結(jié)構(gòu)和鏈表的數(shù)據(jù)分開(kāi)定義。

一般數(shù)據(jù)結(jié)構(gòu)的書(shū)中介紹到的鏈表都是將鏈表的數(shù)據(jù)和鏈表的結(jié)構(gòu)一起定義的。

注:具體介紹可以我之前的博客參見(jiàn):http://www.CUOXin.com/wang_yb/archive/2013/04/16/3023892.html 中的 1.2節(jié)

里面很重要的一點(diǎn)就是:鏈表結(jié)構(gòu)和數(shù)據(jù)分開(kāi)后,是如何通過(guò)鏈表節(jié)點(diǎn)結(jié)構(gòu)來(lái)獲取數(shù)據(jù)的?

帶有safe的函數(shù)或者宏都是可以用于多線程的

1.2 修改部分
  1. 刪除了hlist相關(guān)內(nèi)容
  2. 修改了 list_del 函數(shù): 將 LIST_POISON1 和 LIST_POISON2 改成了 NULL
  3. 刪除了 list_empty_careful: 用戶(hù)空間用不上
  4. 刪除 __list_for_each: 和 list_for_each 重復(fù)
  5. 刪除 list_PRepare_entry: 暫時(shí)不需要
  6. 刪除 list_safe_reset_next: 暫時(shí)不需要
  7. 刪除 list_rotate_left: 暫時(shí)不需要
  8. 所有變量 new 改為了 newnode: new 是 c++ 關(guān)鍵字,用CppUTest進(jìn)行測(cè)試時(shí)無(wú)法編譯

1.3 list.h 對(duì)外的接口

No.

主要 函數(shù)

說(shuō)明

1.list_add在 head 之后追加一個(gè)節(jié)點(diǎn)
2.list_add_tail在 head 之前追加一個(gè)節(jié)點(diǎn), 也就是在末尾追加一個(gè)節(jié)點(diǎn)
3.list_del刪除一個(gè)節(jié)點(diǎn), 并將這個(gè)節(jié)點(diǎn)的next, prev 置為 NULL
4.list_del_init刪除一個(gè)節(jié)點(diǎn)并初始化刪除的節(jié)點(diǎn)
5.list_replace替換一個(gè)節(jié)點(diǎn)
6.list_replace_init替換一個(gè)節(jié)點(diǎn), 并初始化被替換的節(jié)點(diǎn)
7.list_move移動(dòng)節(jié)點(diǎn)到 head 之后
8.list_move_tail移動(dòng)節(jié)點(diǎn)到 head 之前
9.list_is_last判斷節(jié)點(diǎn)是否是鏈表中最后一個(gè)
10.list_empty判斷鏈表是否為空 (即, 是否只有 head 節(jié)點(diǎn))
11.list_is_singular判斷鏈表中是否只有一個(gè)節(jié)點(diǎn) (除了 head 之外)
12.list_cut_position將1個(gè)鏈表截?cái)酁?個(gè)鏈表
13.list_splice將2個(gè)鏈表合并為1個(gè)鏈表, @list中的所有節(jié)點(diǎn)(不包括list)加入到 head 之后
14.list_splice_tail將2個(gè)鏈表合并為1個(gè)鏈表, @list中的所有節(jié)點(diǎn)(不包括list)加入到 head 之前
15.list_splice_init同 list_splice, 最后會(huì)初始化 @list
16.list_splice_tail_init同 list_splice_tail, 最后會(huì)初始化 @list

No.

主要 宏

說(shuō)明

1.list_entry獲取包含此節(jié)點(diǎn)的 struct
2.list_first_entry獲取包含此節(jié)點(diǎn)的 首個(gè) struct
3.list_for_each從 head節(jié)點(diǎn)之后一個(gè)節(jié)點(diǎn)開(kāi)始向后循環(huán)
4.list_for_each_prev從 head節(jié)點(diǎn)之前一個(gè)節(jié)點(diǎn)開(kāi)始向前循環(huán)
5.list_for_each_safelist_for_each 的安全版本, 即, 循環(huán)時(shí)即使有其它線程刪除節(jié)點(diǎn)也可正常運(yùn)行
6.list_for_each_prev_safelist_for_each_prev 的安全版本
7.list_for_each_entry同 list_for_each, 只是參數(shù)不同
8.list_for_each_entry_reverse同 list_for_each_prev, 只是參數(shù)不同
9.list_for_each_entry_continue同 list_for_each_entry, 但不是從頭(head)開(kāi)始循環(huán)的
10.list_for_each_entry_continue_reverse同 list_for_each_entry_reverse, 但不是從頭(head)開(kāi)始循環(huán)的
11.list_for_each_entry_from從指定位置開(kāi)始向后循環(huán)
12.list_for_each_entry_safelist_for_each_entry 的安全版本
13.list_for_each_entry_safe_continuelist_for_each_entry_continue 的安全版本
14.list_for_each_entry_safe_fromlist_for_each_entry_from 的安全版本
15.list_for_each_entry_safe_reverselist_for_each_entry_reverse 的安全版本

1.4 使用示例 - 測(cè)試 list.h 中所有的list操作

構(gòu)造如下場(chǎng)景,用來(lái)測(cè)試上述列出的所有的 list 操作:

1. 構(gòu)造用來(lái)測(cè)試的 struct:(為了使得測(cè)試結(jié)果一目了然,struct盡量簡(jiǎn)單)

struct test_struct {int num;    struct list_head head;};

2. 逐個(gè)函數(shù)進(jìn)行測(cè)試,使用測(cè)試框架 cppUTest

3. 宏 相關(guān)的暫時(shí)沒(méi)有測(cè)試

4. 運(yùn)行測(cè)試非常簡(jiǎn)單(前提是得安裝 cpputest)

make./test_list -v

2. rbtree 介紹1.1 簡(jiǎn)介

紅黑樹(shù)是一種自平衡的二叉搜索樹(shù)。紅黑樹(shù)是有序的。

注: 具體介紹可以我之前的博客參見(jiàn):http://www.CUOXin.com/wang_yb/archive/2013/04/16/3023892.html 中的 第4節(jié)

這里只補(bǔ)充一點(diǎn),紅黑樹(shù)雖然有些復(fù)雜,但是它的查找,插入,刪除操作的效率還不錯(cuò)。查找,插入,刪除的時(shí)間復(fù)雜度都是O(log n) n是樹(shù)中元素?cái)?shù)目

1.2 修改部分

為了是 rbtree 更加簡(jiǎn)單,暫時(shí)刪除了以下內(nèi)容:

  1. 刪除了函數(shù)指針的定義 typedef rb_augment_f
  2. 刪除了 rb_augment_insert
  3. 刪除了 rb_augment_erase_begin
  4. 刪除了 rb_augment_erase_end
  5. 刪除了 rb_link_node

1.3 rbtree.h 對(duì)外接口

注意: rbtree 的對(duì)外接口中沒(méi)有插入node的接口,只有在插入node之后改變node顏色的接口

可能是由于node的順序因具體struct而異,所以沒(méi)法統(tǒng)一實(shí)現(xiàn)

No.

主要 函數(shù)

說(shuō)明

1.rb_set_parent設(shè)置父節(jié)點(diǎn)的地址
2.rb_set_color設(shè)置節(jié)點(diǎn)顏色
3.rb_init_node初始化節(jié)點(diǎn)
4.rb_insert_color設(shè)置新插入節(jié)點(diǎn)的顏色
5.rb_erase刪除一個(gè)節(jié)點(diǎn)
6.rb_next返回當(dāng)前節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)
7.rb_prev返回當(dāng)前節(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn)
8.rb_first返回第一個(gè)葉子節(jié)點(diǎn)(也就是最左邊的葉子節(jié)點(diǎn))
9.rb_last返回最后一個(gè)葉子節(jié)點(diǎn)(也就是最右邊的葉子節(jié)點(diǎn))
10.rb_replace_node替換rbtree中的一個(gè)node(只是簡(jiǎn)單的替換,沒(méi)有管替換的顏色對(duì)不對(duì),數(shù)據(jù)的順序?qū)Σ粚?duì))

No.

主要 宏

說(shuō)明

1.rb_parent獲取父節(jié)點(diǎn)的地址
2.rb_color節(jié)點(diǎn)的顏色
3.rb_is_red是否紅節(jié)點(diǎn)
4.rb_is_black是否黑節(jié)點(diǎn)
5.rb_set_red設(shè)置節(jié)點(diǎn)為紅色
6.rb_set_black設(shè)置節(jié)點(diǎn)為黑色
7.RB_ROOT初始化根節(jié)點(diǎn)
8.rb_entry獲取包含rbtree node的struct
9.RB_EMPTY_ROOT判斷是否只有根節(jié)點(diǎn)
10.RB_EMPTY_NODE判斷節(jié)點(diǎn)是否剛初始化,還沒(méi)有加到樹(shù)中
11.RB_CLEAR_NODE設(shè)置節(jié)點(diǎn)的父節(jié)點(diǎn)也指向自己

1.4 rbtree.c 補(bǔ)充說(shuō)明

rbtree.c 中函數(shù)都比較簡(jiǎn)單,比較復(fù)雜的是 rb_insert_color 和 rb_erase

這2個(gè)函數(shù)還涉及其它未公開(kāi)的函數(shù) __rb_rotate_left, __rb_rotate_right, __rb_erase_color

1. __rb_rotate_left : 左旋,即,以參數(shù) node 為中心點(diǎn),逆時(shí)針旋轉(zhuǎn)。左旋可以調(diào)整右子樹(shù)的高度

下面的4副圖演示了左旋時(shí),struct rb_node 的 left 和 right 指針的變化。

下圖是最復(fù)雜的一種情況,即所有相關(guān)節(jié)點(diǎn)的左右子樹(shù)不為空的情況

rbtree-rotate-left

2. __rb_rotate_right : 右旋,即,以參數(shù) node 為中心點(diǎn),順時(shí)針旋轉(zhuǎn)。右旋可以調(diào)整左子樹(shù)的高度

下面的4副圖演示了右旋時(shí),struct rb_node 的 left 和 right 指針的變化。

下圖是最復(fù)雜的一種情況,即所有相關(guān)節(jié)點(diǎn)的左右子樹(shù)不為空的情況

rbtree-rotate-right

3. rb_erase : 刪除節(jié)點(diǎn),調(diào)用 __rb_erase_color 調(diào)整顏色

下圖演示刪除節(jié)點(diǎn)時(shí),struct rb_node 的 left 和 right 指針的變化。

下圖是最復(fù)雜的一種情況,即所有相關(guān)節(jié)點(diǎn)的左右子樹(shù)不為空的情況

rbtree-erase

4. __rb_erase_color : 刪除節(jié)點(diǎn)后,調(diào)整被刪除節(jié)點(diǎn)后節(jié)點(diǎn)的顏色

被刪除節(jié)點(diǎn) A 的位置由被刪除節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn) B(即被刪除節(jié)點(diǎn)的右子樹(shù)中最左的節(jié)點(diǎn))替換。

調(diào)整的顏色就是 B 節(jié)點(diǎn)的 child 和 parent

刪除時(shí)各種情況的分析參見(jiàn):http://zh.wikipedia.org/wiki/紅黑樹(shù)

5. rb_insert_color : 設(shè)置新插入節(jié)點(diǎn)的顏色,調(diào)整rbtree的平衡

插入的位置需要自己定義,這個(gè)函數(shù)只是調(diào)整插入后節(jié)點(diǎn)的顏色

插入時(shí)各種情況的分析參見(jiàn):http://zh.wikipedia.org/wiki/紅黑樹(shù)

1.5 使用示例

構(gòu)造如下場(chǎng)景,用來(lái)測(cè)試上述列出的所有的 rbtree 操作:

1. 構(gòu)造用來(lái)測(cè)試的 struct:(為了使得測(cè)試結(jié)果一目了然,struct盡量簡(jiǎn)單)

struct test_struct {    int num;    struct rb_node node;};

2. 逐個(gè)函數(shù)進(jìn)行測(cè)試,使用測(cè)試框架 cppUTest

3. 宏 相關(guān)的暫時(shí)沒(méi)有測(cè)試

4. 運(yùn)行測(cè)試非常簡(jiǎn)單(前提是得安裝 cpputest)

make./test_rbtree -v

相關(guān)測(cè)試代碼下載


上一篇:安裝 tomat

下一篇:文件操作

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 广丰县| 阳高县| 汉寿县| 孝昌县| 白玉县| 安龙县| 杨浦区| 习水县| 科技| 衡南县| 邢台县| 德惠市| 赤城县| 桑日县| 丹江口市| 定州市| 岐山县| 驻马店市| 宜春市| 喜德县| 台北市| 乌审旗| 平陆县| 吐鲁番市| 奉新县| 宜兴市| 垣曲县| 若羌县| 崇明县| 稻城县| 仁化县| 临邑县| 咸宁市| 彝良县| 象州县| 辽源市| 开化县| 东乡| 桑植县| 五家渠市| 尉犁县|