了解 Linux 内核中的 hlist_bl_for_each_entry_rcu 宏

Understanding hlist_bl_for_each_entry_rcu macro in Linux Kernel

在浏览Linux内核源代码时,我发现hlist_bl_for_each_entry_rcumacro.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循环中的这个条件?

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

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 块。在无宏版本中,您希望每次 pos 为非 NULL 时设置 tpos' 值,因此您将其添加到 pos &&:

之后的循环条件中
pos && (tpos = hlist_bl_entry(pos, typeof(*tpos), member))

但是现在tops非空变成了一个循环条件,所以你告诉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; })