Closed rylev closed 4 years ago
I'd be curious to hear other's thoughts on this as well, but two "lightweight" ways to do this could be:
wasmtime
-specific at all, but a sort of transformation pass on a *.wasm
file that inserts calls to an imported function at "notable locations" like loops or functions, and the imported function would be called periodically where a trap could signify "time to halt".wasmtime
-specific and provide this as an option during module compilation where it does roughly the same thing but directly on the cranelift IR, where an imported function is called every so often and has the option of trapping.Out of curiosity, you say "stop or pause" but I suspect "stop" is going to be a whole lot easier than "pause". Does your use case require the pausing aspect of resuming again later if something was stopped?
Related to #712
I think both would be helpful. There is a use case for pausing a module as well, but for this specific issue, just being able to stop it is the main feature request
Some other notes:
In https://github.com/bytecodealliance/wasmtime/issues/43 @sunfishcode says:
cranelift-wasm's
FuncEnviron
has atranslate_loop_header
callback which allows embedders to insert custom timeout code at the tops of loops (in addition to the tops of potentially recursive functions). Wasmtime doesn't yet implement timeouts, but this hook is one way it could do so.
In https://github.com/bytecodealliance/wasmtime/issues/712 @pchickey says:
Over in Lucet, @iximeow was able to find an implementation https://github.com/bytecodealliance/lucet/pull/150 that makes it possible to terminate running Wasm code due to either timeout or other external triggers, but it is pretty specific to the way stack switching to Wasm code works in Lucet.
We'd like to port Lucet's stack management code into Wasmtime as part of merging the Lucet project in, so I'd expect the kill switch mechanism to be ported in as well.
@alexcrichton that sounds similar to the path we were starting to go down. so I'll follow along with those issues as well
I personally probably have one of the sillier use-cases for the ability to pause/resume (I wanted to put WASM computers in Minecraft as an exercise), but it gives a few very important use cases for Wasmtime some light: 1) The traditional browser use-case of having separate isolated Wasmtime VMs up and going at once 2) The embedded into another application use-case in, say, a game, where the VM hanging the place would be disastrous, and you're under a strict schedule to get each frame out on time (and as such need a watchdog system, where each VM gets a per-frame budget of how much it gets to execute before pausing)
Note that pausing is harder than stopping because you have to save the execution state (stack and all that) so that you can pick it back up again later. We want this eventually since wasm will eventually get stack switching, but we can probably support interrupting and stopping long-running wasm modules sooner.
In addition to the translate loop header stuff, what we would need is a timer thread or something that sets a flag once a module has taken too long, and then the loop header (and function prologues!) would check that flag and do a custom interrupt trap if it is set.
Sorry, is there a way to pause + resume wasmtime instances right now?
Context: imagine an ant colony simulation, where each ant = tiny wasm vm; we want to run every ant for a bit, then pause it, let other ants run, etc ...
Yes to do that you'd want to use Wasmtime's support for async
. Fuel and epochs are the mechanisms to suspend computations. I'd also recommend opening a new issue and/or a thread on Zulip instead of posting on older issues.
Once a
wasmtime::Instance
in created thestart
function will be run. This may lead to the current thread being blocked for a long time. It would be helpful to have the ability to stop or pause anwasmtime::Instance
while it is running.