list_for_each 详解

list_for_each 详解

最近在学习linux内核,看到进程管理时,有这么一段代码,一脸懵逼;

struct task_struct *task; 
struct list_head *list;
list_for_each(list, &current->children) { 
    task = list_entry(list, struct task_struct, sibling); /* task 现在指向某个子进程 */ } 

其中task即为某个子进程的地址

于是求助大百度,现做些总结:
offsetof

//offsetof(/include/linux/stddef.h):相关宏在内核中的地址
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

为清楚了解list_for_each的含义,先从offsetof开始讲起,offsetof表示MEMBER类型在TYPE类型中的偏移位置;该宏写的很巧妙,将0地址强转为TYPE类型,在对其中的MEMBER进行取址,将该地址转为size_t类型就获得了MEMBER类型在TYPE类型中的偏移位置。
container_of

//container_of(include/linux/kernel.h): 
#define container_of(ptr, type, member) ({ \ 
    const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 
    (type *)( (char *)__mptr - offsetof(type,member) );})

typeof表示取对应参数的类型;
container_of的作用表示先求出结构体成员(即member)在结构体(即type)中的偏移量,然后再根据member的地址(即ptr)来求出其所在结构体的地址。
list_for_each

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

表示遍历循环链表,起始值是pos = (head)->next,条件是pos != (head),条件不满足时遍历下一个值pos = pos->next

#define list_entry(ptr, type, member) \
    container_of(ptr, type, member)

list_entry就表示ptr所在的结构体的地址,就是指针;

list_for_each(list, &current->children) { 
    task = list_entry(list, struct task_struct, sibling); /* task 现在指向某个子进程 */ } 

因此上面代码的含义就是依次访问当前线程的所有子线程;
prefetch()的作用
有一个共识是:程序访问的变量如果都能在系统内存cache中则能提升性能,prefetch是内核中一个预热内存函数,这样下次遍历时就能高效命中内存cache,从而提升程序性能。上面的代码中遍历链表时下次访问的内存为pos->next,故在每次遍历时对pos->next进行预热,从而提升性能。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值