-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: implement memory.atomic.notify,wait32,wait64 #5255
feat: implement memory.atomic.notify,wait32,wait64 #5255
Conversation
1e277e7
to
860d9aa
Compare
The rustix crate wasmtime already uses has futex support. memory.atomic.{notify,wait32,wait64} are modeled after the futex model afaik, not the thread parking model that parking_lot_core exposes. In addition parking_lot_core is modelled on top of futex on Linux. As such using |
Didn't think of wait64. That is indeed an issue. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR here! Would it be possible to add tests with this as well? I'd ideally like to grow the threads test suite to be as comprehensive as we can reasonably get it as features land.
Internally I think there's a few things about the wasm semantics to touch up. You mention i64
vs u64
, and in these intrinsics you'll want to cast timeout: u64
to timeout: i64
since the spec says that it's treated as a signed number. Additionally I think you'll want to handle timeout == 0
differently where it looks like now that equates to now deadline but with the spec that equates to a zero deadline.
For error handling I think it's ok to avoid TrapReason::user_with_backtrace
since all of the error conditions here should be infallible, so I think they'd best be replaced with a .unwrap()
where necessary.
Finally, for the low level implementation, I personally do not want to use parking-lot internally here. I reviewed it historically and I don't think it's suitable for Wasmtime where any mistake is a security issue. I think it would be better to build this with condvars/mutexes/etc within the SharedMemory
structure for state management. That furthermore removes the need for global state management here and additionally enables a more flexible implementation that takes into account async
one day, if necessary.
860d9aa
to
95df1a8
Compare
Implemented |
Err... SIGKILL is hard in the CI :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks reasonable to me, thanks!
One thing that we'll want to add is embedder APIs to interact with these instructions as well. For eample I think we'll want SharedMemory::{notify,wait32,wait64}
which are basically the same wasm instructions but callable by wasmtime
embedders, allowing programmatic interactions with threads as well. That doesn't need to be added necessarily in this PR, however, but it might motivate movement of the implementation of these instructions into wasmtime_runtime::SharedMemory
instead of keeping it in libcalls in the long run.
Oh, and to reiterate, this will require tests to merge. |
@alexcrichton wouldn't that need threading support first, to test it in full action? |
It would indeed, and everything necessary should be implemented in Wasmtime today. There are, for example, already tests with threads. |
74003f8
to
eb5bc23
Compare
Addressed some of the issues, working on the others. Now tested with my real pthread example. |
35dadcf
to
b06836f
Compare
So, I setup the aarch64 cross compile locally and it passes... just takes some time:
|
3bd3fb6
to
c5d9a29
Compare
@alexcrichton added one basic test... more to follow |
c5d9a29
to
20a2e37
Compare
20a2e37
to
91e2e72
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test you added looks good, thanks! I think it might be also good to perhaps have a small mutex-like implementation with 2-4 threads incrementing a shared counter perhaps and ensure that the final count is as expected as well.
Otherwise others tests to add would be the basic single-threaded operational semantics of these instructions in the face of no threads. You may want to check the test suite but IIRC it's not very comprehensive (and we're almost certainly not running it at this time). Anything missing there can be added as a manual *.wast
test or similar. I'm thinking things like:
wait32
doesn't block if the values don't matchwait32
eventually times out if the values matchwait32
traps on unshared memoriesnotify
returns 0 on unshared memoriesnotify
returns 0 with 0 waitersnotify
returns the number woken (this one you can't precisely test for but you could add a sleep for ~100ms and otherwise retry the test N times until it works)wait32
andnotify
require in-bounds and aligned addresses
Much of this can be expressed with a *.wast
test I think. It all should theoretically be covered by the upstream test suite but you'd need to check to make sure it is. I can help out with this if you're having trouble.
Subscribe to Label Actioncc @peterhuene
This issue or pull request has been labeled: "wasmtime:api"
Thus the following users have been cc'd because of the following labels:
To subscribe or unsubscribe from this label, edit the |
added |
1b680f2
to
8c0b176
Compare
ad8c894
to
24d61bb
Compare
24d61bb
to
a04786d
Compare
Subscribe to Label Actioncc @fitzgen
This issue or pull request has been labeled: "fuzzing"
Thus the following users have been cc'd because of the following labels:
To subscribe or unsubscribe from this label, edit the |
Added the parking_spot crate, which provides the needed registry for the operations. Signed-off-by: Harald Hoyer <[email protected]>
The threads spec test wants "unaligned atomic" instead of "misaligned memory access". Signed-off-by: Harald Hoyer <[email protected]>
Signed-off-by: Harald Hoyer <[email protected]>
without pooling and reference types. Also "shared_memory" is added to the "spectest" interface. Signed-off-by: Harald Hoyer <[email protected]>
checking that notify with 0 waiters returns 0 on shared and non-shared memory. Signed-off-by: Harald Hoyer <[email protected]>
05efbe4
to
b6a485e
Compare
- return 2 - timeout for 0 - return 2 - timeout for 1000ns - return 1 - invalid value Signed-off-by: Harald Hoyer <[email protected]>
Signed-off-by: Harald Hoyer <[email protected]>
Signed-off-by: Harald Hoyer <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok this all looks good to me so I'm going to mark this for merging. Thanks again @haraldh for your work here!
Added the parking_spot crate, which provides the needed registry for the operations.
Tests include:
wait32
doesn't block if the values don't matchwait32
eventually times out if the values matchwait32
traps on unshared memoriesnotify
returns 0 on unshared memoriesnotify
returns 0 with 0 waitersnotify
returns the number woken (this one you can't precisely test for but you could add a sleep for ~100ms and otherwise retry the test N times until it works)wait32
andnotify
require in-bounds and aligned addresses