From c470016743474cd4686ddb523652b4ad7c7ef42f Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Mon, 18 Mar 2024 00:39:32 +0100 Subject: Unbreak support for WASI threads --- lib/std/Thread.zig | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) (limited to 'lib/std/Thread.zig') diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig index e895183331..6866a1702d 100644 --- a/lib/std/Thread.zig +++ b/lib/std/Thread.zig @@ -324,6 +324,9 @@ pub const SpawnError = error{ /// would exceed the limit. LockedMemoryLimitExceeded, + /// An allocator is required to spawn a thread + AllocatorRequired, + Unexpected, }; @@ -819,7 +822,7 @@ const WasiThreadImpl = struct { \\ memory.atomic.wait32 0 \\ local.set %[ret] : [ret] "=r" (-> u32), - : [ptr] "r" (&self.thread.tid.value), + : [ptr] "r" (&self.thread.tid.raw), [expected] "r" (tid), ); switch (result) { @@ -831,15 +834,42 @@ const WasiThreadImpl = struct { } } - fn spawn(config: std.Thread.SpawnConfig, comptime f: anytype, args: anytype) !WasiThreadImpl { - if (config.allocator == null) return error.OutOfMemory; // an allocator is required to spawn a WASI-thread + fn spawn(config: std.Thread.SpawnConfig, comptime f: anytype, args: anytype) SpawnError!WasiThreadImpl { + if (config.allocator == null) { + return error.AllocatorRequired; // an allocator is required to spawn a WASI thread + } // Wrapping struct required to hold the user-provided function arguments. const Wrapper = struct { args: @TypeOf(args), fn entry(ptr: usize) void { const w: *@This() = @ptrFromInt(ptr); - @call(.auto, f, w.args); + const bad_fn_ret = "expected return type of startFn to be 'u8', 'noreturn', 'void', or '!void'"; + switch (@typeInfo(@typeInfo(@TypeOf(f)).Fn.return_type.?)) { + .NoReturn, .Void => { + @call(.auto, w, args); + }, + .Int => |info| { + if (info.bits != 8) { + @compileError(bad_fn_ret); + } + _ = @call(.auto, w, args); // WASI threads don't support exit status, ignore value + }, + .ErrorUnion => |info| { + if (info.payload != void) { + @compileError(bad_fn_ret); + } + @call(.auto, f, args) catch |err| { + std.debug.print("error: {s}\n", .{@errorName(err)}); + if (@errorReturnTrace()) |trace| { + std.debug.dumpStackTrace(trace.*); + } + }; + }, + else => { + @compileError(bad_fn_ret); + }, + } } }; @@ -927,7 +957,7 @@ const WasiThreadImpl = struct { \\ i32.const 0 \\ i32.atomic.store 0 : - : [ptr] "r" (&arg.thread.tid.value), + : [ptr] "r" (&arg.thread.tid.raw), ); // Wake the main thread listening to this thread @@ -937,7 +967,7 @@ const WasiThreadImpl = struct { \\ memory.atomic.notify 0 \\ drop # no need to know the waiters : - : [ptr] "r" (&arg.thread.tid.value), + : [ptr] "r" (&arg.thread.tid.raw), ); }, .completed => unreachable, -- cgit v1.2.3 From 9b454a8ce241cf02e2869942c67a6d7871a52fb3 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Tue, 19 Mar 2024 13:11:33 +0100 Subject: WASI-thread: panic if no allocator is given --- lib/std/Thread.zig | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'lib/std/Thread.zig') diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig index 6866a1702d..ec1fef22bb 100644 --- a/lib/std/Thread.zig +++ b/lib/std/Thread.zig @@ -324,9 +324,6 @@ pub const SpawnError = error{ /// would exceed the limit. LockedMemoryLimitExceeded, - /// An allocator is required to spawn a thread - AllocatorRequired, - Unexpected, }; @@ -836,7 +833,7 @@ const WasiThreadImpl = struct { fn spawn(config: std.Thread.SpawnConfig, comptime f: anytype, args: anytype) SpawnError!WasiThreadImpl { if (config.allocator == null) { - return error.AllocatorRequired; // an allocator is required to spawn a WASI thread + @panic("an allocator is required to spawn a WASI thread"); } // Wrapping struct required to hold the user-provided function arguments. -- cgit v1.2.3