知识点滴

知识是一点一滴地积累的

 

Double-list的泛型C实现

linux内核中有一个核心的泛型数据结构list_head,它是一个双链表,大部分的linux内核数据结构都是基于它建立的。

list_head结构很简单:

struct list_head{

    struct list_head *prev;

    struct list_head *next;

};

你如果需要定义自己的双链表结构,可以把它嵌入到你的结构中而进行重用:

struct fox{

    int val;

    struct list_head list;

};

这样带来的好处是你可以使用为list_head实现的很多链表操作函数如list_addlist_deletelist_replace以及list_for_each等,从而省去了很多你自己需要实现的链表操作代码。例如下面的例子:

void main(){

    struct fox f1, f2, f3, *f;

    struct list_head *list;

 

    f1.val = 1;

    f2.val = 2;

    f3.val = 3;

 

    INIT_LIST_HEAD(&f1.list);

    list_add(&f2.list, &f1.list);

    list_add(&f3.list, &f2.list);

    __list_for_each(list, &f1.list){

       f = list_entry(list, struct fox, list);

       printf("%d\t", f->val);

    }

}

能重用的关键是我们需要能够从list_head中取出自己定义的结构fox,毕竟所有的链表操作都是基于list_head进行的,如:

/*

 * Insert a new entry between two known consecutive entries.

 *

 * This is only for internal list manipulation where we know

 * the prev/next entries already!

 */

void __list_add(struct list_head *new_node, struct list_head *prev, struct list_head *next){

    next->prev = new_node;

    new_node->next = next;

    new_node->prev = prev;

    prev->next = new_node;

}

/**

 * list_add - add a new entry

 * @new: new entry to be added

 * @head: list head to add it after

 *

 * Insert a new entry after the specified head.

 * This is good for implementing stacks.

 */

void list_add(struct list_head *new_node,    struct list_head *head){

    __list_add(new_node, head, head->next);

}

要从list_head中取出父结构struct fox,在C语言中可以通过获取list_head在结构fox中的偏移,然后把list_head指针减去那个偏移(内存是从小到大放置对象的):

unsigned long offset = (unsigned long)(&((struct fox *)0)->list);

struct fox *f = ((struct fox *)((char *)list - offset);

上面可以通过定义宏container_of进行简化:

#define container_of(ptr, type, member)         \

    ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))

#define list_entry(ptr, type, member) \

    container_of(ptr, type, member)

有些编译器支持offsetof宏,如gcc,这样可以简化container_of的编写。



posted on 2011-07-10 15:02  阿东  阅读(1271)  评论(0编辑  收藏  举报

导航