authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-04-30 17:11:03+02:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-04-30 17:11:03+02:00
log807bb7c03fc98e3792ece7e0573e226727c18129
tree91563f5b460b932576cc754feb51ad4fa5147bc8
parent55c58f226d06d3708a82878a67f3800e0ce5810b

std: Improve spinloop hint

* Add a yield pattern for PowerPC64 * Fix compile error on pre-v6 ARM targets * Use isb instead of yield on AArch64 to give the CPU a chance to enter low-power states. * Make the hint an inline function, the call overhead can be avoided.

1 files changed, 21 insertions(+), 4 deletions(-)

lib/std/Thread.zig+21-4
......@@ -68,11 +68,28 @@ else switch (std.Target.current.os.tag) {
6868};
6969
7070/// Signals the processor that it is inside a busy-wait spin-loop ("spin lock").
71pub fn spinLoopHint() void {
71pub fn spinLoopHint() callconv(.Inline) void {
7272 switch (std.Target.current.cpu.arch) {
73 .i386, .x86_64 => asm volatile ("pause" ::: "memory"),
74 .arm, .aarch64 => asm volatile ("yield" ::: "memory"),
75 else => {},
73 .i386, .x86_64 => {
74 asm volatile ("pause" ::: "memory");
75 },
76 .arm, .armeb, .thumb, .thumbeb => {
77 // `yield` was introduced in v6k but are also available on v6m.
78 const can_yield = comptime std.Target.arm.featureSetHas(std.Target.current.cpu.features, .has_v6m);
79 if (can_yield) asm volatile ("yield" ::: "memory");
80 },
81 .aarch64, .aarch64_be, .aarch64_32 => {
82 asm volatile ("isb" ::: "memory");
83 },
84 .powerpc64, .powerpc64le => {
85 // No-op that serves as `yield` hint.
86 asm volatile ("or 27, 27, 27" ::: "memory");
87 },
88 else => {
89 // Do nothing but prevent the compiler from optimizing away the
90 // spinning loop.
91 asm volatile ("" ::: "memory");
92 },
7693 }
7794}
7895