Stream: wasi-threads

Topic: pthreads example not working in any runtime


view this post on Zulip Bastian Müller (Dec 02 2023 at 23:11):

I've tried building https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/samples/multi-thread/wasm-apps/main_global_atomic.c with the latest WASI SDK (v20), as well as latest master, and it fails to run in both wasmtime and wamr (iwasm):

$ WASMTIME_BACKTRACE_DETAILS=1 wasmtime -W threads=y -S threads=y pthreads.wasm
Starting threads
Thread creation failed
Thread creation failed
Thread creation failed
Thread creation failed
Joining threads
Value of counter after update: 0 (expected=40)
Error: failed to run main module `pthreads.wasm`

Caused by:
    0: failed to invoke command default
    1: error while executing at wasm backtrace:
           0:  0x5a8 - __main_argc_argv
                           at /home/bastian/Documents/pthreads/main.c:58:9
           1: 0x2bb4 - <unknown>!__main_void
           2:  0x34b - <unknown>!_start
    2: wasm trap: wasm `unreachable` instruction executed
$ iwasm  pthreads.wasm
Starting threads
Thread creation failed
Thread creation failed
Thread creation failed
Thread creation failed
Joining threads
Value of counter after update: 0 (expected=40)
Exception: unreachable

Is this a problem with the WASI SDK or the runtimes?

view this post on Zulip Christof Petig (Dec 03 2023 at 14:58):

I guess the problem could involve how you compile and link your C program. I have successfully used iwasm together with both C++ (SDK v20) and Rust threads (wasm32-wasi-preview1-threads) - the tricky part is whether to import the memory or not.

view this post on Zulip Christof Petig (Dec 03 2023 at 15:02):

Oh, I see, this example still uses the somewhat outdated wasm32 target with wamr specific host extensions. Please give wasm32-wasi-(preview1-)threads a try.

There is a newer wasi-threads example in WAMR as well.

view this post on Zulip Christof Petig (Dec 03 2023 at 15:09):

But even this example predates SDK v20 and makes no use of its built in pthread API. I would try a standard minimal pthread example and compile to wasm32-wasi-threads.

view this post on Zulip Bastian Müller (Dec 03 2023 at 23:37):

@Christof Petig Just to clarify:

@Andrew Brown do you have any ideas or a good simple example that uses pthreads?

view this post on Zulip Enrico Loparco (Dec 04 2023 at 09:04):

The example builds fine for me

# From WAMR root folder
$ cd samples/multi-thread
$ mkdir build && cd build
$ cmake .. -DCMAKE_BUILD_TYPE=Debug -GNinja
$ ninja
$ ./iwasm wasm-apps/main_global_atomic.wasm
Value of counter after update: 4000 (expected=4000)

If you want to use WASI threads instead, I suggest you follow https://github.com/bytecodealliance/wasm-micro-runtime/tree/main/samples/wasi-threads

view this post on Zulip Andrew Brown (Dec 04 2023 at 18:27):

@Bastian Müller, you could always try out the even simpler example from the original blog post, though I suspect the build command might need to be looked at again. How are you building main_global_atomic.c? I'm a bit confused by the back trace pointing at /home/bastian/Documents/pthreads/main.c:58:9 because the original file does not have that many lines. How do I reproduce that Wasmtime failure?

Until now, one piece missing from WebAssembly standalone engines was the ability to spawn threads.Browsers have had this ability for some time via Web Workers, but standalone engines had no standardway to do this. This post describes the...

view this post on Zulip Bastian Müller (Dec 10 2023 at 00:49):

Enrico Loparco said:

The example builds fine for me
[...]

If you want to use WASI threads instead, I suggest you follow https://github.com/bytecodealliance/wasm-micro-runtime/tree/main/samples/wasi-threads

Like I mentioned above, I'm not using the build system from the example, but am using the latest WASI SDK targeting wasm32-wasi-threads. I saw that wamr provides also an older, direct pthreads implementation, but I wasn't using that.

view this post on Zulip Bastian Müller (Dec 10 2023 at 00:57):

@Andrew Brown Thank you for pointing me to the blog post -- I had only looked at the wasi-threads, wasmtime, and wamr repos, but hadn't realized there was a great write-up with an overview and details of the extension, as well as an example.

The blog post had the hint I was missing: It's important to import and export the memory, as well as specify a large enough maximum memory _at build-time_, i.e. pass e.g. -Wl,--import-memory,--export-memory,--max-memory=67108864. I had tried both importing and exporting the memory, but that alone didn't work, and also tried specifying max memory when _executing_ the built module, which also didn't help (obvious in hind-sight).

Building the example with the options above makes it work in both wamr and wasmtime.

It might be worth pointing this subtle, but very important detail of specifying the maximum memory during compilation in the documentation (not sure where is best). Without it, the build succeeds, but like I mentioned in my original question, the programs silently fail, and it isn't obvious why.

Having a working pthreads example module, I was able to complete the threads implementation (shared memory, atomic operations, and wasi-threads) in w2c2 :smile: :tada: (pthreads example: https://github.com/turbolent/w2c2/pull/91/files#diff-1125cd266d1f65514d4efbdf3eb6537294f511c4fb92188e6cdd1985defbbf0e)

Thank you everyone for the help!

Translates WebAssembly modules to portable C. Contribute to turbolent/w2c2 development by creating an account on GitHub.

view this post on Zulip Enrico Loparco (Dec 10 2023 at 21:00):

Like I mentioned above, I'm not using the build system from the example, but am using the latest WASI SDK targeting wasm32-wasi-threads.

I should have been more precise, I meant this one specifically
https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/samples/wasi-threads/wasm-apps/CMakeLists.txt#L35-L43


Last updated: Nov 22 2024 at 17:03 UTC