Interrupt wasmer/wasmtime

Does either wasmer or wasmtime offer a "run for $N instructions" ?

The thing I want to do is (1) load a number of wasm files in separate wasm VMs, (2) in a round robin style, run each wasm for $N instructions, then interrupt it and go to next.

Does either wasmer or wasmtime offer a "run for $N instructions" ?

It's okay if $N is approximate. I don't want this to be interpreted. I want the wasm to be compiled to x86_64 native and then run; thus, it is okay if $N is approximate.

Wasmer doesn't provide any way to interrupt execution, but wasmtime gives you a Store::interrupt_handle() which you can use to programmatically interrupt execution.

To use it, you'd probably need to have a background thread handling the interrupting or do a check at the start of every host function.

1 Like

Store in wasmtime - Rust looks really interesting too. Is the main downside to 'fuel' that for every executed instruction, we add the additional penalty of a decrement and a comparison ?

It depends. If you want a way to ensure a bit of WebAssembly code runs for a bounded amount of time (e.g. when running untrusted code) then you don't really have many other alternatives.

If you've got concerns about performance, I've got a feeling it'd be a bit smarter than "run an instruction, decrement, run the next instruction". Instead you can probably save a lot by batching the decrements up and only doing them before a jump. Depending on the instructions used and architecture, you can probably also make the processor raise an exception whenever you run out of gas instead of doing an explicit comparison - similar to how exceptions can be faster than Result when you'll almost never hit the error path.

So here's the problem I care about: imagine you are building a MMORPG server (like say World of Warcraft), and you allow user scriptable (in wasm32) NPCs.

So I want this to be "mostly fair" but I don't care about exact instruction count fair. So for example, if we have a limit of 1000 instrs per second, but because we only check on every function call / loop, and, as a result, some smart programmers can get 1008 instructions per second, I'm okay with that.

The main thing I don't like about the interrupt strategy is that it is time based rather than instr-executed based. As for fuel, it is a bit too precise for my needs. I'm perfectly fine with a system that had the constraint of :

  • execute at least N instrs, and at most 2*N instrs OR
  • execute at least N instrs, and at most N + 100 instrs

Main point here is being able to say precisely N instrs sounds expensive, and is a level of precision I don't need.

1 Like

Yeah, that's fair. It sounds like "gas" is the mechanism you want, but you may need to do a bit of experimenting to make see whether the added overhead is acceptable for your use case.

Another thing you could do is just check "is it time to do a context switch" at the start of every host function and use the interrupt handle there. Essentially implementing your own "gas" mechanism with host function calls instead of instructions. I'd try the built-in version first though because you don't need to write any extra code.