std.sync.atomic: extended atomic helper functions (#8866)

- deprecates `std.Thread.spinLoopHint` and moves it to `std.atomic.spinLoopHint`
- added an Atomic(T) generic wrapper type which replaces atomic.Bool and atomic.Int
- in Atomic(T), selectively expose member functions depending on T and include bitwise atomic methods when T is an Integer
- added fence() and compilerFence() to std.atomic
This commit is contained in:
protty
2021-05-31 11:11:30 -05:00
committed by GitHub
parent 57cf9f7ea6
commit eb6975f088
14 changed files with 624 additions and 193 deletions

View File

@@ -67,33 +67,7 @@ else switch (std.Target.current.os.tag) {
else => struct {},
};
/// Signals the processor that it is inside a busy-wait spin-loop ("spin lock").
pub inline fn spinLoopHint() void {
switch (std.Target.current.cpu.arch) {
.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.featureSetHasAny(std.Target.current.cpu.features, .{ .has_v6k, .has_v6m });
if (can_yield) asm volatile ("yield" ::: "memory")
// Fallback.
else asm volatile ("" ::: "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");
},
}
}
pub const spinLoopHint = @compileError("deprecated: use std.atomic.spinLoopHint");
/// Returns the ID of the calling thread.
/// Makes a syscall every time the function is called.
@@ -597,8 +571,13 @@ pub fn getCurrentThreadId() u64 {
}
}
test {
test "std.Thread" {
if (!builtin.single_threaded) {
std.testing.refAllDecls(@This());
_ = AutoResetEvent;
_ = ResetEvent;
_ = StaticResetEvent;
_ = Mutex;
_ = Semaphore;
_ = Condition;
}
}