在阅读Linux 内核以及驱动的时候,经常会见到这么一个宏"list_for_each_entry()",或者"list_for_each_entry_xxx()",如果不理解就验证影响代码的理解。拖了很久,这次下决心分析明白,一分析发现实际上很容易理解。
list_for_each_entry() 宏,主要有两个宏,list_first_entry, list_next_entry,加一个for循环组成。而这两个宏核心部分是container_of(),这个宏。
一、所以我们首先分析container_of()这个宏。这个宏在Linux里面非常常见,它的意思可以简单理解为,“根据一个成员变量的地址,获取这个结构体的首地址”。
如果把宏展开的话,那么这个宏看着很吓人,但是实际上表达的意思很浅显,那就是,成员变量的地址减去成员变量的相对偏移,就等于结构体变量的首地址。
二、list_first_entry,看下图,head->next 的值是 S0->List->next 地址,那这个宏可以简化为container_of(&S0->List->next, Type, List),
那意思就是获取S0的首地址,跟字面意思一样,获取这个列表的第一个成员地址。list_next_entry(),这个宏我就不展开了,那肯定是下一个列表成员的首地址了。
三、最后我们综合起来看一下 list_for_each_entry 这个宏。首先我们必须知道这个链表的结构,看下图。
实际上看完这个图,我想大家已经基本搞懂了,我在把这个宏一步一步拆分
最后一步化简结果相信大家清洗了吧,实际上就是一个普通的遍历。因为用了一种特殊的链表,所以遍历的对象稍微特殊一点而已。
因为我不善于描述,所以尽量用图表和代码去阐述。