我目前正在阅读 Robert Love 的“Linux Kernel Development”,我收到了一些关于 CFS 的问题。我的问题是 calc_delta_mine 如何计算:
delta_exec_weighted= (delta_exec * weight)/lw->weight
我想这是通过两个步骤完成的:
计算 (delta_exec * 1024) :
if (likely(weight > (1UL << SCHED_LOAD_RESOLUTION))) tmp = (u64)delta_exec * scale_load_down(weight); else tmp = (u64)delta_exec;
计算 /lw->weight (或 * lw->inv_weight ):
if (!lw->inv_weight) { unsigned long w = scale_load_down(lw->weight); if (BITS_PER_LONG > 32 && unlikely(w >= WMULT_CONST)) lw->inv_weight = 1; else if (unlikely(!w)) lw->inv_weight = WMULT_CONST; else lw->inv_weight = WMULT_CONST / w; } /* * Check whether we'd overflow the 64-bit multiplication: */ if (unlikely(tmp > WMULT_CONST)) tmp = SRR(SRR(tmp, WMULT_SHIFT/2) * lw->inv_weight, WMULT_SHIFT/2); else tmp = SRR(tmp * lw->inv_weight, WMULT_SHIFT); return (unsigned long)min(tmp, (u64)(unsigned long)LONG_MAX);
SRR(右移和舍入)宏通过以下方式定义:
#define SRR(x, y) (((x) + (1UL << ((y) - 1))) >> (y))
并定义了其他宏:
#if BITS_PER_LONG == 32
# define WMULT_CONST (~0UL)
#else
# define WMULT_CONST (1UL << 32)
#endif
#define WMULT_SHIFT 32
有人可以解释一下 SRR 的工作原理以及它如何检查 64 位乘法溢出吗?请解释一下这个函数中宏的定义((~0UL) ,(1UL << 32))?