zig

fork of https://codeberg.org/ziglang/zig
Log | Tree | Refs | README | LICENSE

commit 87b8a0567b0f54415aeecd879d3f1a4e12014d22 (tree)
parent e06ab1b0107e8a6a1720703a6df0f61f535b5e5a
Author: Luuk de Gram <luuk@degram.dev>
Date:   Mon, 26 Jun 2023 19:10:34 +0200

default to single-threaded for WebAssembly

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.

Diffstat:
Mlib/std/Thread.zig | 4++++
Msrc/Compilation.zig | 2+-
Msrc/main.zig | 27++++++++++++++++++++-------
Msrc/target.zig | 5+++++
4 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig @@ -919,6 +919,10 @@ const WasiThreadImpl = struct { /// Bootstrap procedure, called by the host environment after thread creation. export fn wasi_thread_start(tid: i32, arg: *Instance) void { + if (builtin.single_threaded) { + // ensure function is not analyzed in single-threaded mode + return; + } __set_stack_pointer(arg.thread.memory.ptr + arg.stack_offset); __wasm_init_tls(arg.thread.memory.ptr + arg.tls_offset); @atomicStore(u32, &WasiThreadImpl.tls_thread_id, @intCast(tid), .SeqCst); diff --git a/src/Compilation.zig b/src/Compilation.zig @@ -1029,7 +1029,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { const include_compiler_rt = options.want_compiler_rt orelse needs_c_symbols; - const must_single_thread = options.target.isWasm() and !options.linker_shared_memory; + const must_single_thread = target_util.isSingleThreaded(options.target); const single_threaded = options.single_threaded orelse must_single_thread; if (must_single_thread and !single_threaded) { return error.TargetRequiresSingleThreaded; diff --git a/src/main.zig b/src/main.zig @@ -2428,15 +2428,28 @@ fn buildOutputType( link_libcpp = true; } - if (target_info.target.cpu.arch.isWasm() and linker_shared_memory) { - if (output_mode == .Obj) { - fatal("shared memory is not allowed in object files", .{}); + if (target_info.target.cpu.arch.isWasm()) blk: { + if (single_threaded == null) { + single_threaded = true; } + if (linker_shared_memory) { + if (output_mode == .Obj) { + fatal("shared memory is not allowed in object files", .{}); + } - if (!target_info.target.cpu.features.isEnabled(@intFromEnum(std.Target.wasm.Feature.atomics)) or - !target_info.target.cpu.features.isEnabled(@intFromEnum(std.Target.wasm.Feature.bulk_memory))) - { - fatal("'atomics' and 'bulk-memory' features must be enabled to use shared memory", .{}); + if (!target_info.target.cpu.features.isEnabled(@intFromEnum(std.Target.wasm.Feature.atomics)) or + !target_info.target.cpu.features.isEnabled(@intFromEnum(std.Target.wasm.Feature.bulk_memory))) + { + fatal("'atomics' and 'bulk-memory' features must be enabled to use shared memory", .{}); + } + break :blk; + } + + // Single-threaded is the default for WebAssembly, so only when the user specified `-fno_single-threaded` + // can they enable multithreaded WebAssembly builds. + const is_single_threaded = single_threaded.?; + if (!is_single_threaded) { + fatal("'-fno-single-threaded' requires the linker feature shared-memory to be enabled using '--shared-memory'", .{}); } } diff --git a/src/target.zig b/src/target.zig @@ -207,6 +207,11 @@ pub fn supports_fpic(target: std.Target) bool { return target.os.tag != .windows and target.os.tag != .uefi; } +pub fn isSingleThreaded(target: std.Target) bool { + _ = target; + return false; +} + /// Valgrind supports more, but Zig does not support them yet. pub fn hasValgrindSupport(target: std.Target) bool { switch (target.cpu.arch) {