WebAssembly with Embedded feature multithreading

Currently I run Swift compiled for wasm32-unknown-none-wasm triple inside multiple web workers with SharedArrayBuffer memory between them. So my setup is multithreaded.

I wanted to use conditional compilation to separate my code:

#if _runtime(_multithreaded)
print("multithreaded")
#else
print("singlethreaded")
#endif

Is it possible to configure compiler with arguments to understand it's current runtime mode?
Like -pthread in clang.

been looking into the wasm32-unknown-none-wasm triple as well. Since none is so lean, the driver usually needs explicit feature flags like -Xcc -mattr=+atomics,+bulk-memory to trigger those internal defines.

By the way, Ig I just landed a fix for the issue you reported (#9830) regarding noneOS platform mapping, so Package.swift conditions for these triples should be working soon.

Have you tried passing the atomics attributes through the frontend to see if _runtime(_multithreaded) picks it up, or are you looking for a formal -pthread style flag in the Swift driver?

Here is my compilation command:

swift build -c release --triple wasm32-unknown-none-wasm \
		-Xbuild-tools-swiftc -DWASM \
		-Xswiftc -enable-experimental-feature -Xswiftc Embedded \
		-Xswiftc -enable-experimental-feature -Xswiftc Extern \
		-Xcc -pthread \
		-Xcc -matomics \
		-Xcc -mbulk-memory \
		-Xcc -msimd128 \
		-Xlinker --shared-memory \
		-Xlinker --import-memory \
		-Xlinker --max-memory=4294967296

As I understand -Xcc applies only on C compiler. I'm asking how to configure Swift compiler to know that it compiles code for multithreading purposes.

Hi Sergey,
so sorry for responding late.
Yes that makes total sense. The -Xcc flags only pass to Clang, so the Swift compiler never sees those target features and skips the _runtime(_multithreaded) check entirely.

To fix it, swap out those -Xcc -target-feature +atomics and -Xcc -target-feature +bulk-memory lines for this in your swift build command:

-Xswiftc -Xfrontend -Xswiftc -target-feature -Xswiftc -Xfrontend -Xswiftc +atomics \
-Xswiftc -Xfrontend -Xswiftc -target-feature -Xswiftc -Xfrontend -Xswiftc +bulk-memory \


(Keep your existing -Xcc -pthread and linker flags as-is.)

Give that a try and let me know if the compiler finally recognizes it!
and perhaps @dschaefer2 or @jakepetroules could help you further with this.

That's incorrect, and has been discussed on Forums before. -Xcc is the supported way to enable or disable features of WebAssembly and other instruction sets.

1 Like

Thanks for the correction and for linking that discussion, Max! That’s my mistake, completely misunderstood the routing there.

From an architectural standpoint, how does that state sync actually work for Wasm? When -Xcc -mattr=+atomics is passed, does the Swift driver parse the Clang arguments to populate its own frontend feature checks, or do Swift and Clang share a unified underlying LLVM target configuration state during the build?

@purpln Since Max confirmed your -Xcc flags are actually being routed correctly by the driver, it seems like your original command is the right approach. Are you using a custom-built Swift toolchain or SDK that has multithreading enabled in the standard library? I'm wondering if the underlying none OS stdlib wasn't specifically compiled with threading support, which might cause the _runtime(_multithreaded) check to fail even with the right compiler flags.

Correct.

IIRC, the only target triple with truthy _runtime(_multithreaded) is wasm32-unknown-wasip1-threads.

1 Like

Yeah, that makes sense. If that's the only target with it enabled out of the box, it really highlights the limitations of relying on pre-built stdlibs for custom environments. and which is what we are trying to fix with GSoC this year.

And I've been digging into our cross-compilation setup and I actually started looking at how Rust and Zig handle this to get some context. Zig seems to do its own thing with built-in sysroots which is probably too much for us, but Rust’s -Z build-std seems like a much better fit, treating the libraries as modular products that build on-the-fly for a specific target.

Is it feasible for me to dive a bit more into this to actually understand what a finished implementation offers, and probably even some downsides or bottlenecks?