zoukankan      html  css  js  c++  java
  • linux内核链表

    位置
    linux-2.6.32.9/include/linux/list.h

    1. 新建

    #define LIST_HEAD_INIT(name)      { &(name), &(name) }
    
    #define LIST_HEAD(name)      struct list_head name = LIST_HEAD_INIT(name)
    static inline void INIT_LIST_HEAD(struct list_head *list)
    {
        list->next = list;
        list->prev = list;
    }

    2. 插入

    //头
    static inline void list_add(struct list_head *new, struct list_head *head)  
    //尾
    static inline void list_add_tail(struct list_head *new, struct list_head *head)     
    static inline void list_add(struct list_head *new, struct list_head *head)
    {
        __list_add(new, head, head->next);
    }
    
    static inline void list_add_tail(struct list_head *new, struct list_head *head)
    {
        __list_add(new, head->prev, head);
    }
    
    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;
    }

    3. 删除

    static inline void list_del(struct list_head *entry);
    //prev:被删除结点的前驱结点; next:被删除结点后驱结点
    static inline void __list_del(struct list_head * prev, struct list_head * next) 
    static inline void list_del(struct list_head *entry)
    {
        __list_del(entry->prev, entry->next);
        entry->next = LIST_POISON1;
        entry->prev = LIST_POISON2;
    }
    
    /*
     * These are non-NULL pointers that will result in page faults
     * under normal circumstances, used to verify that nobody uses
     * non-initialized list entries.
     */
    翻译:
    在正常环境下,这个非空指针将会引起页错误(通常所说的缺页中断)。可被用来验证没有初始化的链表节点
    
    static inline void __list_del(struct list_head * prev, struct list_head * next)
    {
        next->prev = prev;
        prev->next = next;
    }

    4. 移动

    //先将list节点从原链表中删除,然后将其添加到head链表的表头
    static inline void list_move(struct list_head *list, struct list_head *head);
    //先将list节点从原链表中删除,然后将其添加到head链表的表尾
    static inline void list_move_tail(struct list_head *list, struct list_head *head);

    5. 合并

    //将list链表的全部节点(头节点list除外)插入在prev和next节点之间
    static inline void __list_splice(const struct list_head *list, struct list_head *prev, struct list_head *next)
    //在list是非空链表的情况下,将其插在head链表的头部,即head节点的后面
    static inline void list_splice(const struct list_head *list, struct list_head *head)

    6. 遍历

    //container_of有三个参数, ptr是成员变量的指针, type是指结构体的类型, member是成员变量的名字
    #define list_entry(ptr, type, member)   container_of(ptr, type, member)
    #define container_of(ptr, type, member)     ({ const typeof( ((type *)0)->member ) *__mptr = (ptr); 
                            (type *)( (char *)__mptr - offsetof(type,member) );})
    //利用传入的pos作为循环指针,从表头head开始,逐项向后移动pos,直至又回到head
    #define list_for_each(pos, head) 
            for (pos = (head)->next, prefetch(pos->next); pos != (head); 
            pos = pos->next, prefetch(pos->next)) 
    /**
    * list_for_each_entry - iterate over list of given type
    * @pos:        the type * to use as a loop cursor.
    * @head:       the head for your list.
    * @member:     the name of the list_struct within the struct.
    */
    #define list_for_each_entry(pos, head, member) 
            for (pos = list_entry((head)->next, typeof(*pos), member); 
                 prefetch(pos->member.next), &pos->member != (head); 
                 pos = list_entry(pos->member.next, typeof(*pos), member))
    //用n先将下一个要遍历的节点保存起来,防止删除本节点后,无法找到下一个节点,而出现错误。删除节点用
    /**  
     * list_for_each_safe - iterate over a list safe against removal of list entry  
     * @pos:    the &struct list_head to use as a loop counter.  
     * @n:      another &struct list_head to use as temporary storage  
     * @head:   the head for your list.  
     */  
    #define list_for_each_safe(pos, n, head)   
        for (pos = (head)->next, n = pos->next; pos != (head);   
            pos = n, n = pos->next)  
    /**
    * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
    * @pos:        the type * to use as a loop cursor.
    * @n:          another type * to use as temporary storage
    * @head:       the head for your list.
    * @member:     the name of the list_struct within the struct.
    */
    #define list_for_each_entry_safe(pos, n, head, member) 
            for (pos = list_entry((head)->next, typeof(*pos), member), 
                    n = list_entry(pos->member.next, typeof(*pos), member); 
                 &pos->member != (head); 
                 pos = n, n = list_entry(n->member.next, typeof(*n), member))

    7. 空

    static inline int list_empty(const struct list_head *head)

    8. 最后节点

    static inline void list_is_last(struct list_head *list, struct list_head *head);

    举例

    //插入数据到有序链表
    
    typedef struct
    {
        int a;
        struct list_head list;
    }info_t;
    info_t g_info;
    
    struct list_head *node, *_node;
    
    if(list_empty(&g_info.list))
    {
        printk("empty..
    ");
        list_add(&new->list, &g_info->list);
        return 0;
    }
    
    list_for_each_entry_safe(node, _node, &g_info.list, list)
    {
        if(node->a <= new->a)
        {
            if(list_is_last(&node->list, &g_info.list))
            {
                printk("last..
    ");
                list_add(&new->list, &node->list);
                break;
            }
    
            if(new->a < _node->a)
            {
                printk("middle..
    ");
                list_add(&new->list, &node->list);
                break;
            }
    
            continue;
        }
        else
        {
            printk("first..
    ");
            list_add(&new->list, &g_info->list);
            break;
        }
    }

    参考:http://blog.csdn.net/lmjjw/article/details/9833025

  • 相关阅读:
    折半枚举(双向搜索)
    弹性碰撞
    集合的整数表示
    反转(开关问题)
    尺取法
    floor函数用法
    二分搜索
    4. 差分约束系统
    二叉树的表达式求值
    关于移动app开发的一些不错的站点
  • 原文地址:https://www.cnblogs.com/zhangxuechao/p/11709839.html
Copyright © 2011-2022 走看看