日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux内核计算list的长度,Linux内核通用链表 linux/list.h阅读

發布時間:2025/3/12 linux 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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阅读的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。