authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2024-03-18 00:39:32+01:00
committergravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2024-03-18 16:51:41+01:00
logc470016743474cd4686ddb523652b4ad7c7ef42f
treeedff409066bf71d0d375c04c6d0382a32c627924
parent8e7d9afdacef9d3a9443fc4b70cfe6aa229ecee5

Unbreak support for WASI threads


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

lib/std/Thread.zig+36-6
...@@ -324,6 +324,9 @@ pub const SpawnError = error{...@@ -324,6 +324,9 @@ pub const SpawnError = error{
324 /// would exceed the limit.324 /// would exceed the limit.
325 LockedMemoryLimitExceeded,325 LockedMemoryLimitExceeded,
326326
327 /// An allocator is required to spawn a thread
328 AllocatorRequired,
329
327 Unexpected,330 Unexpected,
328};331};
329332
...@@ -819,7 +822,7 @@ const WasiThreadImpl = struct {...@@ -819,7 +822,7 @@ const WasiThreadImpl = struct {
819 \\ memory.atomic.wait32 0822 \\ memory.atomic.wait32 0
820 \\ local.set %[ret]823 \\ local.set %[ret]
821 : [ret] "=r" (-> u32),824 : [ret] "=r" (-> u32),
822 : [ptr] "r" (&self.thread.tid.value),825 : [ptr] "r" (&self.thread.tid.raw),
823 [expected] "r" (tid),826 [expected] "r" (tid),
824 );827 );
825 switch (result) {828 switch (result) {
...@@ -831,15 +834,42 @@ const WasiThreadImpl = struct {...@@ -831,15 +834,42 @@ const WasiThreadImpl = struct {
831 }834 }
832 }835 }
833836
834 fn spawn(config: std.Thread.SpawnConfig, comptime f: anytype, args: anytype) !WasiThreadImpl {837 fn spawn(config: std.Thread.SpawnConfig, comptime f: anytype, args: anytype) SpawnError!WasiThreadImpl {
835 if (config.allocator == null) return error.OutOfMemory; // an allocator is required to spawn a WASI-thread838 if (config.allocator == null) {
839 return error.AllocatorRequired; // an allocator is required to spawn a WASI thread
840 }
836841
837 // Wrapping struct required to hold the user-provided function arguments.842 // Wrapping struct required to hold the user-provided function arguments.
838 const Wrapper = struct {843 const Wrapper = struct {
839 args: @TypeOf(args),844 args: @TypeOf(args),
840 fn entry(ptr: usize) void {845 fn entry(ptr: usize) void {
841 const w: *@This() = @ptrFromInt(ptr);846 const w: *@This() = @ptrFromInt(ptr);
842 @call(.auto, f, w.args);847 const bad_fn_ret = "expected return type of startFn to be 'u8', 'noreturn', 'void', or '!void'";
848 switch (@typeInfo(@typeInfo(@TypeOf(f)).Fn.return_type.?)) {
849 .NoReturn, .Void => {
850 @call(.auto, w, args);
851 },
852 .Int => |info| {
853 if (info.bits != 8) {
854 @compileError(bad_fn_ret);
855 }
856 _ = @call(.auto, w, args); // WASI threads don't support exit status, ignore value
857 },
858 .ErrorUnion => |info| {
859 if (info.payload != void) {
860 @compileError(bad_fn_ret);
861 }
862 @call(.auto, f, args) catch |err| {
863 std.debug.print("error: {s}\n", .{@errorName(err)});
864 if (@errorReturnTrace()) |trace| {
865 std.debug.dumpStackTrace(trace.*);
866 }
867 };
868 },
869 else => {
870 @compileError(bad_fn_ret);
871 },
872 }
843 }873 }
844 };874 };
845875
...@@ -927,7 +957,7 @@ const WasiThreadImpl = struct {...@@ -927,7 +957,7 @@ const WasiThreadImpl = struct {
927 \\ i32.const 0957 \\ i32.const 0
928 \\ i32.atomic.store 0958 \\ i32.atomic.store 0
929 :959 :
930 : [ptr] "r" (&arg.thread.tid.value),960 : [ptr] "r" (&arg.thread.tid.raw),
931 );961 );
932962
933 // Wake the main thread listening to this thread963 // Wake the main thread listening to this thread
...@@ -937,7 +967,7 @@ const WasiThreadImpl = struct {...@@ -937,7 +967,7 @@ const WasiThreadImpl = struct {
937 \\ memory.atomic.notify 0967 \\ memory.atomic.notify 0
938 \\ drop # no need to know the waiters968 \\ drop # no need to know the waiters
939 :969 :
940 : [ptr] "r" (&arg.thread.tid.value),970 : [ptr] "r" (&arg.thread.tid.raw),
941 );971 );
942 },972 },
943 .completed => unreachable,973 .completed => unreachable,