首页 / 操作系统 / Linux / Linux内核通用链表 <linux/list.h>阅读
#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() * or list_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; }