mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
std: implement Futex for WebAssembly
Implements std's `Futex` for the WebAssembly target using Wasm's `atomics` instruction set. When the `atomics` cpu feature is disabled we emit a compile-error.
This commit is contained in:
parent
062eb6f3c0
commit
ea0d4c8377
@ -73,6 +73,8 @@ else if (builtin.os.tag == .openbsd)
|
||||
OpenbsdImpl
|
||||
else if (builtin.os.tag == .dragonfly)
|
||||
DragonflyImpl
|
||||
else if (builtin.target.isWasm())
|
||||
WasmImpl
|
||||
else if (std.Thread.use_pthreads)
|
||||
PosixImpl
|
||||
else
|
||||
@ -446,6 +448,49 @@ const DragonflyImpl = struct {
|
||||
}
|
||||
};
|
||||
|
||||
const WasmImpl = struct {
|
||||
fn wait(ptr: *const Atomic(u32), expect: u32, timeout: ?u64) error{Timeout}!void {
|
||||
if (!comptime std.Target.wasm.featureSetHas(builtin.target.cpu.features, .atomics)) {
|
||||
@compileError("WASI target missing cpu feature 'atomics'");
|
||||
}
|
||||
const to: i64 = if (timeout) |to| @intCast(i64, to) else -1;
|
||||
const result = asm (
|
||||
\\local.get %[ptr]
|
||||
\\local.get %[expected]
|
||||
\\local.get %[timeout]
|
||||
\\memory.atomic.wait32 0
|
||||
\\local.set %[ret]
|
||||
: [ret] "=r" (-> u32),
|
||||
: [ptr] "r" (&ptr.value),
|
||||
[expected] "r" (@bitCast(i32, expect)),
|
||||
[timeout] "r" (to),
|
||||
);
|
||||
switch (result) {
|
||||
0 => {}, // ok
|
||||
1 => {}, // expected =! loaded
|
||||
2 => return error.Timeout,
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
fn wake(ptr: *const Atomic(u32), max_waiters: u32) void {
|
||||
if (!comptime std.Target.wasm.featureSetHas(builtin.target.cpu.features, .atomics)) {
|
||||
@compileError("WASI target missing cpu feature 'atomics'");
|
||||
}
|
||||
assert(max_waiters != 0);
|
||||
const woken_count = asm (
|
||||
\\local.get %[ptr]
|
||||
\\local.get %[waiters]
|
||||
\\memory.atomic.notify 0
|
||||
\\local.set %[ret]
|
||||
: [ret] "=r" (-> u32),
|
||||
: [ptr] "r" (&ptr.value),
|
||||
[waiters] "r" (max_waiters),
|
||||
);
|
||||
_ = woken_count; // can be 0 when linker flag 'shared-memory' is not enabled
|
||||
}
|
||||
};
|
||||
|
||||
/// Modified version of linux's futex and Go's sema to implement userspace wait queues with pthread:
|
||||
/// https://code.woboq.org/linux/linux/kernel/futex.c.html
|
||||
/// https://go.dev/src/runtime/sema.go
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user