一点真实的上下文说得更清楚,下面以红黑树为例,这是我理解的方式container_of。
如前所述Documentation/rbtree.txt,在 linux 内核代码中,它不是 rb_node 包含数据条目,而是
rbtree 树中的数据节点是包含 struct rb_node 成员的结构。
struct vm_area_struct(在文件中include/linux/mm_types.h:284)就是这样一个结构,
在同一个文件中,有一个宏rb_entry定义为
#define rb_entry(ptr, type, member) container_of(ptr, type, member)
显然,rb_entry与 相同container_of。
在mm/mmap.c:299内部函数定义browse_rb中,有一个用法rb_entry:
static int browse_rb(struct mm_struct *mm)
{
/* two line code not matter */
struct rb_node *nd, *pn = NULL; /*nd, first arg, i.e. ptr. */
unsigned long prev = 0, pend = 0;
for (nd = rb_first(root); nd; nd = rb_next(nd)) {
struct vm_area_struct *vma;
vma = rb_entry(nd, struct vm_area_struct, vm_rb);
/* -- usage of rb_entry (equivalent to container_of) */
/* more code not matter here */
现在很清楚,在container_of(ptr, type, member),
type是容器结构,这里struct vm_area_struct
member是type实例成员的名称,此处vm_rb为 ,类型为rb_node,
ptrmember是一个指向type实例的指针,这里rb_node *nd.
做container_of什么是,就像在这个例子中一样,
- 给定
obj.member(此处obj.vm_rb)的地址,返回 的地址obj。
- 由于结构是一块连续的内存,减号
的地址将是容器的地址。
obj.vm_rboffset between the struct and member
include/linux/kernel.h:858 -- 定义container_of
include/linux/rbtree.h:51 -- 定义rb_entry
mm/mmap.c:299 -- 用法rb_entry
include/linux/mm_types.h:284 --struct vm_area_struct
Documentation/rbtree.txt: -- 红黑树的文档
include/linux/rbtree.h:36 -- 定义struct rb_node
附言
以上文件为当前开发版本,即4.13.0-rc7.
file:k表示 中的第 k 行file。