码迷,mamicode.com
首页 > 其他好文 > 详细

list_for_each_entry

时间:2016-08-03 23:58:27      阅读:375      评论: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
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!