小張學linux核心之資料結構 1 hlist

2021-10-06 13:49:14 字數 1441 閱讀 2539

閱讀linux原始碼時,經常會遇到hlist的使用,hlist,看名稱是雜湊鍊錶的意思,那我們學過hash表,是將一串長的資料物件對映到乙個陣列中,已陣列下標來訪問它所對應的資訊。

在學習linux字元驅動時,也接觸到雜湊桶的知識。相同主裝置號對應乙個hash表的槽位,子裝置號則是這個槽位所掛的鍊錶上的id(linux2.6的核心中;linux3.*後的核心字元型裝置不再用雜湊桶來儲存)。那這個hlist是像字元裝置中所用到的雜湊鍊錶嗎?我們來一**竟。

include/linux/types.h中定義

struct hlist_head ;

struct hlist_node ;

頭節點和普通節點結構體不同,這樣是為了節省雜湊表的儲存空間,通常雜湊表會比較大,這樣頭部只有乙個指標,而不是兩個指標,節省了一半的空間

圖示:

取自pprev不同於普通的list,pprev指向前乙個節點的next。

為何用二級指標,我們知道二級指標改變指標的指向。

同意煉表頭head和儲存節點node。

這樣做的好處:

由於頭結點和其他節點的型別不一致,這樣就不能使用普通的prev指標指向前乙個節點(否則處理的時候還要討論是否是第乙個節點,沒有通用性),這裡設計者的巧妙之處就是pprev指標指向前乙個節點的next,統一了後續所有的節點。可以通過本節點來改變上乙個節點的next指標,這樣就不用遍歷時迭代指標往回移動,提公升效率。

include/linux/list.h中

//插入

static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)

/* next must be != null */

static inline void hlist_add_before(struct hlist_node *n,

struct hlist_node *next)

static inline void hlist_add_behind(struct hlist_node *n,

struct hlist_node *prev)

//刪除

static inline void __hlist_del(struct hlist_node *n)

static inline void hlist_del(struct hlist_node *n)

//指向自己

static inline bool hlist_fake(struct hlist_node *h)

小張學linux核心 七 裝置樹的使用

在很久之前的版本,uboot還需要傳machine id和引數區位址給核心,但現在只傳遞裝置樹 fdt 的位址給核心了,這些引數全在fdt中做了。uboot將裝置樹bin檔案和kernel載入到記憶體,然後將fdt位址傳給kernel,跳到kernel位址執行。fdt為平坦裝置樹,即數作為乙個乙個節...

小張學linux核心 五 cfs排程類和rt排程類

今天我們來學習排程類cfs和rt排程類。簡述 cfs是絕對公平排程演算法,理想情況下,優先順序相同的兩個task,執行時間應該各佔cpu的50 同理3個則cpu利用率為1 3。但是cfs中弱化了優先順序的概念而是使用權重weight來決定任務的執行時間。例如 3個任務a,b,c權重分別1,2,3 則...

Linux核心資料結構

一 概述 linux核心提供了一些常用的資料結構並建議開發者盡量重用,而不需要再去實現一些類似的資料結構。這篇部落格主要描述一下linux核心提供的鍊錶 佇列 對映及二叉樹這四種常用資料結構。當然這裡提到的每一種資料結構要說清楚都需要不少的篇幅,而這篇博文只是簡要分析一下linux核心設計的理念,以...