Linux内核链表的研究与应用(4)

3检测是否为最后结点
1>function:
判断一个结点是不是链表head的最后一个结点。

2>linux内核函数接口
static inline int list_empty(const struct list_head  *list, const struct list_head *head )
{
 return  list->next == head;
}
如果结点的后继为头结点,则说明此结点为最后一个结点。

4.检测链表中是否只有一个结点
1>function:
函数是用来判断head这个链表是不是只有一个成员结点(不算带头结点的那个head),是则返回1,否则返回0.

2>函数接口:
static inline int list_is_singular(const struct list_head *head)

3>函数实现:
static inline int list_is_singular(const struct list_head *head)
{
    return !list_empty(head) && (head->next == head->prev);
}
首先判断链表是否为空,如果非空则判断

5.链表的旋转
1>function:
这个函数把head后的第一个结点放到最后位置。

2> 函数接口:
static inline  void list_rotate_left(struct list_head *head)
3>lis_rotate_left函数实现
static inline void list_rotate_left(struct list_head *head)
{
        struct list_head *first;


        if (!list_empty(head)) {
                first = head->next;
                list_move_tail(first, head);
        }
 }
List_rotate_left函数每次将头结点后的一个结点放到head链表的末尾,直到head结点后没有其他结点。

6.分割链表
1>function:
函数将head(不包括head结点)到entry结点之间的所有结点截取下来添加到list链表中。该函数完成后就产生了两个链表head和list

2>函数接口:
static inline void list_cut_position(struct list_head *list,struct list_head *head,struct list_head *entry)
 list: 将截取下来的结点存放到list链表中
 head: 被剪切的链表
 entry: 所指位于由head所指的链表内。它是分割线,entry之前的结点存放到list之中。Entry之后的结点存放到head链表中。

3>list_cut_position函数实现:
static inline void list_cut_position(struct list_head *list,
                  struct list_head *head, struct list_head *entry)
{
        if (list_empty(head))
                return;
        if (list_is_singular(head) &&
                (head->next != entry && head != entry))
                return;
        if (entry == head)
                INIT_LIST_HEAD(list);
        else
                __list_cut_position(list, head, entry);
}
函数进行了判断:
(1)head链表是否为空,如果为空直接返回不进行操作。否则进行第二步操作
(2)head是否只有一个结点,如果只有一个结点则继续判断该结点是否是entry,如果不是entry则直接返回。(即head链表中没有entry结点则返回,不进行操作)
(3)如果entry指向head结点,则不进行剪切。直接将list链表初始化为空.
(4)判断完后,调用__list_cut_position(list,head,entry)函数完成链表剪切。

4>__list_splice函数:
(1)功能:函数将head(不包括head结点)到entry结点之间的所有结点截取下来添加到list链表。将entry之后的结点放到head链表中。
(2)函数接口:
static  inline void __list_cut_position(struct list_head *list, struct list_head *head, struct list_head *entry)
(3)__list_cut_position函数实现
static  inline void __list_cut_position(struct list_head *list, struct list_head *head, struct list_head *entry)
{
        struct list_head *new_first = entry->next;
        list->next = head->next;
        list->next->prev = list;
        list->prev = entry;
        entry->next = list;
        head->next = new_first;
        new_first->prev = head;
}

函数实现过程见图:

起始:

Linux内核链表的研究与应用

函数执行完:

Linux内核链表的研究与应用


说明:list_cut_position只是添加了一些条件判断,真正的操作是在__list_cut_position函数中完成。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/55d44a25386278bfb811a0069ff678d9.html