Wednesday, August 21, 2013

[reference] list_head


이런 offset 매크로 정의 하나만 놓고 본다면 별 쓸모가 없을 것 같네요. 이런
표현을 조금 응용하면 꽤 유용한 것이 나옵니다. Linux 커널에서 사용하는list_head라는게 있는데, 이런 표현과 유사한 방법을 사용하지요. 아시는 분도많이 계시겠지만 간단히 소개를 드리겠습니다. 우선 구조체 정의는 다음과같습니다

(linux/list.h):

struct list_head 
{    struct list_head *next, *prev;};

뭐.. 별거 없습니다. 그리고 offset을 구하는 식을 다음과 같이 사용하고있습니다

(linux/list.h):


#define list_entry(ptr, type, member) \    ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))


자.. 이제 모든 리스트를 관리하는데 있어서, list_head 구조체 한가지만 있으면되는 세상이 열리게 되는거지요. 태스크리스트, 소켓버퍼리스트, 버스리스트 등몽땅 list_head 포인터로 선언해 버리고 list_head 관련 함수로 삽입, 삭제, 정렬등의 리스트 관리를 합니다. 그리고 해당 리스트 엔트리의 내용을 참조, 혹은업데이트할 필요가 있을때는 list_entry 매크로로 언제든지 엔트리의 포인터를다시 만들어 낼 수 있는 것이지요. list_head를 사용하는 다음과 같은 구조체가있다고 할때

(linux/timer.h):

struct timer_list {    struct list_head list;    unsigned long expires;    unsigned long data;    void (*function)(unsigned long);    long sub_expires;};

어떤 struct list_head *p가 struct timer_list의 멤버 list의 포인터라는 것을알고 있는 함수는 list_entry(p, struct timer_list, list)로 언제든지 p가대표하는 리스트 엔트리를 뽑아서 사용할 수 있습니다. 거의 C에서 C++의 STL을구현한 듯한.. (물론 차이가 많습니다만)reference : http://blog.naver.com/PostView.nhn?blogId=popjunior&logNo=80021648631

[출처] list_head 사용 원리????|작성자 포비

No comments:

Post a Comment