-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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::WaitResultwith 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 inConfig.
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.