linux核心學習中--"list.h" del move splice 函式理解
阿新 • • 發佈:2019-02-15
第三篇部落格,主要是針對刪除,移動,合併函式的理解,很簡單的,相信大家一看就明白了。
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); } }