authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-03-21 15:13:15-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-03-21 15:13:15-07:00
log54c08579e4859673391843182aa2fd44aabbf6cf
tree8459b5a105ceb90b33a944cd80ac00f9c89ced93
parentf32723a237a84cb75c49a3351b951cf8f652fd32
parent9b454a8ce241cf02e2869942c67a6d7871a52fb3
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #19348 from jedisct1/wasi-threads-compfix

Unbreak support for WASI threads

1 files changed, 33 insertions(+), 6 deletions(-)

lib/std/Thread.zig+33-6
......@@ -819,7 +819,7 @@ const WasiThreadImpl = struct {
819819 \\ memory.atomic.wait32 0
820820 \\ local.set %[ret]
821821 : [ret] "=r" (-> u32),
822 : [ptr] "r" (&self.thread.tid.value),
822 : [ptr] "r" (&self.thread.tid.raw),
823823 [expected] "r" (tid),
824824 );
825825 switch (result) {
......@@ -831,15 +831,42 @@ const WasiThreadImpl = struct {
831831 }
832832 }
833833
834 fn spawn(config: std.Thread.SpawnConfig, comptime f: anytype, args: anytype) !WasiThreadImpl {
835 if (config.allocator == null) return error.OutOfMemory; // an allocator is required to spawn a WASI-thread
834 fn spawn(config: std.Thread.SpawnConfig, comptime f: anytype, args: anytype) SpawnError!WasiThreadImpl {
835 if (config.allocator == null) {
836 @panic("an allocator is required to spawn a WASI thread");
837 }
836838
837839 // Wrapping struct required to hold the user-provided function arguments.
838840 const Wrapper = struct {
839841 args: @TypeOf(args),
840842 fn entry(ptr: usize) void {
841843 const w: *@This() = @ptrFromInt(ptr);
842 @call(.auto, f, w.args);
844 const bad_fn_ret = "expected return type of startFn to be 'u8', 'noreturn', 'void', or '!void'";
845 switch (@typeInfo(@typeInfo(@TypeOf(f)).Fn.return_type.?)) {
846 .NoReturn, .Void => {
847 @call(.auto, w, args);
848 },
849 .Int => |info| {
850 if (info.bits != 8) {
851 @compileError(bad_fn_ret);
852 }
853 _ = @call(.auto, w, args); // WASI threads don't support exit status, ignore value
854 },
855 .ErrorUnion => |info| {
856 if (info.payload != void) {
857 @compileError(bad_fn_ret);
858 }
859 @call(.auto, f, args) catch |err| {
860 std.debug.print("error: {s}\n", .{@errorName(err)});
861 if (@errorReturnTrace()) |trace| {
862 std.debug.dumpStackTrace(trace.*);
863 }
864 };
865 },
866 else => {
867 @compileError(bad_fn_ret);
868 },
869 }
843870 }
844871 };
845872
......@@ -927,7 +954,7 @@ const WasiThreadImpl = struct {
927954 \\ i32.const 0
928955 \\ i32.atomic.store 0
929956 :
930 : [ptr] "r" (&arg.thread.tid.value),
957 : [ptr] "r" (&arg.thread.tid.raw),
931958 );
932959
933960 // Wake the main thread listening to this thread
......@@ -937,7 +964,7 @@ const WasiThreadImpl = struct {
937964 \\ memory.atomic.notify 0
938965 \\ drop # no need to know the waiters
939966 :
940 : [ptr] "r" (&arg.thread.tid.value),
967 : [ptr] "r" (&arg.thread.tid.raw),
941968 );
942969 },
943970 .completed => unreachable,