본문 바로가기
Operating System

container_of 매크로 이해하기

by BestUgi 2018. 1. 12.
kobject는 그 자체만으로는 쓰임새가 없고 주로 다른 객체 안에 포함되서 사용된다. 대부분의 sysfs 관련 함수나 디바이스 드라이버 등에서 kobject의 포인터를 인자로 전달받아서 사용한다. 그래야 드라이버 작성자가 어떤 데이터 구조를 만들어서 사용해도 인터페이스는 통일될 수 있다. 그래서 kobject의 포인터에서 kobject가 속한 객체의 포인터를 계산하는 일이 많아지고 이를 위한 container_of 매크로가 만들어졌다.
예를 들어 커널 2.6.23에서 include/linux/cdev.h에는 다음과 같이 문자 장치를 표현하는
cdev 구조체가 선언되어 있다.


13 struct cdev {
14   struct kobject kobj;
15   struct module *owner;
16   const struct file_operations *ops;
17   struct list_head list;
18   dev_t dev;
19   unsigned int count;
20 };


만약 kobject의 주소가 kp라는 변수에 저장되어 있다면 container_of 매크로를 이용해서
cdev의 주소를 알 수 있다. 다음과 같이 사용된다.
 
struct cdev *device = container_of(kp, struct cdev, kobj); // kobject 타입의 kp(포인터)를 포함하는 cdev 구조체를 찾는다.


kp: kobject의 주소
struct cdev: kobject를 포함하는 구조체의 이름
kobj: kobject 필드의 변수 이름



다음은 container_of 매크로가 정의된 코드이다.


/**
 * container_of - cast a member of a structure out to the containing structure
 * @ptr:        the pointer to the member.
 * @type:       the type of the container struct this is embedded in.
 * @member:     the name of the member within the struct.
 *
 */
#define container_of(ptr, type, member) ({                      \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) );})



인용 : from 어셈러브

댓글