linux内核计算list的长度,Linux内核通用链表 linux/list.h阅读
#ifndef _LINUX_LIST_H
#define _LINUX_LIST_H //宏定義,不做過多解釋,就是檢查是否包含了linux/list.h
#ifdef __KERNEL__
#include
#include
#include
/*
* 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;
}
總結
以上是生活随笔為你收集整理的linux内核计算list的长度,Linux内核通用链表 linux/list.h阅读的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 音频功放类型与结构
- 下一篇: 语音信号处理之(一)动态时间规整(DTW