| ... | @@ -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, |
| 326 | | 326 | |
| | 327 | /// An allocator is required to spawn a thread |
| | 328 | AllocatorRequired, |
| | 329 | |
| 327 | Unexpected, | 330 | Unexpected, |
| 328 | }; | 331 | }; |
| 329 | | 332 | |
| ... | @@ -819,7 +822,7 @@ const WasiThreadImpl = struct { | ... | @@ -819,7 +822,7 @@ const WasiThreadImpl = struct { |
| 819 | \\ memory.atomic.wait32 0 | 822 | \\ 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 | } |
| 833 | | 836 | |
| 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-thread | 838 | if (config.allocator == null) { |
| | 839 | return error.AllocatorRequired; // an allocator is required to spawn a WASI thread |
| | 840 | } |
| 836 | | 841 | |
| 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 | }; |
| 845 | | 875 | |
| ... | @@ -927,7 +957,7 @@ const WasiThreadImpl = struct { | ... | @@ -927,7 +957,7 @@ const WasiThreadImpl = struct { |
| 927 | \\ i32.const 0 | 957 | \\ i32.const 0 |
| 928 | \\ i32.atomic.store 0 | 958 | \\ i32.atomic.store 0 |
| 929 | : | 959 | : |
| 930 | : [ptr] "r" (&arg.thread.tid.value), | 960 | : [ptr] "r" (&arg.thread.tid.raw), |
| 931 | ); | 961 | ); |
| 932 | | 962 | |
| 933 | // Wake the main thread listening to this thread | 963 | // 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 0 | 967 | \\ memory.atomic.notify 0 |
| 938 | \\ drop # no need to know the waiters | 968 | \\ 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, |