1. 程式人生 > >linux核心學習中--"list.h" del move splice 函式理解

linux核心學習中--"list.h" del move splice 函式理解

第三篇部落格,主要是針對刪除,移動,合併函式的理解,很簡單的,相信大家一看就明白了。

static inline void __list_del(struct list_head * prev, struct list_head * next)     //刪除結點。刪除連結串列中prev與next之間的元素
{
        next->prev = prev;
        prev->next = next;
}

static inline void list_del(struct list_head *entry)               //刪除一個結點entry,並將刪除結點地址置為0
{                                                     
        __list_del(entry->prev, entry->next);
        entry->next = LIST_POISON1;  //指標清除0
        entry->prev = LIST_POISON2;  //指標清除0
}





static inline void list_del_init(struct list_head *entry)      //從連結串列中刪除元素entry,並將其初始化為新的連結串列。

{
        __list_del(entry->prev, entry->next);
        INIT_LIST_HEAD(entry);        //初始化就是把指標指向自己                       
}

static inline void list_move(struct list_head *list, struct list_head *head) //將該結點摘除並插入到連結串列頭部
{
        __list_del(list->prev, list->next);
        list_add(list, head);
}

static inline void list_move_tail(struct list_head *list,    //將該結點摘除並插入到連結串列尾部部
                                  struct list_head *head)
{
        __list_del(list->prev, list->next);
        list_add_tail(list, head);
}

static inline int list_empty(const struct list_head *head)        //測試連結串列是否為空
{
        return head->next == head;
}

static inline int list_empty_careful(const struct list_head *head)   
{
        struct list_head *next = head->next;
        return (next == head) && (next == head->prev);
}
/*
基本的list_empty()僅以頭指標的next是否指向自己來判斷連結串列是否為空,Linux連結串列另行提供了一個list_empty_careful()巨集,
它同時判斷頭指標的next和prev,僅當兩者都指向自己時才返回真。
這主要是為了應付另一個cpu正在處理同一個連結串列而造成next、prev不一致的情況。
但程式碼註釋也承認,這一安全保障能力有限:除非其他cpu的連結串列操作只有list_del_init(),否則仍然不能保證安全,也就是說,還是需要加鎖保護。
*/
static inline void __list_splice(struct list_head *list,             //合併連結串列, 將連結串列list與head合併。
                                 struct list_head *head)
{
        struct list_head *first = list->next;
        struct list_head *last = list->prev;
        struct list_head *at = head->next;

        first->prev = head;
        head->next = first;

        last->next = at;
        at->prev = last;
}

/**
* list_splice - join two lists
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice(struct list_head *list, struct list_head *head) //list不為空的情況下,呼叫__list_splice()實現list與head的合併
{
        if (!list_empty(list))
                __list_splice(list, head);
}

/**
* list_splice_init - join two lists and reinitialise the emptied list.
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* The list at @list is reinitialised
*/
static inline void list_splice_init(struct list_head *list,       //將兩連結串列合併,並將list初始化。
                                    struct list_head *head)
{
        if (!list_empty(list)) {
                __list_splice(list, head);
                INIT_LIST_HEAD(list);
        }
}