-
Notifications
You must be signed in to change notification settings - Fork 165
Add a "bounded runtime" mode to guest execution. #612
Conversation
d5adc00
to
86ca1d1
Compare
58a5c8c
to
cc3ce00
Compare
Just made a few tweaks to (hopefully) get a green CI again; recent changes in
I'm happy to do either or both of these if needed, just let me know and I'll dig in further to understand the changes better :-) Thanks! |
@cfallin i've cooked up a patch for point 1, and am figuring out point 2 at the moment - i expect we can piece those changes out with a wasmtime update independent of this PR landing, so we don't have to worry about tying up too much in one PR |
e4e95dc
to
4e25235
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.
Thanks so much for getting this implemented! It's going to make a huge difference for async Lucet embedders.
I have a handful of suggestions here but nothing fundamental.
Ah, it occurred to me that we also need a version of |
This modifies the instruction-counting mechanism to track an instruction-count bound as well; and when a bound is set, the Wasm guest will make a hostcall to yield back to the host context. This is all placed under the `run_async()` function, so bounded-execution yields manifest as futures that are immediately ready to continue execution. This should give an executor main loop a chance to do other work at regular intervals.
4e25235
to
276d018
Compare
Updated, and added the async |
This PR revises the simple instruction-count binding work, which initially loaded and stored the instruction-count field from memory on every basic block and emitted an extra conditional branch and yielding block after every basic block, with two optimizations: 1. The instruction count is kept in a local variable (which the register allocator will ideally keep in a register unless spills are necessary), and this count is saved back to the field in memory only when necessary, e.g., before calls and returns. 2. The checks and conditional branches are inserted only in places where necessary to ensure bounded time between checks, at the cost of slightly more overrun/approximation in the bound: specifically, before calls and returns (to avoid unbounded runtime due to recursion) and at loop backedges.
276d018
to
ea3c239
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.
Thank you for the fast work on this!
Curious - would it be possible to expose these APIs publicly? |
@benaubin |
@cfallin I'd love to have access to the |
@benaubin I see -- the If you are not also using the value-yield functionality in hostcalls, you can implement your use-case with Otherwise, the right thing to do would be to have a separate If the latter is what you need, I'm happy to review a PR! Unfortunately I don't have time to work on this myself at the moment though. |
Happy to do a PR. Renaming I'd be happy to build a timeout around CPU time as well, but it would require adding calls to libc for measuring the thread's cpu time - bloat that might not be applicable to all users. |
Oh, I see what you mean! There would need to be a |
@benaubin One other thing that I should probably note also, is that longer-term, the plan is to merge Lucet's functionality into Wasmtime (see blog post from Bytecode Alliance and another blog post on the merging efforts). There are active efforts to make this happen, e.g. async support in bytecodealliance/rfcs#2 and fast instance allocation in bytecodealliance/rfcs#5. In the meantime Lucet is absolutely supported, and as mentioned I'm happy to review a PR; but this may be relevant for your planning :-) |
Thanks for the heads up! We saw that, but want lucet's |
@cfallin On second thought, you were probably right that the |
This modifies the instruction-counting mechanism to track an
instruction-count bound as well; and when a bound is set, the Wasm guest
will make a hostcall to yield back to the host context.
This is all placed under the
run_async()
function, so bounded-executionyields manifest as futures that are immediately ready to continue execution.
This should give an executor main loop a chance to do other work at regular
intervals.