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;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 下一页

相关内容