linux deepin内核头文件解析(一)——list.h

代码文件deepin15.10/include/list.h


linux内核提供了一个双向链表数据结构,同时包括一系列接口。

在list.h里包含的头文件linux/types.h里找到了链表结构体的定义:

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

形象一点的逻辑结构可以表示为:

奇怪的是居然没有数据域(一般的链表包括两个部分,一个是数据域,也就是存放数据的部分,和指针域,用来存放其他节点地址的部分,可能后面还有蹊跷,慢慢往后研究)

结构体里包含两个成员,两个成员都是list_head的指针。分别指向这一节点的前驱(prev)和后继(next)。

在list.h文件里定义的第一个宏

#define LIST_HEAD_INIT(name) { &(name), &(name) }

这个宏定义初看很难懂,LIST_HEAD_INIT()函数传入一个叫name的变量,函数的功能是取变量name的地址。从函数名看出这是链表的初始化。但看了第二句宏定义就豁然开朗了。

#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)

在这句里宏定义一个函数LIST_HEAD,函数创建一个链表节点name,并且将name的前驱和后继都指向自己。

下面声明了第一个函数:

static inline void INIT_LIST_HEAD(struct list_head *list)
{
	WRITE_ONCE(list->next, list);
	list->prev = list;
}

目前我还不清楚这个函数和前一个宏定义的具体区别,是让list链表的前驱和后继都指向list自己。函数WRITE_ONCE()定义在include/linux/compiler.h里(这个函数涉及编译时的内存操作,和后面的READ_ONCE()一样都是为了cpu读取和访问内存时候的操作安全)

下面的代码都是在Debug模式下检查链表有效性的:

#ifdef CONFIG_DEBUG_LIST
extern bool __list_add_valid(struct list_head *new,
			      struct list_head *prev,
			      struct list_head *next);
extern bool __list_del_entry_valid(struct list_head *entry);
#else
static inline bool __list_add_valid(struct list_head *new,
				struct list_head *prev,
				struct list_head *next)
{
	return true;
}
static inline bool __list_del_entry_valid(struct list_head *entry)
{
	return true;
}
#endif

文件之后定义了一系列操作链表节点的接口,逐一看。

static inline void __list_add(struct list_head *new,
			      struct list_head *prev,
			      struct list_head *next)
{
	if (!__list_add_valid(new, prev, next))
		return;

	next->prev = new;
	new->next = next;
	new->prev = prev;
	WRITE_ONCE(prev->next, new);
}

这个函数传递三个参数,分别是插入节点的地址,插入位置的前后节点的地址:

比如调用函数_list_add(&new, &(n), &(n+1)),执行结果是在节点n和节点n+1之间插入节点new:

第一步:节点n+1的prev指向节点new的地址0x06f

第二步:节点new的next指向节点n+1的地址0x00a

第三步:节点n的next指向节点new,节点new的prev指向节点n


未完。。。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值