Kernel macro definition Chain list
struct list_head{ struct list_head *next,*prev;}
Linked List declaration
#define LIST_HEAD_INIT(name) {&(name),&(name)}================================================1.静态初始化#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)================================================= LIST_HEAD(list_name); ==> struct list_head list_name = LIST_HEAD_INIT(name);==> struct list_head list_name = {&(list_name), &(list_name)}; //相当于给一个结构声明加初始化,让list_name的成员变量 //【next,prev】 = {&(list_name), &(list_name)}2.运行时初始化stattic inline void INIT_LIST_HEAD(struct list_head *list){ list->next = list; list->prev = list;}
Whether the linked list is empty
static inline int list_empty(const struct list_head* head){ return head->next == head;}
Linked list insertion
1.插入head后static inline void list_add(struct list_head* new, struct list_head* head){ __list_add(new, head, head->next);}2.插入head->prev后static inline void list_add_tail(struct list_head* new, struct list_head* head){ __list_add(new, head->prev, head);}
Delete
static inline void list_replace_init(struct list_head *old, struct list_head *new){ list_replace(old,new); INIT_LIST_HEAD(old);}
Traverse
#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) ); }#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
Note : Why this can be achieved, with the C language feature is very related to C, in the given structure, the member's offset at compile time is fixed.
遍历链表:宏:list_for_each()#define list_for_each(pos, head) for (pos = (head)->next, prefetch(pos->next); pos != (head); pos = pos->next, prefetch(pos->next))pos是迭代指针,指向当前访问的链表头。head是要访问的链表的链表头。结合list_entry使用,就可以访问链表头所在元素了。list_for_each(p,&elem_list){ f = list_entry(p, struct elem, list);}更简单使用:宏:list_for_each_entry(pos,head,member)
Some of the macros in Linux