linux内核入门之list源码分析(2)

list_head的核心源代码都在<linux/list.h>文件中,该文件包含了主要的inline函数和宏.
下面的代码是一些关键函数和宏的分析.

struct list_head结构体:
struct list_head {
        struct list_head *next, *prev;
};

LIST_HEAD_INIT宏:
#define LIST_HEAD_INIT(name) { &(name), &(name) }

LIST_HEAD宏:
#define LIST_HEAD(name) \
        struct list_head name = LIST_HEAD_INIT(name)
        
LIST_HEAD(list)宏展开后相当于
struct list_head list = { &list, &list}
用于定义一个纯粹的list_head节点
         +-> +----------+ <-+                                               
         +---|  prev    |   |                                               
             +----------+   |                                               
             |  next    |---+                                               
             +----------+                                                   
                 list                                                       

list_add函数:
/**
 * list_add - 添加新链表项
 * @new: 要添加的新项
 * @head: 将新项添加到head之后
 *
 * 将新表项插入到指定的head之后.
 * 使用它实现Stack是非常有用的.
 */
static inline void list_add(struct list_head *new, struct list_head *head)
{
        __list_add(new, head, head->next);
}

list_add_tail函数:
/**
 * list_add_tail - 添加新链表项
 * @new: 要添加的新项
 * @head: 将新表项添加到head之后
 *
 * 将新表项插入到指定的head之前.
 * 使用它实现Queue是非常有用的.
 */
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
        __list_add(new, head->prev, head);
}

__list_add函数:
/**
 * 在两个连续的链表项之间加入一个新项
 *
 * 这个函数仅于链表内部处理,且prev和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;
}                 
     +-----------+        +------------+       +------------+               
     |   prev    |<-------|   prev     |<------|    prev    |               
     +-----------+        +------------+       +------------+               
     |   next    |------->|   next     |------>|    next    |               
     +-----------+        +------------+       +------------+               
         prev                 new                   next                    


list_del函数:
/**
 * list_del - 从链表中删除项
 * @entry: 被删除的元素
 * 注意: 在此函数之后,在entry上调用list_empty()不会返回true, entry处于未知状态
 */
static inline void list_del(struct list_head *entry)
{
        __list_del(entry->prev, entry->next);
        entry->next = LIST_POISON1;//LIST_POISON1表示一种未知的指针
        etnry->prev = LIST_POISON2;//LIST_POISON2同上
}

LIST_POISON1和LIST_POISON2定义在<linux/poison.h>文件中:
#define LIST_POISON1 ((void *) 0x00100100 + POISON_POINTER_DELTA)
#define LIST_POISON2 ((void *) 0x00200200 + POISON_POINTER_DELTA)

list_del_init函数:
/**
 * list_del_init - 从链表中删除项,并重新初始化这个项
 * @entry: 从链表中删除的元素
 */
static inline void list_del_init(struct list_head *entry)
{
        __list_del(entry->prev, entry->next);
        INIT_LIST_HEAD(entry);
}

INIT_LIST_HEAD函数:
/**
 * INIT_LIST_HEAD - 将list的prev和next指向自身
 */
static inline void INIT_LIST_HEAD(struct list_head *list)
{
        list->next = list;
        list->prev = list;
}

__list_del函数:
/**
 * 通过使prev/next指针指向彼此来删除一个链表项
 *
 * 这个仅用于链表内部处理,且prev/next项都是已知的.
 */
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
        next->prev = prev;
        prev->next = next;
}

list_replace函数:
/**
 * list_replace - 用新节点替换旧节点
 * @old: 被替换的旧元素
 * @new: 新元素
 */
static inline void list_replace(struct list_head *old,
                                struct list_head *new)
{
        new->next = old->next;
        new->next->prev = new;/*将old->next节点指向new*/
        new->prev = old->prev;
        new->prev->next = new;/*将old->prev节点指向new*/
}                             
   

list_move函数:
/**
 * list_move - 将一个表中的项移到另一个表头
 * @list: 移动的链表项
 * @head: 链表头
 */
static inline void list_move(struct list_head *list, struct list_head *head)
{
        __list_del(list->prev, list->next);/*从表中删除*/
        list_add(list, head);/*添加到表头*/
}

list_empty函数:
/**
 * list_empty - 测试链表是否为空
 * @head: 测试链表表头
 */
static inline int list_empty(const struct list_head *head)
{
        return head->next == head;
}

list_is_last函数:
/**
 * list_is_last - 测试list是否为head表的尾节点
 * @list: 测试节点
 * @head: 测试链表表头
 */
static inline int list_is_last(const struct list_head *list,
                                const struct list_head *head)
{
        return list->next == head;
}

list_rotate_left函数:
/**
 * list_rotate_left - 将链表元素循环左移
 * @head: 链表表头
 */
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_splice函数:
/**
 * list_splice - 连接两个链表, 它为Stack而设计
 * @list: 要添加的的新链表
 * @head: 将第一个list添加到head之后
 */
static inline void list_splice(const struct list_head *list,
                                struct list_head *head)
{
        if (!list_empty(list))
                __list_splice(list, head, head->next);
}                              

list_splice_tail函数:
/**
 * list_splice_tail - 连接两个链表, 它为Queue设计
 */
static inline void list_splice_tail(struct list_head *list,
                                struct list_head *head)
{
        if (!list_empty(list))
                __list_splice(list, head->prev, head);
}                                        

__list_splice函数:
/**
 * __list_splice - 将list拼接到prev和next链表项之间
 *
 * 注意: 拼接时不包含list表头
 */
static inline void __list_splice(const struct list_head *list,
                                struct list_head *prev,
                                struct list_head *next)
{
        struct list_head *first = list->next;
        struct list_head *last = list->prev;
        
        first->prev = prev;
        prev->next = first;
        
        last->next = next;
        next->prev = last;
}                                
                             

list_entry宏:
/**
 * list_entry - 获取包含此链表项的结构体
 * @ptr: 指向结构体内的list_head成员的指针
 * @type: 嵌入此链表项的结构体类型
 * @member: list_head在结构体中的名称
 */
#define list_entry(ptr, type, member) \
        container_of(ptr, type, member)

container_of宏:
该宏定义在<linux/kernel.h>中
#define container_of(ptr, type, member) ({                      \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type, member) );})

typeof(x)获取x数据类型
offsetof(type, memeber)获取member在type中的偏移量

结构体的地址 = 某成员地址 - 该成员在结构体中的偏移量
        +-----------+<----- mptr - offsetof(type, member)                                     
        |           |  |                                                   
        |    ...    |  |offsetof(type, member)                                             
        |           |  |                                                   
        +-----------+<----- mptr                                            
        |   member  |                                                      
        +-----------+                                                      
        |    ...    |                                                      
        +-----------+                  

list_for_each宏:
/**
 * list_for_each - 遍历一个链表
 * @pos: 循环游标,指向每次遍历的节点
 * @head: 链表的头节点
 */
#define list_for_each(pos, head) \
        for (pos = (head)->next; prefetch(pos->next), pos != (head); \
                pos = pos->next)
prefech试图将pos->next存放到CPU L1缓存中,有利于下次快速获取.
        
       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值