리눅스상에서 여러가지 구조체가 존재한다. 이런 모든 구조체가 거의 double linked list로 관리되어 지는데, 각 구조체 마다 이를 삽입/수정/삭제 등을 위한 함수를 만드는 것은 낭비이다. 이러한 낭비를 없애기 위해서
struct list_head
{
struct list_head *next;
struct list_head *prev;
}
인 구조체를 만들어서 전체적으로 관리한다.
이런 경우 필요한 구조체를 찾아내기 위한 값이 필요하다.
찾고자 하는 구조체의 주소를 알아 내기 위한 매크로 함수를 만들어라....
원형은
get_entry(member의 주소, type, member)
직접 짠 소스
[code type=c]#include <stdio.h>
struct x
{
int a;
int b;
};
#define get_entry(address, type, member) \
(type *)((unsigned int)address - ( (unsigned int)&((type *)0)->member ))
int main(void)
{
struct x ss = {10, 20};
struct x *temp;
temp = get_entry(&ss.b, struct x, b);
printf("a = %d, b = %d\n", temp->a, temp->b);
return 0;
}[/code]
출력물
a = 10, b = 20
실제 리눅스 코드에서 사용하는 방법
http://lxr.linux.no/source/include/linux/sched.h에서
1004 #define next_task(p) list_entry((p)->tasks.next, struct task_struct, tasks)
1005 #define prev_task(p) list_entry((p)->tasks.prev, struct task_struct, tasks)
http://lxr.linux.no/source/include/linux/list.h#L320
[code type=c]314 /**
315 * list_entry - get the struct for this entry
316 * @ptr: the &struct list_head pointer.
317 * @type: the type of the struct this is embedded in.
318 * @member: the name of the list_struct within the struct.
319 */
320 #define list_entry(ptr, type, member) \
321 container_of(ptr, type, member)
http://lxr.linux.no/source/include/linux/kernel.h#L243
243 #define container_of(ptr, type, member) ({ \
244 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
245 (type *)( (char *)__mptr - offsetof(type,member) );})[/code]
받은 트랙백이 없고,
댓글이 없습니다.



글
댓글을 달아 주세요
댓글 RSS 주소 : http://www.cipher.pe.kr/tt/cipher/rss/comment/122댓글 ATOM 주소 : http://www.cipher.pe.kr/tt/cipher/atom/comment/122