Stream: wasi-threads

Topic: chicken_egg


view this post on Zulip Harald Hoyer (Oct 12 2022 at 10:28):

After patching Config with:

diff --git a/crates/wasmtime/src/config.rs b/crates/wasmtime/src/config.rs
index 54073aa83..18e7f1750 100644
--- a/crates/wasmtime/src/config.rs
+++ b/crates/wasmtime/src/config.rs
@@ -188,7 +188,10 @@ impl Config {
             wasm_backtrace: true,
             wasm_backtrace_details_env_used: false,
             native_unwind_info: true,
-            features: WasmFeatures::default(),
+            features: WasmFeatures {
+                threads: true,
+                ..Default::default()
+            },
             #[cfg(feature = "async")]
             async_stack_size: 2 << 20,
             async_support: false,

I got this far with a patched wasi-libc:

 cargo run -- ~/pthread_create_example
    Finished dev [unoptimized + debuginfo] target(s) in 0.23s
     Running `target/debug/wasmtime /home/harald/pthread_create_example`
Error: failed to run main module `/home/harald/pthread_create_example`

Caused by:
    0: failed to instantiate "/home/harald/pthread_create_example"
    1: unknown import: `wasi_snapshot_preview2::thread_spawn` has not been defined

view this post on Zulip Harald Hoyer (Oct 12 2022 at 14:10):

ok, with a wasi_snapshot_preview2::thread_spawn stub function I get:

Error: failed to run main module `/home/harald/pthread_create_example`

Caused by:
    0: failed to invoke command default
    1: wasm trap: out of bounds memory access
       wasm backtrace:
           0:  0x298 - <unknown>!__wasm_init_memory

view this post on Zulip Harald Hoyer (Oct 12 2022 at 14:39):

@Andrew Brown ^^^

view this post on Zulip Andrew Brown (Oct 12 2022 at 20:17):

Good to see you are making some progress; not sure what to make of the wasm trap: out of bounds memory access--is there something wrong in wasi-libc? (BTW, you probably don't need to patch Wasmtime since you should be alter the configuration from the CLI; just use cargo run -- --wasm-features threads ... or something like that).

view this post on Zulip Andrew Brown (Oct 12 2022 at 20:21):

E.g., if your Wasm file's memory is declared like (memory 0 ...), then somewhere in the Wasm file there needs to be a memory.grow or all memory accesses will be out of bounds.

view this post on Zulip Andrew Brown (Oct 12 2022 at 20:25):

Another thought, unrelated to the above, is that the wasi-threads implementation I'm working on is not the only piece to get a working end-to-end example in Wasmtime. Wasmtime only has stub implementations for wait and notify so those need to be implemented as well since they are used by, e.g., pthread_join in wasi-libc.

view this post on Zulip Andrew Brown (Oct 12 2022 at 20:25):

those need to be implemented

Many chickens, many eggs...

view this post on Zulip Harald Hoyer (Oct 14 2022 at 11:30):

yeah, it's the --shared-memory linker directive causing the "__wasm_init_memory" trap... set also by -pthread CC option

view this post on Zulip Harald Hoyer (Oct 14 2022 at 13:16):

https://github.com/WebAssembly/tool-conventions/blob/main/Linking.md#shared-memory-and-passive-segments

The memory.init instructions that initialize these passive segments and the data.drop instructions that mark them collectible will be emitted into a synthetic function __wasm_init_memory that is made the WebAssembly start function and called automatically on instantiation but is not exported. __wasm_init_memory shall perform any synchronization necessary to ensure that no thread returns from instantiation until memory has been fully initialized, even if a module is instantiated on multiple threads simultaneously.

Conventions supporting interoperatibility between tools working with WebAssembly. - tool-conventions/Linking.md at main · WebAssembly/tool-conventions

view this post on Zulip Harald Hoyer (Oct 14 2022 at 13:16):

so, it's the start function created by the linker

view this post on Zulip Harald Hoyer (Oct 14 2022 at 14:33):

@Andrew Brown

(;@2b6   ;)        memory.atomic.notify

view this post on Zulip Harald Hoyer (Oct 14 2022 at 14:34):

    0: failed to invoke `_start`
    1: wasm trap: out of bounds memory access
       wasm backtrace:
           0:  0x2b6 - <unknown>!__wasm_init_memory

for this one

view this post on Zulip Harald Hoyer (Oct 14 2022 at 14:35):

this is linker generated code, so it feels like wasmtime is missing something here?

view this post on Zulip Harald Hoyer (Oct 14 2022 at 14:49):

    Err(
        anyhow::anyhow!("unimplemented: wasm atomics (fn memory_atomic_notify) unsupported",)
            .into(),
    )

view this post on Zulip Andrew Brown (Oct 14 2022 at 15:37):

Yeah, this is what I meant up above:

Wasmtime only has stub implementations for wait and notify so those need to be implemented as well since they are used by...

view this post on Zulip Andrew Brown (Oct 14 2022 at 15:39):

I will hopefully have the WASI bindings for wasi-threads available in some form today but one of us needs to take a look at implementing wait and notify to make an end-to-end example work. (Also, you might be interested in @Dan Gohman's recent change to avoid running constructors twice in wasi-libc: https://github.com/WebAssembly/wasi-libc/pull/339).

Use an atomic compare-and-swap for checking whether constructors have been run, when threads are enabled.

view this post on Zulip Andrew Brown (Oct 15 2022 at 00:01):

@Harald Hoyer, the progress I have made on a WIP implementation of wasi-threads is available on a branch of that name in my fork: https://github.com/bytecodealliance/wasmtime/compare/main...abrown:wasmtime:wasi-threads. The unstable feature get_mut_unchecked is a particularly heinous hack that will need to get resolved before I consider putting this up as a PR, even as a draft. I have documented the issues I observed in implementing this in the commit comments (note that this change stacks on #5054, included in the branch). Please use this change with the understanding that it is highly experimental, unsafe (no host import locking), and can easily be broken.

A fast and secure runtime for WebAssembly. Contribute to bytecodealliance/wasmtime development by creating an account on GitHub.
wiggle looks for an exported Memory named "memory" to use for its guest slices. This change allows it to use a SharedMemory if this is the kind of memory used for the export.

view this post on Zulip Andrew Brown (Oct 15 2022 at 00:02):

(cc: @Alex Crichton, @Dan Gohman, who may be interested as well)

view this post on Zulip Harald Hoyer (Oct 17 2022 at 13:56):

diff --git a/tests/all/cli_tests.rs b/tests/all/cli_tests.rs
index fa13f32c4..002800bf0 100644
--- a/tests/all/cli_tests.rs
+++ b/tests/all/cli_tests.rs
@@ -404,13 +404,16 @@ fn run_threads() -> Result<()> {
     let wasm = build_wasm("tests/all/cli_tests/threads.wat")?;
     let stdout = run_wasmtime(&[
         "run",
+        "--wasi-modules",
+        "experimental-wasi-threads",
+        "--wasm-features",
+        "threads",
+        "--disable-cache",
         "--",
         wasm.path().to_str().unwrap(),
-        "--wasi-modules experimental-wasi-threads",
-        "--wasm-features threads",
-        "--disable-cache",
     ])?;

view this post on Zulip Harald Hoyer (Oct 17 2022 at 13:56):

@Andrew Brown ^^

view this post on Zulip Harald Hoyer (Oct 17 2022 at 14:22):

@Andrew Brown here is an attempt for memory_atomic_wait32 and memory_atomic_notify
https://github.com/haraldh/wasmtime/commit/2341d1bb1ae2892992b977c4162d495233d1700b

based upon Linux futex Signed-off-by: Harald Hoyer <harald@profian.com>

view this post on Zulip Harald Hoyer (Oct 17 2022 at 14:25):

I kind of can report success, although the new threads do not have the same SharedMemory it seems

view this post on Zulip Harald Hoyer (Oct 17 2022 at 14:27):

@Andrew Brown also I have made a PR to fix validate_atomic_addr() .. https://github.com/bytecodealliance/wasmtime/pull/5063

Apparently addr is a pointer to real memory. Signed-off-by: Harald Hoyer harald@profian.com

view this post on Zulip Harald Hoyer (Oct 17 2022 at 14:33):

So, if I use clang -pthread ... it generates code with:

(memory (;0;) 2 2 shared)
(export "memory" (memory 0))

unless I use -Xlinker --import-memory, which produces:

(import "env" "memory" (memory (;0;) 2 2 shared))

but then:

Error: failed to run main module `/home/harald/pthread_create_example`

Caused by:
    0: failed to invoke command default
    1: missing required memory export
       wasm backtrace:
           0:  0x751 - <unknown>!__wasi_fd_write
           1:  0x953 - <unknown>!writev
           2:  0x9e4 - <unknown>!__stdio_write
           3: 0x119d - <unknown>!vfprintf
           4: 0x4089 - <unknown>!fprintf
           5: 0x6fa8 - <unknown>!__pthread_create
           6:  0x4ab - <unknown>!__original_main
           7:  0x2d5 - <unknown>!_start

view this post on Zulip Andrew Brown (Oct 17 2022 at 14:39):

re: your initial patch to fix the test's CLI arguments, thanks! I think that is right. I still see test failures due to the WAT reading-writing though, so something else needs fixing

view this post on Zulip Andrew Brown (Oct 17 2022 at 14:43):

re: the shared memory, I believe that for now we must both import a shared memory (so that all of the thread instances share the same one) AND export that same memory (so that Wiggle can use it for buffers in host calls)

view this post on Zulip Andrew Brown (Oct 17 2022 at 14:45):

I can't tell from your last example if the emitted module had both the import and the export, but it seems as it does not due to the error. I side-stepped this by hand-crafting the WAT test. I would think there is a way to tell Clang to do both?

view this post on Zulip Harald Hoyer (Oct 17 2022 at 14:57):

btw, I found in crates/wasmtime/src/memory.rs:695 :

/// let shared_memory = SharedMemory::new(&engine, MemoryType::shared(1, 2))?;
/// let module = Module::new(&engine, r#"(module (memory (import "" "") 1 2 shared))"#)?;
/// let instance = Instance::new(&mut store, &module, &[shared_memory.into()])?;

view this post on Zulip Harald Hoyer (Oct 17 2022 at 14:59):

and I have the feeling, that the SharedMemory returned from your crates/wasi-threads/src/lib.rs:add_to_linker() has to be used the same somehow

view this post on Zulip Harald Hoyer (Oct 17 2022 at 15:10):

Andrew Brown said:

I can't tell from your last example if the emitted module had both the import and the export, but it seems as it does not due to the error. I side-stepped this by hand-crafting the WAT test. I would think there is a way to tell Clang to do both?

It had only the import
❯ $CC $CFLAGS -Xlinker --help ~/pthread_create_example.c -o ~/pthread_create_example|fgrep memory
--import-memory Import memory from the environment
--initial-memory=<value>
Initial size of the linear memory
--max-memory=<value> Maximum size of the linear memory
--shared-memory Use shared linear memory
--stack-first Place stack at start of linear memory rather than after data

view this post on Zulip Harald Hoyer (Oct 17 2022 at 15:11):

Isn't export just fine, as clang does it with -pthread (which activates the --shared-memory linker flag)?

view this post on Zulip Andrew Brown (Oct 17 2022 at 15:19):

Harald Hoyer said:

and I have the feeling, that the SharedMemory returned from your crates/wasi-threads/src/lib.rs:add_to_linker() has to be used the same somehow

Ah, so here's how that happens using a Linker, which in this case is a more indirect way of defining the imports: if wasi_threads::add_to_linker finds a shared memory import it must satisfy, it generates a new SharedMemory and adds it to the Linker here. (add_to_linker should only be called once, so there should only be one shared memory to speak of). Then when the Linker is used to instantiate the child module here, that shared memory will be imported to the child instance.

A fast and secure runtime for WebAssembly. Contribute to bytecodealliance/wasmtime development by creating an account on GitHub.
A fast and secure runtime for WebAssembly. Contribute to bytecodealliance/wasmtime development by creating an account on GitHub.

view this post on Zulip Andrew Brown (Oct 17 2022 at 15:20):

Harald Hoyer said:

Isn't export just fine, as clang does it with -pthread (which activates the --shared-memory linker flag)?

At least for now, until several things change, we will need to have the shared memory be both imported and exported.

view this post on Zulip Andrew Brown (Oct 17 2022 at 15:20):

Andrew Brown said:

re: the shared memory, I believe that for now we must both import a shared memory (so that all of the thread instances share the same one) AND export that same memory (so that Wiggle can use it for buffers in host calls)

view this post on Zulip Sam Clegg (Oct 18 2022 at 20:38):

Andrew Brown said:

Andrew Brown said:

re: the shared memory, I believe that for now we must both import a shared memory (so that all of the thread instances share the same one) AND export that same memory (so that Wiggle can use it for buffers in host calls)

Why not just export it? Then the runtime can use the exported shared memory when it creates new threads. At least this is how we do it on the web currently.

view this post on Zulip Sam Clegg (Oct 18 2022 at 20:40):

Having the runtime create a memory and pass it in seems like extra work that the runtime doesn't need to do. In emscripten we avoid creating the memory in the loader in almost all cases these days.

view this post on Zulip Andrew Brown (Oct 18 2022 at 21:07):

But we want the memory to actually be shared between all the threads: if the parent thread creates it then the only way to make sure the child threads use that same linear memory is some engine magic. By importing the shared memory, both the parent and the child threads can use the same memory in a Wasm-friendly way.

view this post on Zulip Sam Clegg (Oct 18 2022 at 21:49):

Andrew Brown said:

But we want the memory to actually be shared between all the threads: if the parent thread creates it then the only way to make sure the child threads use that same linear memory is some engine magic. By importing the shared memory, both the parent and the child threads can use the same memory in a Wasm-friendly way.

Oh, you are completely correct, please ignore me :) In emscripten we create the memory (SAB) in the loader code in the case of the pthreads. Doh

view this post on Zulip Dan Gohman (Oct 19 2022 at 00:11):

On the Web, with Worker-based threads, does a trap in one thread automatically take down the other threads, or does Emscripten implement this behavior in JS?

view this post on Zulip Sam Clegg (Oct 19 2022 at 14:25):

Emscripten has to implement the behavior internally. Basically, any uncaught exception in a worker is proxied back to the main thread an results in an abort that kill all threads/workers.

view this post on Zulip Harald Hoyer (Oct 19 2022 at 14:45):

@Andrew Brown So, I can confirm threading works ... just one big problem: If I read that correct WasiCtx is not thread safe and is shared to all threads mutable, which leads to unwanted strange side effects. Or, if WasiCtx is not shared mutable, how can they share state change?

view this post on Zulip Harald Hoyer (Oct 19 2022 at 14:47):

@Dan Gohman ? ^^

view this post on Zulip Andrew Brown (Oct 19 2022 at 15:07):

@Dan Gohman and I were just discussing this a couple of days ago. I was thinking of placing a mutex or read-write lock around each WASI context but struggling to find a refactoring in which this can be done optionally, so that users who do not want threads can avoid the locking overhead.

view this post on Zulip Andrew Brown (Oct 19 2022 at 15:08):

Maybe for your use case it makes sense to always lock...

view this post on Zulip Harald Hoyer (Oct 19 2022 at 15:09):

Some global locks defy the use of threading. So while one thread wants to listen for a connection and waits, another cannot write.

view this post on Zulip Harald Hoyer (Oct 19 2022 at 15:11):

Then there is the problem of RwLockWriteGuard not being Send, which needs to be with async and await. And WasiCtx being created from non async code.

view this post on Zulip Harald Hoyer (Oct 19 2022 at 15:14):

anyway, the whole Table is a problem

view this post on Zulip Harald Hoyer (Oct 19 2022 at 16:29):

Let me retry again tomorrow.. I might have forgotten to Arc<> the RwLock<>s

view this post on Zulip Andrew Brown (Oct 19 2022 at 18:09):

Yeah, this sounds like the issues I was running into; what did you do re: the get_cx signature?

view this post on Zulip Sam Clegg (Oct 19 2022 at 20:20):

There are no shared tables in wasm (yet) so each instance/threads would get its own table.

view this post on Zulip Sam Clegg (Oct 19 2022 at 20:20):

(assuming you mean the indirection function table)

view this post on Zulip Harald Hoyer (Oct 20 2022 at 07:22):

Sam Clegg said:

(assuming you mean the indirection function table)

I mean the WasiCtx.table with the WasiFiles and directories and sockets.

view this post on Zulip Nathaniel McCallum (Oct 20 2022 at 13:30):

@Harald Hoyer WasiCtx as a whole is fairly problematic. I have rather strong opinions about its current implementation.

view this post on Zulip Harald Hoyer (Oct 20 2022 at 13:42):

So, I managed to Arc<RwLock>> the Table entries ... with RwLock from async_lock. Every now and then, I get:

thread 'wasi-thread-680788223' panicked at 'wasi-thread-680788223 exited unsuccessfully: Cannot wait on pending future: must enable wiggle "async" future and execute on an async Store

Although I enabled "wasmtime-wasi/tokio", "wasmtime/async"

view this post on Zulip Harald Hoyer (Oct 20 2022 at 13:45):

Here the debug output of some experimental C-lib with TLS and a simple pthread_create with two threads and join at the end.

 cargo +nightly run  --features wasi-threads  -- run --disable-cache --wasm-features threads --wasi-modules experimental-wasi-threads tt
    Finished dev [unoptimized + debuginfo] target(s) in 0.16s
     Running `target/debug/wasmtime run --disable-cache --wasm-features threads --wasi-modules experimental-wasi-threads tt`
m map = 0x11230
m &args->thread = 0x11228
m args->thread = 0x11230
m __wasi_thread_spawn(0x11220)
m ret = 28742
aligned_alloc sizeof(struct pthread) = 112 size=112
m map = 0x112c0
m &args->thread = 0x112b8
m args->thread = 0x112c0
m __wasi_thread_spawn(0x112b0)
wasi_thread_start start_args = 0x11220
wasi_thread_start &args->thread = 0x11228
wasi_thread_start args->thread = 0x11230
wasi_thread_start args->start_func = 0x1
wasi_thread_start args->start_arg = 0

 First thread processing

 Finished
__pthread_exit self = 0x11230
wasi_thread_start start_args = 0x112b0
wasi_thread_start &args->thread = 0x112b8
wasi_thread_start args->thread = 0x112c0
wasi_thread_start args->start_func = 0x1
wasi_thread_start args->start_arg = 0

 Second thread processing

 Finished
__pthread_exit self = 0x112c0

view this post on Zulip Harald Hoyer (Oct 20 2022 at 15:01):

@Andrew Brown I got a version of your ./tests/all/cli_tests/threads.wat, which reliably outputs:

Hello _start
Hello wasi_thread_start
Hello wasi_thread_start
Hello wasi_thread_start
Hello done

using memory.atomic.wait32 and memory.atomic.notify

view this post on Zulip Harald Hoyer (Oct 20 2022 at 15:02):

let me rework stuff and make PRs for the memory.atomic operations

view this post on Zulip Andrew Brown (Oct 20 2022 at 15:09):

Nice!

view this post on Zulip Andrew Brown (Oct 20 2022 at 15:21):

It's exciting that there is now a working example of all of this stuff working. Any more issues on the tool chain side? Now the trick is to see if we can find a way to make all of this upstreamable.

view this post on Zulip Andrew Brown (Oct 20 2022 at 15:22):

Do any of you want to meet today before going offline?

view this post on Zulip Harald Hoyer (Oct 21 2022 at 11:15):

Harald Hoyer said:

Every now and then, I get:

thread 'wasi-thread-680788223' panicked at 'wasi-thread-680788223 exited unsuccessfully: Cannot wait on pending future: must enable wiggle "async" future and execute on an async Store

Although I enabled "wasmtime-wasi/tokio", "wasmtime/async"

ok, managed to create a full async wasmtime version. No help needed anymore

view this post on Zulip Harald Hoyer (Oct 21 2022 at 12:23):

Looking at the wat, I see

  (global $__stack_pointer (;0;) (mut i32) i32.const 70000)

Is that something, which has to be TLS?

view this post on Zulip Harald Hoyer (Oct 21 2022 at 12:27):

interesting ... https://github.com/kettle11/wasm_set_stack_pointer

Expose a function from Rust WebAssembly that allows the host to set the stack pointer - GitHub - kettle11/wasm_set_stack_pointer: Expose a function from Rust WebAssembly that allows the host to set...

view this post on Zulip Harald Hoyer (Oct 21 2022 at 12:39):

ok, TIL global is TLS

view this post on Zulip Harald Hoyer (Oct 21 2022 at 14:36):

Andrew Brown said:

It's exciting that there is now a working example of all of this stuff working. Any more issues on the tool chain side? Now the trick is to see if we can find a way to make all of this upstreamable.

toolchain wise, the linker -Xlinker --import-memory works, but the re-export (export "memory" (memory 0)) is missing then

view this post on Zulip Harald Hoyer (Oct 21 2022 at 14:37):

other than that: CFLAGS=-pthread seems to work fine

view this post on Zulip Harald Hoyer (Oct 21 2022 at 15:13):

@Andrew Brown so, regarding the $__stack_pointer I would love to hear your advice.. should it be a wasm assembler trampoline, which first allocates the stack, sets the $__stack_pointer, then calls the real wasi_thread_start func?

view this post on Zulip Harald Hoyer (Oct 21 2022 at 15:14):

or can this be done from within wasmtime?

view this post on Zulip Andrew Brown (Oct 21 2022 at 15:31):

toolchain wise, the linker -Xlinker --import-memory works, but the re-export (export "memory" (memory 0)) is missing then

I looked into this and perhaps it is not yet possible in the toolchains. wasm-ld (from wasi-sdk) has --export=<value> to force a symbol to be exported but I don't think we can name memories with symbols yet (right, @Dan Gohman?). Perhaps there is some trick to convince wasm-ld to both import the memory and then turn around and export it, but I don't know it and don't see any mention in the docs either.

view this post on Zulip Andrew Brown (Oct 21 2022 at 15:35):

The "import then export" pattern seems to me a temporary thing, but perhaps this is still a useful feature to have in wasm-ld; what do you think @Dan Gohman, @Sam Clegg?

view this post on Zulip Andrew Brown (Oct 21 2022 at 15:40):

so, regarding the $__stack_pointer I would love to hear your advice

I think the linker is adding this, or perhaps you are triggering dynamic linking? I don't have the answer off-hand but my sense is that some modifications to __pthread_create in wasi-libc should make this work?

Conventions supporting interoperatibility between tools working with WebAssembly. - tool-conventions/Linking.md at 79d4b069951edf50546ba8d2f2ecdef24301b7a1 · WebAssembly/tool-conventions
WASI libc implementation for WebAssembly. Contribute to WebAssembly/wasi-libc development by creating an account on GitHub.

view this post on Zulip Andrew Brown (Oct 21 2022 at 15:42):

To answer your earlier question about this, yes, I think the stack pointer should be part of the TLS data.

view this post on Zulip Andrew Brown (Oct 21 2022 at 19:00):

(rereading what I wrote, I think I would edit the above to read: I think the _stack_ should be part of the TLS data and the stack pointer global should be set as part of the TLS data setup in pthread_create)

view this post on Zulip Dan Gohman (Oct 21 2022 at 19:04):

https://reviews.llvm.org/D135898 is a patch which I think should support "import than export"

view this post on Zulip Harald Hoyer (Oct 24 2022 at 11:14):

please enlighten me and correct my statements.

So, what I am might see in my execution is $__stack_pointer being used with the same index in threads (leading to UB), because nothing initializes $__stack_pointer on thread start. And even, if, to what value should it be set???? Seems like the value of $__stack_pointer is just the same on thread clone.

view this post on Zulip Harald Hoyer (Oct 24 2022 at 11:15):

@Dan Gohman ^^

view this post on Zulip Harald Hoyer (Oct 24 2022 at 11:53):

I guess, I will have to allocate memory and point the $__stack_pointer to it, using hand written functions without $__stack_pointer usage. The only remaining question is, how big should it be? Can I assume the current value of $__stack_pointer is a good size?

view this post on Zulip Harald Hoyer (Oct 24 2022 at 12:31):

Even, if I allocate new memory, would I need to clone the old one, because it could still reference memory from there?

view this post on Zulip Dan Gohman (Oct 24 2022 at 14:33):

I expect you'll want to have the parent allocate the memory for the new thread, before the new thread is created, so that you can just use regular malloc and friends. Then the thread entrypoint can just have a small bit of code that assigns the thread-local stack pointer to the allocated stack before doing anything else.

view this post on Zulip Harald Hoyer (Oct 24 2022 at 15:05):

got it working! :)

view this post on Zulip Harald Hoyer (Oct 24 2022 at 15:06):

How do I allow memory.grow? Currently I am manually editing:
(import "env" "memory" (memory (;0;) 2 2 shared)) to (import "env" "memory" (memory (;0;) 100 100 shared))

view this post on Zulip Harald Hoyer (Oct 24 2022 at 15:06):

@Dan Gohman ?

view this post on Zulip Harald Hoyer (Oct 24 2022 at 15:08):

But doing that I can create and join 10 threads :)

 cargo +nightly run  --features wasi-threads -- run --disable-cache --wasm-features bulk-memory,threads --wasi-modules experimental-wasi-threads tt
    Finished dev [unoptimized + debuginfo] target(s) in 0.12s
     Running `target/debug/wasmtime run --disable-cache --wasm-features bulk-memory,threads --wasi-modules experimental-wasi-threads tt`
 Thread 70064 processing
 Thread 70496 processing
 Thread 70352 processing
 Thread 70640 processing
 Thread 70928 processing
 Thread 69920 processing
 Thread 70784 processing
 Thread 70208 processing
 Thread 71072 processing
 Thread 71216 processing
 Thread 71216 still processing
 Thread 70928 still processing
 Thread 70784 still processing
 Thread 70208 still processing
 Thread 69920 still processing
 Thread 70496 still processing
 Thread 71072 still processing
 Thread 70352 still processing
 Thread 70640 still processing
 Thread 70064 still processing
Joined thread #0 69920
Joined thread #1 70064
Joined thread #2 70208
Joined thread #3 70352
Joined thread #4 70496
Joined thread #5 70640
Joined thread #6 70784
Joined thread #7 70928
Joined thread #8 71072
Joined thread #9 71216
All threads joined

view this post on Zulip Andrew Brown (Oct 24 2022 at 22:07):

Harald Hoyer said:

How do I allow memory.grow? Currently I am manually editing:
(import "env" "memory" (memory (;0;) 2 2 shared)) to (import "env" "memory" (memory (;0;) 100 100 shared))

I think you could use the --initial-memory and --max-memory flags in the wasm-ld to do this when you compile the Wasm program (see here). (Sort of a separate issue, but this raises the question in my mind whether MUSL's stack limit heuristic here should change for Wasm.)

WASI libc implementation for WebAssembly. Contribute to WebAssembly/wasi-libc development by creating an account on GitHub.

view this post on Zulip Harald Hoyer (Oct 25 2022 at 13:38):

So, here is my wasi-libc PR:
https://github.com/WebAssembly/wasi-libc/pull/343

and cleanup in pthread_exit() Signed-off-by: Harald Hoyer harald@profian.com

view this post on Zulip Harald Hoyer (Nov 11 2022 at 14:24):

so, here is a notify/wait implementation https://github.com/bytecodealliance/wasmtime/pull/5255 with parking_lot_core

CC @Alex Crichton

Use parking_lot_core, as this established crate does exactly what is needed here. WARNING memory_atomic_wait32() and memory_atomic_wait64() are called with an unsigned timeout: u64. The Threading p...

view this post on Zulip Harald Hoyer (Nov 11 2022 at 14:25):

CC @Amanieu

view this post on Zulip Harald Hoyer (Nov 16 2022 at 20:41):

@Alex Crichton could you please give me some hints on how to construct a multi threaded test?

view this post on Zulip Alex Crichton (Nov 16 2022 at 20:43):

There are some basic examples here

A fast and secure runtime for WebAssembly. Contribute to bytecodealliance/wasmtime development by creating an account on GitHub.

view this post on Zulip Alex Crichton (Nov 16 2022 at 20:43):

but I don't have much to offer beyond combining the primitives that the wasmtime crate API gives

view this post on Zulip Harald Hoyer (Nov 16 2022 at 20:58):

Thanks!

view this post on Zulip Harald Hoyer (Nov 17 2022 at 19:36):

@Alex Crichton first test added, more to come tomorrow

view this post on Zulip Steve Schoettler (Nov 18 2022 at 03:02):

@Alex Crichton Is there a way to access shared memory from a guest compiled from rust? All the examples I've seen are in wat so I don't know if the tooling supports it. Some related questions:

view this post on Zulip Alex Crichton (Nov 18 2022 at 03:58):

What build flags are needed to create a shared memory section?

I have not personally tried to get wasm32-wasi working, but I know abrown has and may know more. Otherwise though this is sufficient for me: RUSTFLAGS=-Ctarget-feature=+atomics,+bulk-memory,+mutable-globals cargo +nightly build -Zbuild-std=panic_abort,std --target wasm32-unknown-unknown

Can the shared memory be accessed as a byte slice?

Yes and not, it's just "memory". Rust only works with a single linear memory and with +atomics the singular linear memory is a shared memory.

Can Atomics from the std::sync::atomic package be mapped into that shared memory?

They can indeed, in +atomics mode atomic instructions are used for all atomic operations.

view this post on Zulip Steve Schoettler (Nov 18 2022 at 07:27):

Thanks. I think I'm still missing one or two pieces of information. How does the rust guest get a pointer to the shared memory region? It's clear how the host can get it, so the host could export a function that the guest could use to fetch the pointer, but I don't know if there's a way for the guest to obtain that pointer directly.
Then, can you use mem::transmute to tell rust that a set of bytes contain an Atomic? I did't know if llvm/wasm has a special way to access atomics (vs other rust data structures), so I wasn't sure if it would work for arbitrary memory locations

view this post on Zulip Alex Crichton (Nov 18 2022 at 15:23):

Rust doesn't really get a pointer to the region or anything specific like that, it just gets access to the whole thing. It's the same compilation model for Rust as before, it gets one linear memory, it's just that in this case it's a shared linear memory. If you mean whether the memory is defined locally or imported from the system then that's controlled by -Clink-arg=--import-memory or not

view this post on Zulip Harald Hoyer (Nov 25 2022 at 16:09):

@Alex Crichton @Andrew Brown first Draft for immutable WasiCtx
https://github.com/bytecodealliance/wasmtime/pull/5326

No description provided.

view this post on Zulip Harald Hoyer (Nov 25 2022 at 16:09):

Still some things to do, of course

view this post on Zulip Harald Hoyer (Nov 25 2022 at 16:12):

This time I managed to use std::sync::RwLock by removing async from WasiFile::num_ready_bytes(), so no need to use tokio RwLock and go full tokio.

view this post on Zulip Andrew Brown (Nov 25 2022 at 16:33):

Most of us in the US are out due to Thanksgiving; I will take a look on Monday.

view this post on Zulip Harald Hoyer (Nov 30 2022 at 13:09):

Hi @bstrie !

view this post on Zulip bstrie (Nov 30 2022 at 13:09):

Hello!

view this post on Zulip Harald Hoyer (Nov 30 2022 at 14:53):

@Andrew Brown @Alex Crichton meet @bstrie , he will take over my wasi threads work for now, as I was shifted to implement a page fault handler in our microkernel for lazy memory loading, to provide wasmtime with 2GB of mmaped static memory (default).


Last updated: Nov 22 2024 at 16:03 UTC