内核链表list.h---把函数功能记下来,不用忘记了每次都要分析代码

文件中描述的是一个双向链表的定义和操作。

(1)结构定义和初始化

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

//每个链表有一个head,它是一个开始标志,链表的第一个元素是head->next

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

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

static inline void INIT_LIST_HEAD(struct list_head *list) //初始化双向链表为空链表
{
	list->next = list;
	list->prev = list;
}


例如:

struct MyList
{
struct list_head list;
int data;
};

struct MyList mylist1;        //定义一个
INIT_LIST_HEAD(&mylist1.list);  //初始化双向链表为空链表


 

(2)插入操作

void __list_add(struct list_head *new,
			      struct list_head *prev,
			      struct list_head *next)   //将new插入到prev和next之间

void list_add(struct list_head *new, struct list_head *head) //将new插入到head链表的首部
void list_add_tail(struct list_head *new, struct list_head *head) //将new插入到head链表的尾部


 

(3)删除操作

__list_del(struct list_head * prev, struct list_head * next) //将prev和next之间的元素删除
void list_del(struct list_head *entry) //在链表中删除元素entry(元素entry脱离链表)
void list_del_init(struct list_head *entry) //在链表中删除元素entry(元素entry脱离链表并初始化为空链表)


(4)替换操作

void list_replace(struct list_head *old, 	struct list_head *new) //将元素new替换old
void list_replace_init(struct list_head *old, struct list_head *new) //将元素new替换old,并将old初始化为空链表。


(5)移动操作

void list_move(struct list_head *list, struct list_head *head) //将list从一个链表中删除,并把它加入到head链表的首部。
void list_move_tail(struct list_head *list, struct list_head *head) //将list从一个链表中删除,并把它加入到head链表的尾部。
void list_cut_position(struct list_head *list,struct list_head *head, struct list_head *entry)//entry是head链表中的元素,list是另一个链表。将entry之前(包含entry)的元素剪切出来入到list中(list链表的首部)。
__list_splice(const struct list_head *list, struct list_head *prev, struct list_head *next) //将链表list加入到另一个链表元素prev和next之间。
void list_splice(const struct list_head *list,struct list_head *head)//将链表list加入到head链表(head链表首部)。
void list_splice_tail(struct list_head *list,struct list_head *head)//将链表list加入到head链表的尾部。
void list_splice_init(struct list_head *list,struct list_head *head) //和list_splice_init功能一样,但初始化list为空.
void list_splice_tail_init(struct list_head *list, struct list_head *head) //和list_splice_tail功能一样,但初始化list为空.


(6)判断

int list_is_last(const struct list_head *list,const struct list_head *head)//判断list是否是head链表的最后一个元素
int list_empty(const struct list_head *head)//判断链表是否为空
int list_empty_careful(const struct list_head *head) //判断链表是否为空,排除另一个CPU在修改它
int list_is_singular(const struct list_head *head)//判断链表是否只有一个元素


(7)宏

list_entry(ptr, type, member) //得到链表所在的结构体(结构体类型为type)。
例:list_entry(&mylist1.list, struct MyList, list)它指向mylist1。

list_for_each(pos, head) //遍历head链表的所有元素,pos是一个游标。
如://统计链表中元素的个数
struct list_head *p;
int count = 0;
list_for_each(p, mylist1)
{
    ++count;
}

list_for_each_prev(pos, head) //反向遍历head链表的所有元素,pos是一个游标。

list_for_each_safe(pos, n, head) //功能和list_for_each (pos, head)相同,但当内部需要修改pos->next时(例如增加删除元素操作),使用这个更安全。

list_for_each_prev_safe(pos, n, head) //功能和list_for_each_prev(pos, head)相同,但当内部需要修改pos->prev时(例如增加删除元素操作),使用这个更安全。

list_for_each_entry(pos, head, member) //遍历所有定义struct list_head所在的结构体实体。
如:在结构struct MyList中定义了struct list_head list,那么要实现打印所有的data成员的数据的代码如下:
struct MyList *p;
list_for_each_entry(p, &mylist1.list, list)
{
    printf(“%d”, p->data);
}

list_for_each_entry_reverse(pos, head, member) //反向遍历所有定义struct list_head所在的结构体实体。

list_for_each_entry_continue(pos, head, member) //从pos位置开始遍历定义struct list_head所在的结构体实体。

list_prepare_entry(pos, head, member)  //如果pos不为空,则返回pos;如果为空,则返回链表头。这个宏用来给list_for_each_entry_continue参数pos初始化。

list_for_each_entry_continue_reverse(pos, head, member) // list_for_each_entry_continue的反向遍历

list_for_each_entry_from(pos, head, member) //从pos元素开始遍历定义struct list_head所在的结构体实体。

//以下安全访问函数,和上面的功能类型。消除修改prev和next带来的影响
list_for_each_entry_safe(pos, n, head, member)
list_for_each_entry_safe_continue (pos, n, head, member)
list_for_each_entry_safe_from(pos, n, head, member)
list_for_each_entry_safe_reverse(pos, n, head, member)


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值