linux内核链表的使用
注意这个链表只能在驱动程序中使用
定义struct list_head {
struct list_head *prev;
struct list_head *next;
};
初始化链表:
#define LIST_HEAD_INIT(name) { &name, &name}
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
static struct list_head LIST_HEAD_INIT(head);
就初始化了一个链表头为head的双链表
或者使用LIST_HEAD(head) ;一步到位
添加链表:
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
经过我的分析:list_add(new,head)是将new添加到head后面,应该叫插入head后面
如果要加入链尾,使用list_add_tail
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
链表的删除:
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(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}
删除了entry这个链表
链表的移动:将list节点加到head后面
static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del_entry(list);
list_add(list, head);
}
static inline void __list_del_entry(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
}
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}
链表的遍历:
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
#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)); })
container_of()实现了根据一个已知结构体成员的指针和变量名得出宿主结构体的地址的功能
list_entry用于获取struct list_head结构体指针所在结构体变量的首地址
list_first_entry用于获取链表中第一个节点所在结构体的首地址
如图: