曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 9911|回复: 0
打印 上一主题 下一主题

内核链表遍历 | list_for_each_entry()

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
跳转到指定楼层
楼主
发表于 2011-5-19 13:47:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
内核版本:2.6.24
list_for_each_entry() 宏用来遍历内核链表,它定义在 include/linux/list.h 中:
[C++] 纯文本查看 复制代码
/**
 * list_for_each_entry    -    iterate over list of given type
 * @pos:    the type * to use as a loop cursor.
 * @head:    the head for your list.
 * @member:    the name of the list_struct within the struct.
 */
#define list_for_each_entry(pos, head, member)                \
    for (pos = list_entry((head)->next, typeof(*pos), member);    \
         prefetch(pos->member.next), &pos->member != (head);     \
         pos = list_entry(pos->member.next, typeof(*pos), member))

由注释知道,pos 参数是 1 个遍历用的指针,第 2 个参数就是链表头,第 3 个参数为链表中元素的一个成员。该宏被定义为一个 for 循环,可以用它从它从第 1 个元素开始(list_entry((head)->next)遍历整个链表。其中 prefetch() 函数用以加快对链表的遍历速度,它实际上是 gcc 内置函数 __builtin_prefetch 的封装,关于 __builtin_prefetch 函数的描述可参考:http://www.groad.net/bbs/read.php?tid-3542.html 。在 2.6.3x 这样的内核中,取消了 prefetch() 函数在此的使用,估计是和后来的 CPU 的缓存机制更为先进的缘故。

下面用这个函数遍历整个模块链表,并打印出各个模块的名字,就如同 lsmod 的精简版:
[C++] 纯文本查看 复制代码
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/version.h>
#include <linux/list.h>

MODULE_LICENSE("Dual BSD/GPL");

struct module *m = &__this_module;

static void list_module_test(void)
{
        struct module *mod;
        list_for_each_entry(mod, m->list.prev, list)
                printk ("%s\n", mod->name);

}
static int list_module_init (void)
{
        list_module_test();
        return 0;
}

static void list_module_exit (void)
{
        printk ("unload listmodule.ko\n");
}

module_init(list_module_init);
module_exit(list_module_exit);

因为插入的当前模块会加在表头和原来的第一个模块之间,所以 m->list.prev 参数用以指名从表头开始遍历。
加载后输出:
[root@SLinux listmodule]# dmesg -c
listmodule
fuse
ip6table_filter
ip6_tables
xt_CHECKSUM
iptable_mangle
ipt_MASQUERADE
iptable_nat
... ...
ata_generic
pata_acpi
ata_piix
dm_mod
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-17 04:23 , Processed in 0.062113 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表