bytecodealliance / bytecodealliance/wasmtime
Epoch interruption of memory.atomic.wait* instructions
- Dominant language
- Rust
- Stars
- 18.6k
- Forks
- 1.8k
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 126
Description
#### Feature
Currently epoch interruption has no effect on memory.atomic.wait* instructions since they just block and give no opportunity for epoch checking to occur. It would be nice to make threads work with epoch interruption.
#### Benefit
Being able to interrupt threads that stale on waiting for something to happen on another thread.
I'm personally interested in being able to do the following with programs targeting `wasip1-threads`:
- Terminating all threads on some event (a trap, proc_exit, etc.)
- Pausing all threads for debug purposes
#### Implementation
I believe this problem can be solved by doing the following:
- Extending `wasmtime::runtime::vm::WaitResult` with an new case. (e.g. `Interrupted = 3`)
- Adding a function to notify all shared memories in engine to return that new case. Maybe even call it on each `Engine::increment_epoch`
- Wrapping each call to memory_atomic_wait* builtin function with a loop. That loop would check epoch and continue if returned value is `Interrupted`, and break otherwise. It may worth it to gate this transformation behind some condition, like weather epoch interruption is enabled, or a dedicated flag in `Config`.
This is what I initially tried to do on my own, but `wasmtime-internal-cranelift` crate scared me a bit, so I guess it is better to be done by someone who knows what to do.
I believe there is no need to try to do the same for fuel consumption.
#### Alternatives
Alternative 1. Almost the same can be done by transforming WASM. Same loop, but timeout is limited to, let's say, 10 ms. Not sure when to break that loop. It comes with huge performance penalty for programs that spawn lots of stale threads.
Alternative 2. Notify all waits on all shared memories without doing any changes, probably multiple times, so memory.atomic.wait* instructions would simply return 0 (Ok). May break some logic in guest code, so it is suitable only for terminating.
Alternative 3. That loop, as well as checking for epoch, can be implemented on the host side, but I don't know how to access current epoch value from there.
Contributor guide
Assessment
This issue has not been assessed yet.