Stream: general

Topic: Epoch injection


view this post on Zulip Nicholas Renner (Dec 20 2024 at 23:58):

Is there any documentation giving details about how the actual epoch injection takes place? IE at what stages and how?

Thanks!

view this post on Zulip Chris Fallin (Dec 21 2024 at 00:14):

This method is the only one that updates the epoch: https://docs.rs/wasmtime/latest/wasmtime/struct.Engine.html#method.increment_epoch

view this post on Zulip Chris Fallin (Dec 21 2024 at 00:15):

that links to the docs on the config option, which covers the whole flow of methods to call and what happens when

view this post on Zulip Nicholas Renner (Dec 21 2024 at 00:16):

I meant how is the code instrumented. I'm under the impression that code to "check" the epoch is added? How does that process work? The API documentation is quite good I'm just trying to understand whats going on under the hood.

view this post on Zulip Chris Fallin (Dec 21 2024 at 00:17):

Yes, that's right, we insert checks -- they happen at loop backedges and at function entry

view this post on Zulip Chris Fallin (Dec 21 2024 at 00:18):

we don't document the "how" in the public docs because it's an internal implementation detail, but basically: we load the current epoch and the deadline from memory and compare, branching to a call back into the runtime (that subsequently traps or async-yields) if the deadline's exceeded

view this post on Zulip Chris Fallin (Dec 21 2024 at 00:19):

current epoch is an atomic u64; and increment_epoch is an atomic increment, nothing more, which is how we made it signal-safe and thread-safe

view this post on Zulip Nicholas Renner (Dec 21 2024 at 00:26):

Okay thanks!

At what point are the checks injected? At compile time?

view this post on Zulip Chris Fallin (Dec 21 2024 at 00:31):

Yes; there would be no way to inject them later, as we don't do runtime code patching

view this post on Zulip Victor Adossi (Dec 21 2024 at 03:07):

@Chris Fallin do you think it makes sense to add this documentation to the increment_epoch() or maybe Config::epoch_interruption might be the better place since there's a decent chunk of documenation there.

If so, @Nicholas Renner would you mind adding the documentation you would have wanted to see to wasmtime?

view this post on Zulip Chris Fallin (Dec 21 2024 at 06:48):

@Victor Adossi I don't think it really makes sense to put in the public API documentation -- the question was "how did we implement it" and we generally don't put implementation details in public docs (as it's irrelevant to the audience that only wants to use wasmtime). Perhaps in the architecture doc somewhere (docs/contributing-architecture.md)?

view this post on Zulip Nicholas Renner (Dec 21 2024 at 22:34):

I had some more specific questions, still trying to understand some of this:

  1. does the code injection happens at wasm level (i.e. injected as wasm byte code), or at native code level (injected as native instruction on cwasm)?
  2. which approach is used to transfer the control to runtime? Using a function call (i.e. if check passed, just do a normal function callback)? Or raising a trap and let trap handler to handle it?
  3. If the code injection happens at wasm level, is there way to output the epoch transformed wasm file?

view this post on Zulip Chris Fallin (Dec 21 2024 at 22:52):

@Nicholas Renner have you looked into the implementation? It might be more efficient to read the code if you have specific questions about how this works. Grep for epoch_interruption and go from there; crates/cranelift/ contains the Wasm-to-CLIF translator. (It would also help us to know whether you have already read the code and are still unsure, or if these questions are your starting point, to calibrate level of detail.)

It would also help to know to what end these questions are directed -- are you trying to build a feature that integrates with this? Understand performance implications? Other?

That said: injection is not exactly either of your options -- we do not inject Wasm bytecode, and we do not edit the cwasm or operate after the compiler. Rather we inject compiler IR when we translate the Wasm to CLIF. Control is passed to the runtime via a Wasm-to-host call; yielding occurs via our async mechanism that does stack switching (see the "fiber" crate).

view this post on Zulip Jonas Kruckenberg (Dec 22 2024 at 20:17):

might be worth adding @Nicholas Renner that - while you cannot output the WASM with epoch instrumentation as WASM - you can output the clif IR https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.emit_clif in case you want to just look at it or study its impact on code behavior or something

view this post on Zulip Nicholas Renner (Dec 22 2024 at 21:42):

Thanks all,

Yeah, I'm still coming in somewhat blind. I mostly wanted to be pointed to the sections in the implementation to start looking at so thanks for that. I'm building something that uses asyncify with wasmtime for our project's use, I know thats pretty out of scope for wasmtime in general, but was trying to find some information to see how epochs would interact with the asyncify mechanisms.

view this post on Zulip Chris Fallin (Dec 22 2024 at 22:19):

Ah! That's a much more specific and easily-answerable question: epoch interruption should not interfere with Wasm semantics at all, including Wasm semantics utilized by asyncify. It operates one level down, invisible to the Wasm execution: we basically split the execution into pieces each of which runs in one future-poll invocation in the Wasmtime host-side async interface.

Integration between what guest code calls "async" and what host code calls "async" is a much deeper question, and one that is unrelated to epoch interruption: that veers into WASI 0.3 and async work around component interfaces (talk to @Joel Dice about that one)

view this post on Zulip Chris Fallin (Dec 22 2024 at 22:20):

(said more briefly: if what you're looking for is to reflect async details in the guest into the host side, epoch interruption is not what you want -- it serves a different purpose)

view this post on Zulip Nicholas Renner (Dec 23 2024 at 01:47):

Great, thank you very much for the responses. Going to take some time to look this over and may have some more questions, but this was super helpful!


Last updated: Dec 23 2024 at 12:05 UTC