您的位置:首页 > 运维架构 > Linux

linux中container_of(ptr, type, member)

2015-10-10 10:48 375 查看
在linux下很多地方使用了list_entry(链表结构实现), rb_entry(红黑树实现), sb_entry(文件系统实现)之类的结构,原因是因为linux内核在实现链表,红黑树这一类基本的数据结构的时候都是最简单化的实现,如果要使用这些基本数据结构,就需要在自己定义的数据结构中包含这类最基本的数据结构。

而我们在使用中往往需要返回包含这类基本数据结构的大结构本身,这时候我们就需要用到list_entry,rb_entry这些宏的实现,而这些宏本身却都是基于一个叫container_of的宏的实现,其解释如下:

#define container_of(ptr, type,
member)
({                  \
const typeof(
((type
*)0)->member
) *__mptr
= (ptr);    \
(type *)(
(char
*)__mptr
- offsetof(type,member)
);})
#define
offsetof(TYPE, MEMBER)
((size_t)
&((TYPE
*)0)->MEMBER)

它的作用是:设ptr是某个type类型结构中的member成员变量的地址,该宏的结果是得到该type的地址。即有结构中成员变量的地址得到结构的地址。
1.ptr为物理地址,其类型和member类型一致,最终使用typeof(
((type
*)0)->member
)

由编译器自动返回member的类型

2.type为包含member成员的结构体

3.offsetof(type,member)为member成员在type结构体中的偏移值,大小范围0~sizeof(type)字节
(因为以0地址为type类型数据结构的起始地址)

4.ptr-
offsetof()就等于包含该ptr的type结构体父变量的物理起始地址,强制转换为(type*).

5.
((size_t)
&((TYPE
*)0)->MEMBER)表示当结构TYPE为0时其成员MEMBER的地址,即位移量。
关于linux内核中的链表数据结构,推荐看一篇文章:
《
深入分析 Linux 内核链表》,文章链接是:
http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/

注:转载出自:http://blog.chinaunix.net/uid-24549279-id-71354.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: