zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 807bb7c03fc98e3792ece7e0573e226727c18129 (tree)
parent 55c58f226d06d3708a82878a67f3800e0ce5810b
Author: LemonBoy <thatlemon@gmail.com>
Date:   Fri, 30 Apr 2021 17:11:03 +0200

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.

Diffstat:
Mlib/std/Thread.zig | 25+++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig @@ -68,11 +68,28 @@ else switch (std.Target.current.os.tag) { }; /// Signals the processor that it is inside a busy-wait spin-loop ("spin lock"). -pub fn spinLoopHint() void { +pub fn spinLoopHint() callconv(.Inline) void { switch (std.Target.current.cpu.arch) { - .i386, .x86_64 => asm volatile ("pause" ::: "memory"), - .arm, .aarch64 => asm volatile ("yield" ::: "memory"), - else => {}, + .i386, .x86_64 => { + asm volatile ("pause" ::: "memory"); + }, + .arm, .armeb, .thumb, .thumbeb => { + // `yield` was introduced in v6k but are also available on v6m. + const can_yield = comptime std.Target.arm.featureSetHas(std.Target.current.cpu.features, .has_v6m); + if (can_yield) asm volatile ("yield" ::: "memory"); + }, + .aarch64, .aarch64_be, .aarch64_32 => { + asm volatile ("isb" ::: "memory"); + }, + .powerpc64, .powerpc64le => { + // No-op that serves as `yield` hint. + asm volatile ("or 27, 27, 27" ::: "memory"); + }, + else => { + // Do nothing but prevent the compiler from optimizing away the + // spinning loop. + asm volatile ("" ::: "memory"); + }, } }