2011. 10. 11. 23:04
container_of 매크로 OS이야기2011. 10. 11. 23:04
http://lxr.linux.no/linux+v3.0.4/include/linux/kernel.h#L645
#define container_of(ptr, type, member) ({ \
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0->member) * __mptr = (ptr); \
(type *) ( (char *)__mptr - offsetof(type,member)); })
구조체의 멤버의 주소를 알면 구조체의 시작주소를 알 수 있다. 즉, 구조체를 구할 수 있다.
(type *)0->member에서 '0'은 가상 구조체를 말한다.
member의 타입을 받아서 ( const typeof() ) __mptr 에 그 구조체의 멤버 주소를 넣는다.( __mptr = (ptr))
상대주소에서 - 절대주소를 빼면 구조체의 시작주소를 알 수 있따.
__mptr - offsetof(type, member)
%모르는 것 %
왜 리턴 값이 구조체의 시작주소를 리턴하는지 모르겠다.
예)
struct task_struct *task;
struct list_head *list;
list_for_each(list, ¤t->children)
{
(type *) ( (char *)__mptr - offsetof(type,member)); })
구조체의 멤버의 주소를 알면 구조체의 시작주소를 알 수 있다. 즉, 구조체를 구할 수 있다.
(type *)0->member에서 '0'은 가상 구조체를 말한다.
member의 타입을 받아서 ( const typeof() ) __mptr 에 그 구조체의 멤버 주소를 넣는다.( __mptr = (ptr))
상대주소에서 - 절대주소를 빼면 구조체의 시작주소를 알 수 있따.
__mptr - offsetof(type, member)
%모르는 것 %
왜 리턴 값이 구조체의 시작주소를 리턴하는지 모르겠다.
예)
struct task_struct *task;
struct list_head *list;
list_for_each(list, ¤t->children)
{
task = list_entry(list, struct task_struct, sibling);
}
#define list_for_each( pos, head) \
for( pos = (head) - > next; pos != (head); pos = pos->next)
%설명
typeof(struct task_struct *0->sibling) *__mptr = list;
list - offsetof(stuct task_struct, sibling);
sibling의 타입은 struct list_head 일 것이다.
(검색해보니 struct list_head sibling)
#define list_for_each( pos, head) \
for( pos = (head) - > next; pos != (head); pos = pos->next)
%설명
typeof(struct task_struct *0->sibling) *__mptr = list;
list - offsetof(stuct task_struct, sibling);
sibling의 타입은 struct list_head 일 것이다.
(검색해보니 struct list_head sibling)