| author | |
| committer | |
| log | 87b8a0567b0f54415aeecd879d3f1a4e12014d22 |
| tree | 77cea5728d61fd701009a40e6ac0c70ce282c69a |
| parent | e06ab1b0107e8a6a1720703a6df0f61f535b5e5a |
| signature |
When targeting WebAssembly, we default to building a single-threaded build
as threads are still experimental. The user however can enable a multi-
threaded build by specifying '-fno-single-threaded'. It's a compile-error
to enable this flag, but not also enable shared-memory.4 files changed, 30 insertions(+), 8 deletions(-)
lib/std/Thread.zig+4| ... | @@ -919,6 +919,10 @@ const WasiThreadImpl = struct { | ... | @@ -919,6 +919,10 @@ const WasiThreadImpl = struct { |
| 919 | 919 | ||
| 920 | /// Bootstrap procedure, called by the host environment after thread creation. | 920 | /// Bootstrap procedure, called by the host environment after thread creation. |
| 921 | export fn wasi_thread_start(tid: i32, arg: *Instance) void { | 921 | export fn wasi_thread_start(tid: i32, arg: *Instance) void { |
| 922 | if (builtin.single_threaded) { | ||
| 923 | // ensure function is not analyzed in single-threaded mode | ||
| 924 | return; | ||
| 925 | } | ||
| 922 | __set_stack_pointer(arg.thread.memory.ptr + arg.stack_offset); | 926 | __set_stack_pointer(arg.thread.memory.ptr + arg.stack_offset); |
| 923 | __wasm_init_tls(arg.thread.memory.ptr + arg.tls_offset); | 927 | __wasm_init_tls(arg.thread.memory.ptr + arg.tls_offset); |
| 924 | @atomicStore(u32, &WasiThreadImpl.tls_thread_id, @intCast(tid), .SeqCst); | 928 | @atomicStore(u32, &WasiThreadImpl.tls_thread_id, @intCast(tid), .SeqCst); |
src/Compilation.zig+1-1| ... | @@ -1029,7 +1029,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1029,7 +1029,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1029 | 1029 | ||
| 1030 | const include_compiler_rt = options.want_compiler_rt orelse needs_c_symbols; | 1030 | const include_compiler_rt = options.want_compiler_rt orelse needs_c_symbols; |
| 1031 | 1031 | ||
| 1032 | const must_single_thread = options.target.isWasm() and !options.linker_shared_memory; | 1032 | const must_single_thread = target_util.isSingleThreaded(options.target); |
| 1033 | const single_threaded = options.single_threaded orelse must_single_thread; | 1033 | const single_threaded = options.single_threaded orelse must_single_thread; |
| 1034 | if (must_single_thread and !single_threaded) { | 1034 | if (must_single_thread and !single_threaded) { |
| 1035 | return error.TargetRequiresSingleThreaded; | 1035 | return error.TargetRequiresSingleThreaded; |
src/main.zig+20-7| ... | @@ -2428,15 +2428,28 @@ fn buildOutputType( | ... | @@ -2428,15 +2428,28 @@ fn buildOutputType( |
| 2428 | link_libcpp = true; | 2428 | link_libcpp = true; |
| 2429 | } | 2429 | } |
| 2430 | 2430 | ||
| 2431 | if (target_info.target.cpu.arch.isWasm() and linker_shared_memory) { | 2431 | if (target_info.target.cpu.arch.isWasm()) blk: { |
| 2432 | if (output_mode == .Obj) { | 2432 | if (single_threaded == null) { |
| 2433 | fatal("shared memory is not allowed in object files", .{}); | 2433 | single_threaded = true; |
| 2434 | } | 2434 | } |
| 2435 | if (linker_shared_memory) { | ||
| 2436 | if (output_mode == .Obj) { | ||
| 2437 | fatal("shared memory is not allowed in object files", .{}); | ||
| 2438 | } | ||
| 2435 | 2439 | ||
| 2436 | if (!target_info.target.cpu.features.isEnabled(@intFromEnum(std.Target.wasm.Feature.atomics)) or | 2440 | if (!target_info.target.cpu.features.isEnabled(@intFromEnum(std.Target.wasm.Feature.atomics)) or |
| 2437 | !target_info.target.cpu.features.isEnabled(@intFromEnum(std.Target.wasm.Feature.bulk_memory))) | 2441 | !target_info.target.cpu.features.isEnabled(@intFromEnum(std.Target.wasm.Feature.bulk_memory))) |
| 2438 | { | 2442 | { |
| 2439 | fatal("'atomics' and 'bulk-memory' features must be enabled to use shared memory", .{}); | 2443 | fatal("'atomics' and 'bulk-memory' features must be enabled to use shared memory", .{}); |
| 2444 | } | ||
| 2445 | break :blk; | ||
| 2446 | } | ||
| 2447 | |||
| 2448 | // Single-threaded is the default for WebAssembly, so only when the user specified `-fno_single-threaded` | ||
| 2449 | // can they enable multithreaded WebAssembly builds. | ||
| 2450 | const is_single_threaded = single_threaded.?; | ||
| 2451 | if (!is_single_threaded) { | ||
| 2452 | fatal("'-fno-single-threaded' requires the linker feature shared-memory to be enabled using '--shared-memory'", .{}); | ||
| 2440 | } | 2453 | } |
| 2441 | } | 2454 | } |
| 2442 | 2455 |
src/target.zig+5| ... | @@ -207,6 +207,11 @@ pub fn supports_fpic(target: std.Target) bool { | ... | @@ -207,6 +207,11 @@ pub fn supports_fpic(target: std.Target) bool { |
| 207 | return target.os.tag != .windows and target.os.tag != .uefi; | 207 | return target.os.tag != .windows and target.os.tag != .uefi; |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | pub fn isSingleThreaded(target: std.Target) bool { | ||
| 211 | _ = target; | ||
| 212 | return false; | ||
| 213 | } | ||
| 214 | |||
| 210 | /// Valgrind supports more, but Zig does not support them yet. | 215 | /// Valgrind supports more, but Zig does not support them yet. |
| 211 | pub fn hasValgrindSupport(target: std.Target) bool { | 216 | pub fn hasValgrindSupport(target: std.Target) bool { |
| 212 | switch (target.cpu.arch) { | 217 | switch (target.cpu.arch) { |