Linux内核中的list_head

Posted 行远山

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux内核中的list_head相关的知识,希望对你有一定的参考价值。

一般我们想要实现一种数据结构的双链队列,一般都是这样操作:

  typedef struct Datastructure
{
    struct Datastructure *next;
    struct Datastructure *prev;
    //......
}datastructure;

然而在Linux内核中,使用了大量不同的数据结构的双链队列。
因此,内核作者们把指针prev和next从具体的宿主中抽象出来成为了一种数据结构list_head。

struct list_head
{
    struct list_head *next, *prev;
};

在其宿主结构中:

typedef struct page
{
    struct list_head list;
    //.......
    struct page *next_hash;
    //.......
    struct list_head lru;
};

数据结构之间的连接操作都通过list_head执行。
接着内核定义了如下的一个函数:
memlist_entry(cur, struct page, list);
这个函数将list_head的指针curr换算成了宿主结构的其实地址,也就是其宿主page结构的指针。
但事实上,同一文件中将memlist_entry定义为list_entry。
page = (struct page*)((char*)(curr) - (usigned long)(& (struct page*)0) -> list));
其中curr是page结构中成分list的地址,page本身的地址,通过curr减去一个位移量就能得出,而这个位移量,就是page刚好在地址0时其成分list的地址,既:
& (struct page*)0) -> list)

以上是关于Linux内核中的list_head的主要内容,如果未能解决你的问题,请参考以下文章

Linux list_head

双向循环链表list_head WRITE_ONCE READ_ONCE 函数的分析与使用

list链表

Android中的双向链表

Linux内核数据结构hlist_head

内核数据结构 内核链表分析