为什么内核宏 for_each_cpu 从 cpu = -1 循环到 smp?

why kernel macro for_each_cpu loop from cpu = -1 for smp?

为什么宏 for_each_cpucpu 开始循环等于 -1?在include/linux/cpumask.h:

中很难理解这个定义
249 /**
250  * for_each_cpu - iterate over every cpu in a mask
251  * @cpu: the (optionally unsigned) integer iterator
252  * @mask: the cpumask pointer
253  * 
254  * After the loop, cpu is >= nr_cpu_ids.
255  */
256 #define for_each_cpu(cpu, mask)             \
257     for ((cpu) = -1;                \
258         (cpu) = cpumask_next((cpu), (mask)),    \
259         (cpu) < nr_cpu_ids;)

而不是 for 表达式的 "canonic" 形式:

for(<initialize>; <condition>; <move-to-next>)

for_each_cpu使用另一种形式:

for(<pre-initialize>; (<move-to-next>, <condition>); )

也就是说,它将 3d 参数留空,但将 <move-to-next><condition> 部分组合到 for 的第二个参数中(记住:逗号运算符的结果是它的右边部分)。

这大致相当于

for(<pre-initialize> and <move-to-next>; <move-to-next>; <condition>)

也就是说,move-to-next操作甚至在第一次迭代之前执行

因此,for_each_cpu 可以定义 "canonically" 如下:

#define for_each_cpu(cpu, mask)            \
 for ((cpu) = cpumask_next((-1), (mask));  \
    (cpu) = cpumask_next((cpu), (mask));   \
    (cpu) < nr_cpu_ids)

与原始定义的区别之一是此处 mask 计算两次 (而原始定义仅计算 mask 一次)。

可能,只评估一次 mask 的意图是 "complex" 定义的原因。