Linux核心原始碼——鏈表

來源:互聯網
上載者:User

       關於Linux核心代碼的真正接觸還是最近2個月,首先接觸這個最簡單的就是雙向鏈表了,這個鏈表可謂真的短小。原來有些時候,看這種經典代碼也是一種享受。在大學裡面寫的那些雙向鏈表那隻不過是學習而已。

 

 #ifndef _LINUX_LIST_H<br />#define _LINUX_LIST_H</p><p>#ifdef __KERNEL__</p><p>struct list_head {<br />struct list_head *next, *prev;<br />};</p><p>#define LIST_HEAD_INIT(name) { &(name), &(name) }</p><p>#define LIST_HEAD(name) /<br />struct list_head name = LIST_HEAD_INIT(name)</p><p>#define INIT_LIST_HEAD(ptr) do { /<br />(ptr)->next = (ptr); (ptr)->prev = (ptr); /<br />} while (0)</p><p>static __inline__ void __list_add(struct list_head * new,<br />struct list_head * prev,<br />struct list_head * next)<br />{<br />next->prev = new;<br />new->next = next;<br />new->prev = prev;<br />prev->next = new;<br />}</p><p>static __inline__ void list_add(struct list_head *new, struct list_head *head)<br />{<br />__list_add(new, head, head->next);<br />}</p><p>static __inline__ void list_add_tail(struct list_head *new, struct list_head *head)<br />{<br />__list_add(new, head->prev, head);<br />}</p><p>static __inline__ void __list_del(struct list_head * prev,<br /> struct list_head * next)<br />{<br />next->prev = prev;<br />prev->next = next;<br />}</p><p>static __inline__ void list_del(struct list_head *entry)<br />{<br />__list_del(entry->prev, entry->next);<br />}</p><p>static __inline__ void list_del_init(struct list_head *entry)<br />{<br />__list_del(entry->prev, entry->next);<br />INIT_LIST_HEAD(entry);<br />}</p><p>static __inline__ int list_empty(struct list_head *head)<br />{<br />return head->next == head;<br />}</p><p>static __inline__ void list_splice(struct list_head *list, struct list_head *head)<br />{<br />struct list_head *first = list->next;</p><p>if (first != list) {<br />struct list_head *last = list->prev;<br />struct list_head *at = head->next;</p><p>first->prev = head;<br />head->next = first;</p><p>last->next = at;<br />at->prev = last;<br />}<br />}</p><p>#define list_entry(ptr, type, member) /<br />((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))</p><p>#define list_for_each(pos, head) /<br />for (pos = (head)->next; pos != (head); pos = pos->next)</p><p>#endif /* __KERNEL__ */</p><p>#endif<br />

 

這些鏈表結構體只能在核心使用,但其實我們在平時寫鏈表時,可以仿照這樣,精簡。

如果我們需要某種資料結構的隊列,就在這種結構內部放上list_head結構即可。例如:

typedef struct page {

struct list_head list;

.....

struct list_head lru;

.... 

}page_t;

這裡面放了了2個list_head結構體(list和lru),這代表page結構體可以存在兩個隊列中,如下面圖所示:

 

在這鏈表裡面最關鍵的地方在

#define list_entry(ptr, type, member) /
 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))

通過它才可以訪問鏈表裡面真正的元素

例如:

list_head pstList;

struct page *page;

page = list_entry(pstList, struct page, list); 其中pstList 指向一個page結構體。

list_entry的原理的,通過這個結構體鏈表頭在結構體中的位移來擷取 某個結構體的地址。

(unsigned long)(&((type *)0)->member)),這個是擷取結構鏈表頭的位移值,如在page中,list位移page的值

然後再把該地址減去該位移才真正得到我們想要的結構體地址。

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.