内核中链表的使用非常广泛,这里将linux/list.h中的部分,也是最常用的宏定义给总结了。
Pro-III、内核链表:
1、定义+初始化:
#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;
}
2、添加:
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{//[prev]--[new]--[next]
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
static inline void list_add(struct list_head *new, struct list_head *head)
{//将new添加到链表头
__list_add(new, head, head->next);
}
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{//将new添加到链表尾
__list_add(new, head->prev, head);
}
3、删除:
static inline void __list_del(struct list_head * prev, struct list_head * next)
{//[prev]--[del]--[next]
next->prev = prev;
prev->next = next;
}
static inline void list_del(struct list_head *entry)
{//彻底删除
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1; //指向无效地址
entry->prev = LIST_POISON2;
}
static inline void list_del_init(struct list_head *entry)
{//删除+初始化
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
4、移动:
static inline void list_move(struct list_head *list, struct list_head *head)
{//将list移到链表最前
__list_del(list->prev, list->next);
list_add(list, head);
}
static inline void list_move_tail(struct list_head *list,
struct list_head *head)
{//将list移到链表最后
__list_del(list->prev, list->next);
list_add_tail(list, head);
}
5、判断:
static inline int list_is_last(const struct list_head *list,
const struct list_head *head)
{//list是否为最后一个
return list->next == head;
}
static inline int list_empty(const struct list_head *head)
{//链表是否为空
return head->next == head;
}
6、得到结构体:
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
//得到MEMBER和TYPE结构体地址之间的差值
#define container_of(ptr, type, member) ({ /
const typeof( ((type *)0)->member ) *__mptr = (ptr); /
//定义一个和membe变量类型一样的指针__mptr
(type *)( (char *)__mptr - offsetof(type,member) );})
//显然type结构体的地址肯定比member变量的地址低
//于是减去它们的差值就得到真实type结构体的地址
#define list_entry(ptr, type, member) /
container_of(ptr, type, member)
//得到type结构体的地址
#define list_first_entry(ptr, type, member) /
list_entry((ptr)->next, type, member)
//得到链表中第一个节点指针
7、遍历链表:
#define list_for_each(pos, head) /
for (pos = (head)->next; prefetch(pos->next), pos != (head); /
pos = pos->next)
//prefetch是预取内存的内容,程序员告诉CPU哪些内容可能马上用到,CPU预取,用于优化。
#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)
//向前遍历链表
#define list_for_each_safe(pos, n, head) /
for (pos = (head)->next, n = pos->next; pos != (head); /
pos = n, n = pos->next)
//安全遍历,容许有删除操作发生
//设想,假设采用list_for_each(pos,head),如果将pos给删除了
//那么pos=pos->next这条语句就有问题了,pos->next指向一个
//非法的位置(list_del)或者指向了自己(del_del_init),这怎么能容许
//第一种情况在第二次会直接出错,因为pos= LIST_POISON1(非法指针)
//第二种情况直接死循环,因为pos初始化时将next设置为自己了
#define list_for_each_prev_safe(pos, n, head) /
for (pos = (head)->prev, n = pos->prev; /
prefetch(pos->prev), pos != (head); /
pos = n, n = pos->prev)
//向前的安全遍历
#define list_for_each_entry(pos, head, member) /
for (pos = list_entry((head)->next, typeof(*pos), member); /
prefetch(pos->member.next), &pos->member != (head); /
pos = list_entry(pos->member.next, typeof(*pos), member))
//在遍历的过程中直接使用结构体指针
#define list_for_each_entry_reverse(pos, head, member) /
for (pos = list_entry((head)->prev, typeof(*pos), member); /
prefetch(pos->member.prev), &pos->member != (head); /
pos = list_entry(pos->member.prev, typeof(*pos), member))
//向前遍历
#define list_for_each_entry_continue(pos, head, member) /
for (pos = list_entry(pos->member.next, typeof(*pos), member); /
prefetch(pos->member.next), &pos->member != (head); /
pos = list_entry(pos->member.next, typeof(*pos), member))
//同样是遍历,但是这里的pos是已经存在的结构体指针,也就是可以从任何节点开始遍历
#define list_for_each_entry_safe(pos, n, head, member) /
for (pos = list_entry((head)->next, typeof(*pos), member), /
n = list_entry(pos->member.next, typeof(*pos), member); /
&pos->member != (head); /
pos = n, n = list_entry(n->member.next, typeof(*n), member))
//安全遍历
#define list_for_each_entry_safe_continue(pos, n, head, member) /
for (pos = list_entry(pos->member.next, typeof(*pos), member), /
n = list_entry(pos->member.next, typeof(*pos), member); /
&pos->member != (head); /
pos = n, n = list_entry(n->member.next, typeof(*n), member))
//安全遍历,并且可以任意节点遍历