概述
编解码内核驱动,会调用到list_for_each_entry来遍历。
1、#define list_for_each_entry(pos, head, member)
for (pos = list_entry((head)->next, typeof(*pos), member);
&pos->member != (head);
pos = list_entry(pos->member.next, typeof(*pos), member))
我们将for循环分解为一下三点:
(1) for循环初始化 pos = list_entry((head)->next, typeof(*pos), member);
:从for循环的结构上可以看出pos是控制for循环的一个变量,但不是我们常用的int类型而是指针。
:#define list_entry(ptr, type, member) container_of(ptr, type, member)
1)const typeof( ((type *)0)->member ) *__mptr = (ptr); (type *)( (char *)__mptr - offsetof(type,member) )
(type *)0是一个强转的操作,将0强行装换成type类型的指针。这个地址(0x0000)指向的是类型type的数据
注意:32bit系统 为0x0000, 64bit系统 为0x00000000,这里已32bit为例子。64bit同理。
指针就是刚才通过0强转的地址。所以也就是相当于地址0x0000 是结构体类型type的首地址,
通过->取其中的成员变量member。
2) const typeof( ((type *)0)->member ) *__mptr = (ptr) 定义指针
(type *)0)->member的作用就是得到成员变量member后,再通过typeof((type *)0)->member),就知道
member成员 的类型了。
:定义一个指针变量__mptr,指向的类型是member的类型,其初始化为ptr的值。
ptr是container_of(ptr, type, member)的第一个参数。
3) (type *)( (char *)__mptr - offsetof(type,member) );
__mptr是上面定义的member成员类型的指针,初始化为ptr,offsetof(type,member)是求出
member在结构体中的偏移量,其中type是结构体的类型。
(char *)__mptr - offsetof(type,member)就是__mptr - offset,即member类型的指针减去member结构体中的偏量。
一般__mptr = ptr,ptr是member的地址,那么member的地址减去member在结构体中偏移量不就是得
到结构体的地址了吗。
container_of的作用很明显了 -- 获得结构体的地址。那么我们需要给他提供三个参数,
分别是:ptr:member成员的 指针type:结构体类型 member:成员member的名字。
这样我们就能通过container_of(ptr, type, member)的返回值,得到结构体的地址。
(2)for循环执行条件 &pos->member != (head);
prefetch(pos->member.next),&pos->member!= (head);
prefetch的含义是告诉cpu那些元素有可能马上就要用到,告诉cpu预取一下,这样可以提高速度,
用于预取以提高遍历速度; &pos->member !=(head) ,这个判断循环条件。
(3)每循环一次执行 pos = list_entry(pos->member.next, typeof(*pos), member))
逐项向后(next 方向)移动 pos。
最后
以上就是腼腆鸵鸟为你收集整理的视频编解码(十三):list_for_each_entry列表总结的全部内容,希望文章能够帮你解决视频编解码(十三):list_for_each_entry列表总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复