linux內核鏈表的使用

注意這個鏈表只能在驅動程序中使用spa

定義struct list_head {指針

     struct list_head *prev;blog

     struct list_head *next;io

};變量

初始化鏈表:遍歷

#define LIST_HEAD_INIT(name)  { &name, &name}程序

#define LIST_HEAD(name) \
    struct list_head name = LIST_HEAD_INIT(name)im

static struct list_head LIST_HEAD_INIT(head);d3

就初始化了一個鏈表頭爲head的雙鏈表鏈表

或者使用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(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(new,head)是將new添加到head後面,應該叫插入head後面

若是要加入鏈尾,使用list_add_tail

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;
}

鏈表的刪除:

static inline void list_del(struct list_head *entry)
{
 __list_del(entry->prev, entry->next);
 entry->next = LIST_POISON1;
 entry->prev = LIST_POISON2;
}

static inline void __list_del(struct list_head * prev, struct list_head * next)
{
 next->prev = prev;
 prev->next = next;
}

刪除了entry這個鏈表

鏈表的移動:將list節點加到head後面

static inline void list_move(struct list_head *list, struct list_head *head)
{
 __list_del_entry(list);
 list_add(list, head);
}

static inline void __list_del_entry(struct list_head *entry)
{
 __list_del(entry->prev, entry->next);
}

static inline void __list_del(struct list_head * prev, struct list_head * next)
{
 next->prev = prev;
 prev->next = next;
}

鏈表的遍歷:

#define list_for_each_entry(pos, head, member)    \
 for (pos = list_entry((head)->next, typeof(*pos), member); \
      &pos->member != (head);  \
      pos = list_entry(pos->member.next, typeof(*pos), 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)); })

container_of()實現了根據一個已知結構體成員的指針和變量名得出宿主結構體的地址的功能

list_entry用於獲取struct list_head結構體指針所在結構體變量的首地址

list_first_entry用於獲取鏈表中第一個節點所在結構體的首地址

如圖:

相關文章
相關標籤/搜索