list_head(list_for_each_entry)


エレメントの要素のstruct list_head listから取得したアドレスはエレメントのアドレスでなく、エレメント要素のstruct list_head listのアドレスで、struct list_head listが先頭要素ならstruct list_head listのアドレスは、エレメントアドレスとなりますが、そうでないなら、struct list_head listのオフセット位置を差し引いたアドレスのエレメントアドレスとする実装となります。
#define list_for_each_entry(pos, head, member)                          \
      for (pos = list_entry((head)->next, typeof(*pos), member);      \
           &pos->member != (head);    \
           pos = list_entry(pos->member.next, typeof(*pos), member))

#define list_for_each(pos, head) \
      for (pos = (head)->next; pos != (head); pos = pos->next)

#define list_entry(ptr, type, member) \
      container_of(ptr, type, member)
[root@localhost c]# cat list_head2.c
#include <stdio.h>
#include <stddef.h>

void    get_list(char* msg);
void    add_tail_list(int id);
void    add_head_list(int id);
void    init_link_list();

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

struct babakaka {
   char  id1;
   char name[2];
   struct list_head list;
   char  id2;
};

struct list_head head;
struct babakaka element[10];

void    init_element()
{
       int     i;

       head.next = &head;
       head.prev = &head;
       for(i = 0; i < 10; i++) {
               element[i].id1 = i;
               element[i].id2 = i + 10;
               sprintf(element[i].name, "%c", 'a'+i);
               element[i].name[1] = 0;
       }

}

void    main()
{
       init_element();

       init_link_list();
       get_list("init");

       add_tail_list(4);
       add_tail_list(5);
       add_tail_list(6);
       get_list("add tail");

       add_head_list(7);
       add_head_list(8);
       add_head_list(9);
       get_list("add head");
}

void    init_link_list()
{
       int     i;

       head.next = &element[0].list;

       element[0].list.prev = &head;
       element[0].list.next = &element[1].list;

       element[1].list.prev = &element[0].list;
       element[1].list.next = &element[2].list;

       element[2].list.prev = &element[1].list;
       element[2].list.next = &element[3].list;

       element[3].list.prev = &element[2].list;
       element[3].list.next = &head;

       head.prev = &element[3].list;
}

void    add_head_list(int id)
{
       struct list_head *a, *b, *c;

       a = &head;
       b = &element[id].list;
       c = head.next;

       a->next = b;

       b->prev = a;
       b->next = c;

       c->prev = b;
}

void    add_tail_list(int id)
{
       struct list_head *a, *b, *c;

       a = &head;
       b = &element[id].list;
       c = head.prev;

       a->prev = b;

       b->next = a;
       b->prev = c;

       c->next = b;
}

void    get_list(char* msg)
{
       struct  babakaka        *p;
       int     listoffset_of_babakaka;

       printf("%10s:", msg);
       listoffset_of_babakaka = offsetof(struct  babakaka, list);
       for (p = (struct babakaka *) ((char *)head.next - listoffset_of_babakaka);
               p->list.next != &head;
                       p = (struct babakaka *)((char *)p->list.next - listoffset_of_babakaka)) {
              printf("[%d.%s.%d] ", p->id1, p->name, p->id2);
       }
       printf("\n");
}

[root@localhost c]# ./a.out
     init:[0.a.10] [1.b.11] [2.c.12]
 add tail:[0.a.10] [1.b.11] [2.c.12] [3.d.13] [4.e.14] [5.f.15]
 add head:[9.j.19] [8.i.18] [7.h.17] [0.a.10] [1.b.11] [2.c.12] [3.d.13] [4.e.14] [5.f.15]


最終更新 2017/01/02 13:24:20 - north
(2017/01/02 13:24:20 作成)


検索

アクセス数
3590116
最近のコメント
コアダンプファイル - sakaia
list_head構造体 - yocto_no_yomikata
勧告ロックと強制ロック - wataash
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
Adsense
広告情報が設定されていません。