無料Wikiサービス | デモページ
検索

アクセス数
最近のコメント
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
はじめ - ノース
はじめ - ノース
はじめ - 楽打連動ユーザー
はじめ - 楽打連動ユーザー
Adsense
広告情報が設定されていません。

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 作成)