当前位置:文档之家› Linux内核通用链表 linuxlist.h阅读

Linux内核通用链表 linuxlist.h阅读

Linux内核通用链表 <linux/list.h>阅读2008-10-23 22:43#ifndef _LINUX_LIST_H#define _LINUX_LIST_H //宏定义,不做过多解释,就是检查是否包含了linux/list.h#ifdef __KERNEL__#include <linux/stddef.h>#include <linux/prefetch.h>#include <asm/system.h>/** 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 *) 0x00200200)/** Simple doubly linked list implementation.** Some of the internal functions ("__xxx") are useful when* manipulating whole lists rather than single entries, as* sometimes we already know the next/prev entries and we can* generate better code by using them directly rather than* using the generic single-entry routines.*/entry似乎应该翻译成表或者节点。

简单的双向链表实现:一些内部函数在熟练操作整个链表比单个入口更有用,当我们已经知道next/prev入口,通过使用直接它们比使用一般的单入口程序产生更好的代码。

struct list_head {struct list_head *next, *prev;};#define LIST_HEAD_INIT(name) { &(name), &(name) }#define LIST_HEAD(name) \struct list_head name = LIST_HEAD_INIT(name)如果一开始没有看懂LIST_HEAD_INIT宏定义的话,上面这个应该可以让人豁然开朗,初始化一个name链表,让头和尾都指向自己。

#define INIT_LIST_HEAD(ptr) do { \(ptr)->next = (ptr); (ptr)->prev = (ptr); \} while (0)/** Insert a new entry between two known consecutive entries.** This is only for internal list manipulation where we know* the prev/next entries already!*/在已知的连续节点中间插入一个新的节点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 - add a new entry* @new: new entry to be added* @head: list head to add it after** Insert a new entry after the specified head.* This is good for implementing stacks.*/在制订head节点之后插入一个新的节点,这个适用于栈static inline void list_add(struct list_head *new, struct list_head *head){__list_add(new, head, head->next);/*** list_add_tail - add a new entry* @new: new entry to be added* @head: list head to add it before** Insert a new entry before the specified head.* This is useful for implementing queues.*/在指定节点前插入一个新节点,适用于队列static inline void list_add_tail(struct list_head *new, struct list_head *head){__list_add(new, head->prev, head);}/** Insert a new entry between two known consecutive entries.** This is only for internal list manipulation where we know* the prev/next entries already!*/此函数仅供内置链表操作,就是只用于此头文件中所有的关于链表操作的函数就是要已知 prev/next 节点static inline void __list_add_rcu(struct list_head * new,struct list_head * prev, struct list_head * next){new->next = next;new->prev = prev;smp_wmb();next->prev = new;prev->next = new;}/*** list_add_rcu - add a new entry to rcu-protected list* @new: new entry to be added* @head: list head to add it after** Insert a new entry after the specified head.* This is good for implementing stacks.* The caller must take whatever precautions are necessary* (such as holding appropriate locks) to avoid racing* with another list-mutation primitive, such as list_add_rcu()* or list_del_rcu(), running on this same list.* However, it is perfectly legal to run concurrently with* the _rcu list-traversal primitives, such as* list_for_each_entry_rcu().*/调用必须提供任何的必要的防范措施(比如固定适当的锁)来避免在运行于同一个链表时和另一个原始的链表操作竞争,比如 list_add_rcu() * orlist_del_rcu(), 但是和_rcu 原始的链表遍历同时运行是完全合法的。

static inline void list_add_rcu(struct list_head *new, struct list_head *head){__list_add_rcu(new, head, head->next);}/*** list_add_tail_rcu - add a new entry to rcu-protected list* @new: new entry to be added* @head: list head to add it before** Insert a new entry before the specified head.* This is useful for implementing queues.** The caller must take whatever precautions are necessary* (such as holding appropriate locks) to avoid racing* with another list-mutation primitive, such as list_add_tail_rcu() * or list_del_rcu(), running on this same list.* However, it is perfectly legal to run concurrently with* the _rcu list-traversal primitives, such as* list_for_each_entry_rcu().*/static inline void list_add_tail_rcu(struct list_head *new,struct list_head *head){__list_add_rcu(new, head->prev, head);}/** Delete a list entry by making the prev/next entries* point to each other.* This is only for internal list manipulation where we know* the prev/next entries already!*/看不懂此函数可以看下面就明白了,删除已知节点,需要知道节点的后继和前趋static inline void __list_del(struct list_head * prev, struct list_head * next){next->prev = prev;prev->next = next;}/*** list_del - deletes entry from list.* @entry: the element to delete from the list.* Note: list_empty on entry does not return true after this, the entry is* in an undefined state.*/static inline void list_del(struct list_head *entry){__list_del(entry->prev, entry->next);entry->next = LIST_POISON1;entry->prev = LIST_POISON2;}常规的方法是entry->next 置空,这里做什么为了什么还有待于参考。

相关主题