码迷,mamicode.com
首页 > 系统相关 > 详细

Linux Kernel:  container_of 黑科技

时间:2016-05-01 21:39:22      阅读:363      评论:0      收藏:0      [点我收藏+]

标签:

 1 #include<stdio.h>
 2 
 3 #define offsetof(TYPE,MEMBER)  ((size_t)&((TYPE*)0)->MEMBER)
 4 
 5 #define container_of(ptr,type,member) ({       6     const typeof( ((type*)0)->member ) *__mptr = (ptr);   7     (type *)( (char *)__mptr - offsetof(type,member) );})
 8 
 9 
10 #define list_entry(ptr,type,member) 11     container_of(ptr,type,member)
12 
13 struct MyStruct {
14     int i_1;
15     int i_2;
16     int i_3;
17     int i_4;
18     int i_5;
19     int i_6;
20     int i_7;
21     int i_8;
22     int i_9;
23     int i_a;
24     int i_b;
25     int i_c;
26     int i_d;
27     int i_e;
28     int i_f;
29     int i_g;
30     int i_h;
31     int i_j;
32 };
33 
34 int main()
35 {
36     struct MyStruct Test = { 0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18};
37     printf("Just a test: Test->i_1: %d\n",Test.i_1);
38     int *ptr = &(Test.i_2);
39     printf("Now we got i_2: %d \n",*ptr);
40     struct MyStruct *struct_ptr = container_of(ptr,struct MyStruct,i_2);
41     printf("Now we got struct\n");
42     printf("Test.i_3 is: %d \n",struct_ptr->i_3);
43 
44     return 0;
45 }

由一个struct里的member(成员)的指针得到这个struct的指针,从而可以得到这个struct的其他成员。

通过这种方法,Linux内部就不需要维护一个task_struct的双向链表了,只需要维护task_struct里面的某个成员的双向链表,效果等同于一个task_struct的双向链表。这样就可以节省空间。而通过上面的黑科技,有可以达到双向链表的效果,一举两得。

(task_struct是Linux Kernel内部用来描述一个process/thread的struct,维护一个task_struct的双向链表是因为要从一个进程得到其子进程、父进程、兄弟进程......)

可以看出其实这个黑科技之所以能实现主要是因为gcc那个 typeof 操作符......

 

 

 

 

 

 

 

 

:)

 

Linux Kernel:  container_of 黑科技

标签:

原文地址:http://www.cnblogs.com/blog-of-walker/p/5451090.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!