linux 内核链表

来源:互联网 发布:风力预报软件 编辑:程序博客网 时间:2024/05/16 16:15

linux内核中大量使用如下数据结构实现双向链表:

 

struct list_head {    struct list_head *next, *prev;};

  如果需要有某种数据结构的双向队列,就在这种结构内部放一个list_head数据结构成员。

struct kobject {    const char        *name;    struct list_head    entry;    struct kobject        *parent;    struct kset        *kset;

}

如何通过kobject 链表结构中的 list_head 成员entry访问下一个成员呢?

系统提供了宏list_entry:

#define list_entry(ptr, type, member) \         ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) 
//访问链表成员kobject
*obj = objList;kobject *nextObj = (kobject *)list_entry(obj->entry->next,struct kobject,entry);

这个list_entry是什么道理呢:

  ptr:是指向当前kobject结构对象中的数据成员entry,(char *)(ptr):entry成员地址 ——AddrA

  (unsigned long)(&((type *)0)->member)):将地址0转化为类型为type(struct kobject )对象,取member(entry)成员的地址——AddrB

  (type *)(AddrA - AddrB):得到kobject结构对象的首地址,转化为kobject对象。

 

  这里需要关注的就是AddrB:将地址0转化为类型为type(struct kobject )对象,取member(entry)成员的地址。

    表示当struct kobject 对象首地址为0时,得到成员member(entry)的地址,相对首地址的偏移地址。

    通过struct kobject 对象中member(entry)的地址 ,以及相对首地址的偏移量,就能计算出struct kobject 对象的首地址。



list_add_tail(&dev->devlist, &devlist);   // 将new所代表的list_head插入head所索引的队列的尾部
0 0