jump label"/>
jump label
这段代码的反汇编如下所示
static inline bool test_idle_cores(int cpu, bool def)
{struct sched_domain_shared *sds;if (static_branch_unlikely(&sched_smt_present)) {sds = rcu_dereference(per_cpu(sd_llc_shared, cpu));if (sds)return READ_ONCE(sds->has_idle_cores);}return def;
}0000000000000884 <test_idle_cores>:
{884: 12001c21 and w1, w1, #0xff
#define JUMP_LABEL_NOP_SIZE AARCH64_INSN_SIZEstatic __always_inline bool arch_static_branch(struct static_key *key,bool branch)
{asm_volatile_goto(888: d503201f nop
}88c: 2a0103e0 mov w0, w1890: d65f03c0 retsds = rcu_dereference(per_cpu(sd_llc_shared, cpu));894: 90000003 adrp x3, 0 <__per_cpu_offset>898: 91000063 add x3, x3, #0x089c: 90000002 adrp x2, 0 <sd_llc_shared>8a0: 91000042 add x2, x2, #0x08a4: f860d860 ldr x0, [x3, w0, sxtw #3]8a8: f8606840 ldr x0, [x2, x0]if (sds)8ac: b4ffff00 cbz x0, 88c <test_idle_cores+0x8>return READ_ONCE(sds->has_idle_cores);8b0: b9400800 ldr w0, [x0, #8]8b4: 7100001f cmp w0, #0x08b8: 1a9f07e1 cset w1, ne // ne = any8bc: 17fffff4 b 88c <test_idle_cores+0x8>为什么会是这样呢,我们看看static_branch_likely的实现
如果使能jump_label的话是先如下,如果没有的话就等同普通的unlikely
#define static_branch_unlikely(x) \
({ \bool branch; \if (__builtin_types_compatible_p(typeof(*x), struct static_key_true)) \branch = arch_static_branch_jump(&(x)->key, false); \else if (__builtin_types_compatible_p(typeof(*x), struct static_key_false)) \branch = arch_static_branch(&(x)->key, false); \else \branch = ____wrong_branch_error(); \unlikely_notrace(branch); \
})由于本例中的sched_smt_present 默认为false,所以我们看看 arch_static_branch的实现static __always_inline bool arch_static_branch(struct static_key *key,bool branch)
{asm_volatile_goto("1: nop \n\t"" .pushsection __jump_table, \"aw\" \n\t"" .align 3 \n\t"" .long 1b - ., %l[l_yes] - . \n\t"" .quad %c0 - . \n\t"" .popsection \n\t": : "i"(&((char *)key)[branch]) : : l_yes);return false;
l_yes:return true;
}可以和上面的汇编对比下。这里也可以看出static_branch_unlikely 是一个宏,会被展开,最后就是一行unlikely_notrace
可见static_branch_unlikely 是包含unlikely_notrace.
简单理解就是
仔细看代码就会发现 static_branch_likely 不等于 !static_branch_unlikely 同样!static_branch_likely 也不等于static_branch_unlikely.
可以通过反汇编查询上面两种情况的区别. 性能上也是有差异的,取决于key的初始值是true还是false.
那什么时候用!static_branch_unlikely这个组合呢?
那就是当key是false时,static_branch_unlikely 对应的就是nop,但是代码中又不需要这个条件成立时,可以自己体会下.
更多推荐
jump label
发布评论