最基本的定义:
struct list_head
{
struct list_head *next, *prev;
};
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member)*__mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })
通过指针ptr, 获取对应的结构体指针。其中member是typeof中的指针。ptr就是指向member。
#define list_for_each_entry(pos, head, member) list_for_each_entry_safe(pos, pos, head, member)
#define list_for_each(pos, head) for (pos = (head)->next; prefetch(pos->next), pos != (head); pos = pos->next)
上面的不但获取到写一个list_head,并且通过list_entry获取到list对应的结构体。
下面的pos则直接是head->next的类型,在Linux内核中一般是list_head类型。
#define list_for_each_safe(pos, n, head) for (pos = (head)->next, n = pos->next; pos != (head); pos = n, n = pos->next)
#define list_for_each_entry_safe(pos, n, head, member)
\
for (pos = list_entry((head)->next, typeof(*pos), member),
\
n = list_entry(pos->member.next, typeof(*pos), member);
&pos->member != (head); pos = n, n = list_entry(n->member.next, typeof(*n), member))
该宏则通过n保存了pos对应的下一个对象,当在有删除操作时删除了当前节点还可以通过next继续遍历下去。其实在只要找到一个节点的时候完全没有必要这个n节点。