Linux内核链表剖析

来源:互联网 发布:湖北航天信息开票软件 编辑:程序博客网 时间:2024/05/01 21:31

        Linux内核链表的存放路径是 /include/linux/list.h 任何有安装Linux系统的机器上都可以轻易找到。

        Linux内核中有很多用的很经典的数据结构,链表就算其中之一。其他的还有队列,哈希查找,红黑树查找等等。 内核链表的设计很经典,就连很多开发内核的黑客们都觉得内核中链表的设计是他们引以自豪的一部分。

        采用Linux内核链表的设计有两大优点两种:1是可扩展性,2是封装。可扩展性肯定是必须的,内核一直都是在发展中的,所以代码都不能写成死代码,要方便修改和追加。将链表常见的操作都进行封装,使用者只关注接口,不需关注实现。


以下是Linux内核链表的源码,分析稍后慢慢补充

#ifndef __DLIST_H#define __DLIST_H#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)#define container_of(ptr, type, member) \(\{\        const typeof( ((type *)0)->member ) *__mptr = (ptr);\        (type *)( (char *)__mptr-offsetof(type,member) );})/* These are non-NULL pointers that will result in page faults * under normal circumstances, used to verify that nobody uses * non-initialized list entries. */#define LIST_POISON1  ((void *) 0x00100100)#define LIST_POISON2  ((void *) 0x00200)struct list_head {struct list_head *next; struct list_head *prev;};#define LIST_HEAD_INIT(name) { &(name), &(name) }#define LIST_HEAD(name) \struct list_head name = LIST_HEAD_INIT(name)#define INIT_LIST_HEAD(ptr) \do\{ \(ptr)->next = (ptr); \(ptr)->prev = (ptr); \}while (0)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_add(struct list_head *new, struct list_head *head){__list_add(new, head, head->next);}static inline void list_add_tail(struct list_head *new, struct list_head *head){__list_add(new, head->prev, head);}static inline void __list_del(struct list_head *prev, struct list_head *next){next->prev = prev;prev->next = next;}static inline void list_del(struct list_head *entry){__list_del(entry->prev, entry->next);entry->next = (void *) 0;entry->prev = (void *) 0;}static inline void list_del_init(struct list_head *entry){__list_del(entry->prev, entry->next);INIT_LIST_HEAD(entry);}static inline void list_move(struct list_head *list,struct list_head *head){__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_del(list->prev, list->next);list_add_tail(list, head);}static inline int list_empty(struct list_head *head){return head->next == head;}static inline void __list_splice(struct list_head *list,struct list_head *head){struct list_head *first = list->next;struct list_head *last = list->prev;struct list_head *at = head->next;first->prev = head;head->next = first;last->next = at;at->prev = last;}static inline void list_splice(struct list_head *list, struct list_head *head){if (!list_empty(list))__list_splice(list, head);}static inline void list_splice_init(struct list_head *list,struct list_head *head){if (!list_empty(list)) {__list_splice(list, head);INIT_LIST_HEAD(list);}}#define list_entry(ptr, type, member) \((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))#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; 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)#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_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))#endif


0 0
原创粉丝点击