了解Linux内核中的hlist_bl_for_each_entry_rcu宏

时间:2018-04-15 06:38:45

标签: c linux-kernel kernel

在浏览Linux内核源代码时,我发现hlist_bl_for_each_entry_rcu宏.Below是它的定义

for (pos = hlist_bl_first_rcu(head);                            \
                pos &&                                                  \
                ({ tpos = hlist_bl_entry(pos, typeof(*tpos), member); 1; }); \
                pos = rcu_dereference_raw(pos->next))

__d_lookup()中使用此宏来获取dentry。我不明白的是行

({ tpos = hlist_bl_entry(pos, typeof(*tpos), member); 1; });

它得到了tpos。 1在这有什么用?如何在for循环中理解这个条件?

1 个答案:

答案 0 :(得分:2)

如果你是无宏地编写它,它可能看起来像这样:

for (pos = hlist_bl_first_rcu(head); pos; pos = rcu_dereference_raw(pos->next)) {
    tpos = hlist_bl_entry(pos, typeof(*tpos), member);

    /* do something with pos and tpos */

}

对于宏,您可能希望将tpos = hlist_bl_entry(pos, typeof(*tpos), member);移至for (...),因此用户只需提供for块。在无宏版本中,您需要tpos'每次pos为非NULL时设置的值,因此在pos &&之后将其添加到循环条件中:

pos && (tpos = hlist_bl_entry(pos, typeof(*tpos), member))

但现在tops非nullness成为循环条件,所以你告诉C ignore the return value

pos && ((tpos = hlist_bl_entry(pos, typeof(*tpos), member)), 1)

但内核代码无论如何都是GNU C,因此您可以改为使用statement expressions

pos && ({ tpos = hlist_bl_entry(pos, typeof(*tpos), member); 1; })