首页 > 其他 > 详细

list_for_each_entry

时间:2016-08-03 23:56:42      阅读:517      评论:0      收藏:0      [点我收藏+]

内核里面用list_for_each_entry实在太多了,定义在linux-3.10/include/linux/list.h:

 1 /**
 2  * list_for_each_entry    -    iterate over list of given type
 3  * @pos:    the type * to use as a loop cursor.
 4  * @head:    the head for your list.
 5  * @member:    the name of the list_struct within the struct.
 6  */
 7 #define list_for_each_entry(pos, head, member)                 8     for (pos = list_entry((head)->next, typeof(*pos), member);     9          &pos->member != (head);     10          pos = list_entry(pos->member.next, typeof(*pos), member))
11 
12 /**
13  * list_entry - get the struct for this entry
14  * @ptr:    the &struct list_head pointer.
15  * @type:    the type of the struct this is embedded in.
16  * @member:    the name of the list_struct within the struct.
17  */
18 #define list_entry(ptr, type, member) 19     container_of(ptr, type, member)

 

要分析list_entry就得分析container_of,linux-3.10/include/linux/kernel.h:

 1 /**
 2  * container_of - cast a member of a structure out to the containing structure
 3  * @ptr:    the pointer to the member.
 4  * @type:    the type of the container struct this is embedded in.
 5  * @member:    the name of the member within the struct.
 6  *
 7  */
 8 #define container_of(ptr, type, member) ({             9     const typeof( ((type *)0)->member ) *__mptr = (ptr);    10     (type *)( (char *)__mptr - offsetof(type,member) );})

宏定义的第一行:typeof(x)是gcc预处理,获取x的类型,这里((type *)0)->member利用p=0的指针指向相应结构体(type)的成员,typeof获取该成员的类型并定义__mptr。

第二行:#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER),跟第一行的((type *)0)->member一个样子,获取结构体(type)的偏移量,最后__mptr转换成(char *)减去自己在结构体(type)的偏移量得到结构体(type)的指针。

可以看出第一行在功能上是没有什么卵用,其实只是作为类型检测,实现一个给定成员类型(member)的指针(ptr)找到这个成员的结构体(type)功能的只在第二行。

 

返回看list_entry(ptr, type, member)其实就是通过ptr找到type。

再回到list_for_each_entry(pos, head, member)的实现可以知道,用list_head通过list_entry找到包含next list_head的结构体(pos)作为变量进行循环。可得要使用list_for_each_entry,struct pos里面的成员必须包含list_head。所以在linux里面的struct经常看到list_head这个成员就是这个道理

list_for_each_entry

原文:http://www.cnblogs.com/kevinhwang/p/5734022.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!