list_for_each_entry


Rev.4を表示中。最新版はこちら

[root@localhost north]# cat sample.c
#include <stddef.h>
#include <stdio.h>

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

struct babakaka1 {
    struct list_head child;
    struct list_head parent;
    int data;
};

struct babakaka2 {
    int data;
    struct list_head child;
    struct list_head parent;
};

struct babakaka1 a1,b1,c1,d1;
struct babakaka2 a2,b2,c2,d2;

void	obj1_list();
void	obj1_disp();
void	obj2_list();
void	obj2_disp();

void	main()
{
    obj1_list();
    obj2_list();

    obj1_disp();
    obj2_disp();
}

void	obj1_list()
{
    a1.data = 1; b1.data = 2; c1.data = 3; d1.data = 4;

    a1.parent.next = &b1.child;
    b1.child.next = &c1.child;
    c1.child.next = &d1.child;
    d1.child.next = &a1.parent;
}

void	obj2_list()
{
    a2.data = 1; b2.data = 2; c2.data = 3; d2.data = 4;

    a2.parent.next = &b2.child;
    b2.child.next = &c2.child;
    c2.child.next = &d2.child;
    d2.child.next = &a2.parent;
} 

void	obj1_disp()
{
    struct	babakaka1 *obj;
    int	offset_child;

    printf("***disp obj[1]\n");
    offset_child = offsetof(struct babakaka1, child);
    printf("listed child member offset in struct:%d\n", offset_child);

    obj = &a1;
    printf("%d\n", obj->data);
    obj = (struct babakaka1 *)obj->parent.next;
    while(1) {
        printf("%d\n", obj->data);
        if(obj->child.next == &a1.parent) {
            break;
          }
        obj = (struct babakaka1 *)obj->child.next;
    }
}

void    obj2_disp()
{
    struct  babakaka2 *obj, *obj1;
    int	offset_child;

    printf("***disp obj[2]\n");
    offset_child = offsetof(struct babakaka2, child);
    printf("listed child offset member in struct:%d\n", offset_child);

    obj = &a2;
    printf("%d\n", obj->data);
    obj = (struct babakaka2 *)((char *)obj->parent.next - offset_child);
    while(1) {
        printf("%d\n", obj->data);
        if(obj->child.next == &a2.parent) {
            break;
          }
        obj = (struct babakaka2 *)((char *)obj->child.next - offset_child);
    }
}

[root@localhost north]# ./sample.out 
***disp obj[1]
listed child member offset in struct:0
1
2
3
4
***disp obj[2]
listed child offset member in struct:4
1
2
3
4

list_for_each_entryは、disp obj[2]に係る処理のマクロによるfor文による実装
#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)

#define container_of(ptr, type, member) ({                      \
       const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
       (type *)( (char *)__mptr - offsetof(type,member) );})

備考

オブジェクトが複数のリストで管理するケースでは、struct list_head childに係るメンバーは複数設定される故、list_head childオフセットを考慮しないdisp obj[1]による実装されない。

list_head->prevは接続元の親オブジェクトで、オブジェクト削除は、削除オブジェクト->prev->next = 削除オブジェクト->nextとなる。親オジェクトのprevは、リストされている終端オブジェクトで、オブジェクトの追加時に参照される。

最終更新 2017/08/27 17:55:17 - north
(2013/06/23 23:57:37 作成)


検索

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