Linux内核链表 ——list相关内容

1  链表数据结构的定义:

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

list_head结构包含两个指向list_head结构的指针prev和next,内核的链表具备双链表功能,实际上,通常它都组织成双循环链表。
这里的list_head没有数据域。在Linux内核链表中,不是在链表结构中包含数据,而是在数据结构中包含链表节点

2   声明和初始化链表

#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)
LIST_HEAD_INIT初始化链表 next、prev指针都为指向自己,因为Linux用头指针的next是否指向自己来判断链表是否为空:

static inline int list_empty(const struct list_head *head)
{
	return head->next == head;
}
3  宏定义操作


#define list_entry(ptr, type, member) /  
    container_of(ptr, type, member)  

#define container_of(ptr, type, member) ({                      /  
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    /  
        (type *)( (char *)__mptr - offsetof(type,member) );})  
先把0强制类型转换成为指向一个type型数据空间的指针,然后取其中的成员member,通过typeof得到这个成员member的类型,然后定义一个指向这个类型数据的指针命名为__mptr,并赋值为ptr;

把上面得到的__mptr减去成员member的偏移量,然后在强制类型转换成指向type型空间的指针,也就是地址,也就是得到了type类型的首地址,也就得到了一个指针,可以用它做“->”运算,得到其结构体中的任意一个值

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)  

先把0强制类型转换成为指向一个TYPE型数据的指针,然后取其中的MEMBER成员,再取它的地址,最后再强制类型转换成size_t型,就是unsigned long型,也就是MEMBER成员的地址,而该TYPE型数据的首地址为0,所以这个地址也就是MEMBER成员的偏移量,所以offsetof得到的是TYPE类型数据中成员MEMBER的地址偏移量

list_entry,ptr从一个结构的成员指针找到其容器的指针, ptr是找容器的那个变量的指针,把它减去自己在容器中的偏移量的值就应该 得到容器的指针。(容器就是包含自己的那个结构)

#define list_first_entry(ptr, type, member) /  
    list_entry((ptr)->next, type, member) 
它是调用了list_entry来定义的,就是找到ptr->next的地址,也就是第一节点的地址

下面给出一些定义,根据上面的内容很容易看懂

#define list_for_each(pos, head) /  
    for (pos = (head)->next; prefetch(pos->next), pos != (head); /  
            pos = pos->next)  
#define __list_for_each(pos, head) /  
    for (pos = (head)->next; pos != (head); pos = pos->next) 

#define list_for_each_prev(pos, head) /  
    for (pos = (head)->prev; prefetch(pos->prev), pos != (head); /  
            pos = pos->prev)  



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值