list_for_each_entry
Rev.3を表示中。最新版はこちら。
list_for_each_entryは以下の様に展開されて、ちょっと引いてしまいそうですが、要はリスト処理でlist_for_eachとlist_entryの機能をもたせたものにすぎません。なお、リスト処理その物の取り扱いについてはlist_head構造体参照してもらえばと思います。
#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)
list_for_each_entryとlist_for_eachでリストを走査するサンプルです。使い方を見ていただいて、改めて上記マクロ展開の内容を吟味された方が、理解しやすかと思います。
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/slab.h>
MODULE_DESCRIPTION("list_for_each_entry");
MODULE_AUTHOR("y.kitamura");
static LIST_HEAD(head);
struct my_object {
struct list_head list;
int sec;
};
void set_data(void)
{
struct my_object *myobj;
int i;
for (i = 0; i < 10; ++i) {
myobj = (struct my_object*)kmalloc(sizeof(struct my_object), GFP_KERNEL);
myobj->sec = i;
list_add_tail(&myobj->list, &head);
}
}
void for_each(void)
{
struct list_head *p;
struct my_object *myobj;
list_for_each(p, &head) {
myobj = list_entry(p, struct my_object, list);
printk("%d:", myobj->sec);
}
printk("\n");
}
void for_each_entry(void)
{
struct my_object *myobj;
list_for_each_entry(myobj, &head, list) {
printk("%d:", myobj->sec);
}
printk("\n");
}
int init_module(void)
{
set_data();
for_each();
for_each_entry();
return 0;
}
void cleanup_module(void)
{
struct my_object *myobj;
while(!list_empty(&head)) {
myobj = list_entry(head.next, struct my_object, list);
list_del(&myobj->list);
kfree(myobj);
}
}
[root@localhost lkm]# insmod list_head.ko [root@localhost lkm]# dmesg : : [11090.009091] pcnet32 0000:02:01.0: eth0: link up [11092.004380] pcnet32 0000:02:01.0: eth0: link down [11102.008055] pcnet32 0000:02:01.0: eth0: link up [21452.459410] 0:1:2:3:4:5:6:7:8:9: [21452.459423] 0:1:2:3:4:5:6:7:8:9:





