Skip to content

Commit

Permalink
Add 05-06 meeting notes (WebAssembly#431)
Browse files Browse the repository at this point in the history
  • Loading branch information
linclark authored May 7, 2021
1 parent bef8a66 commit f44df04
Showing 1 changed file with 139 additions and 0 deletions.
139 changes: 139 additions & 0 deletions meetings/2021/WASI-05-06.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,142 @@ The meeting will be on a zoom.us video conference.
1. Proposals and discussions
1. Presentation: Supporting alternative ABIs for blocking function calls (Luke Wagner)
2. Demo (if time allows): Update on wasi-io (Dan Gohman)

## Notes
### Attendees

- Lin Clark
- Luke Wagner
- Sam Clegg
- Piotr Sikora
- Francis McCabe
- Mark McCaskey
- Dan Gohman
- Andrew Brown
- Mingqiu Sun
- Matt Butcher
- Radu Matei
- Yong He
- Johnnie Birch

**Luke Wagner:** Fleshing out idea from conversation last week. Want to see if this looks reasonable to Piotr

What to do about blocking is an open question for WASI. There are callback style APIs. Challenges when supporting non-async languages. Some languages have some kind of structured concurrency, e.g. greenthread. For such langs, you have to do something. One option is asyncify, but that has significant overhead. Even langs with async have subtle differences, would be hard to capture those difference.

There’s also blocking style APIs. With blocking APIs, you can support both sync and async pretty efficiently, doing blocking on root of callstack. Big downside is that it requires native engine support.

Question for WASI: Do we just pick one? Seems problematic because interest in all styles. Pick arb based on champion? Do we do both? Or have a single interface that can be programmatically converted to use in both styles?

**Johnnie Birch:** How do you consider wasm and the way that wasm will handle threading?

**Luke Wagner:** Yeah, wasm doesn’t have native wasm threading. Some sketches of what it would look like. Subtle distinction between threads and stacks. When we talk about native wasm threads, that’s something more like pthread or greenthread?

**Johnnie Birch:** Is it possible to compartmentalize?

**Luke Wagner:** Definitely hard question. Hopefully what I present here will go some way to answering.

**Francis McCabe:** If wasm stack switching was already done, how would that… you can answer at end, but how would that affect?

**Luke Wagner:** If the answer is we wouldn’t do two things, then hard questions, but I think there are some scenarios where we do want callback style. Will return at the end.

Recap bits from last CG meeting. Component model, question was to use WASI do you need to use component model? Answer is that you can use WASI without CM. WASI specs could be defined in terms of IT but via canonical ABI can create interfaces that only use core types. WASI can support CM, but doesn’t need everyone to buy into it. One thing that I didn’t explain before, from perspective of compiler, we can think of these as different bin format. LD could either emit component or core module. Since that meeting, Alex has posted PR that has concrete PR for canonical ABI.

Question relevant: what about wasm GC? I also mentioned that we don’t need to have literally one ABI, but it could be parameterized. Linear memory version vs GC version. With memory=linear, signature uses i32s, with GC memory uses GC types. One interface signature but can derive two canonical ABI representations of it.

Idea is to add a blocking attribute to function interface types. Intro ABI variant, blocking=suspend|callback. When callback, exports and imports return callback+closures. When blocking=suspend, exports are sync and generate two sigs, either sync or return future/

To show in more concrete detail [walk through Cannonical ABI blocking variants slide].

**Francis McCabe:** I think there’s a bunch of questions here. The future that you’re returning—who’s going to specify what that future looks like.

**Luke Wagner:** Combination of interface you use and canonical ABI. That’s a thing I left out.

**Francis McCabe:** Reason I ask is diff stack switching proposals will have… not obvious who’s responsible for designing async/await on top of stack switching. So WASI’s taking it on?

**Luke Wagner:** Yes, for these particular kinds of interfaces, yes. So design of canonical ABI would say what you could do on a future. I’ll put a little more detail

**Piotr Sikora:** On the suspend side, you are missing continuation, right?

**Luke Wagner:** You’d say I’m going to block in the future, can either wait for all to finish select. Either blocking now or in the future.

**Piotr Sikora:** On the callback side, are interface types enough?

**Luke Wagner:** Doesn’t even block on interface types. Can both work today immediately and in the future.

[Continues with walk through]

From the perspective of the spec, when I’m doing suspend, I call the canonical export func, plain old sync. When I call import adapted functions, I just wait on them

In contrast, when callback, conceptually one adapted function call, but I’m calling deep and then return. When I want to do IO, I call import function, it’s my job as the calling code to do the extra work to get off the call stack. That’s what it looks like from spec perspective.

From impl perspective, probably want a greenthread for suspend. In contrast, when callback can have a host event loop. So this is basically classic event loop. Third possibility, if you have a greenthread no problem doing callback style. Greenthread allows strictly more options, but if you don’t have them can still do the callback ABI.

**Francis McCabe:** Going back to prev slide, would you expect someone exporting a blocking function today to support both implementations.

**Luke Wagner:** This gets to impl thing here, on hosts that have green threads, I can do both. Until we get stack switching, in which case it can emulate greenthreads

**Sam Clegg:** Or with Asyncify

**Luke Wagner:** If proxy-wasm were to go this direction, what would that look like? [Talk through To adopt in proxy-wasm]

Does this potentially satisfy proxy-wasm’s requirements?

**Piotr Sikora:** I would need to sketch it out. Would on_fetch be enough to satisfy all callbacks without wasm code?

**Luke Wagner:** I’m oversimplifying here, some other calls. For each of them, I think it makes sense to have different exports.

**Francis McCabe:** I have a syntax question. In IT land, one question that comes up is who writes the IT signature.

**Luke Wagner:** In this case it’s WASI.

**Francis McCabe:** So if you’re handwriting, you can put blocking and reentrant on signature. But one scenario is that someone wants to be able to autogenerate IT sigs from C sigs, and blocking and reentrant don’t show up in C.

**Luke Wagner:** You’re right, different scenario, I expect to be handled with macros. If this all worked out, as a component author, I would just say implement that please. It will spit out all the signatures. That’s what we’re going for witx tooling.

**Francis McCabe:** I think both scenarios will show up

**Sam Clegg:** Would given module have to choose between callback and suspend

**Luke Wagner:** You’re right. Component authors would have to specify, and hosts would reject if couldn’t support

**Sam Clegg:** And then fully flexible API would present either option

**Luke Wagner:** I also think blocking composes, satisfying virtualization requirements

**Till Schneidereit:** On web, define in terms of workers

**Sam Clegg:** Can’t multiplex within a worker. Could have an HTTP impl that was using blocking and then a consumer that uses callbacks, and engine could stitch together

**Luke Wagner:** Yeah, and if you’ve been following, JS API is just an example of this

**Piotr Sikora:** Question regarding callback, we’d use function indirection table. Do you know the overhead?

**Luke Wagner:** I think it should be optimizable. I think crossing cost is the high order bit.

**Piotr Sikora:** Is there any reason not to use some convention

**Luke Wagner:** If you do it right, thing that is expensive is dynamic function signature. You have to go through slow trampoline. That thing doesn’t care because always a pointer. If you have a type specialized code path, but the callee is still an actual pointer. My guess is that in the host you’re going through indirection anyway and we’re not adding that much if any.

**Piotr Sikora:** Thank you, I think this will work. Will need to consider. Should we try this with a small component?

**Luke Wagner:** Yeah, great starting point. Maybe we can help by writing a sketch of the witx toolchain, and you can evaluate that

**Piotr Sikora:** That would be perfect

----

**Dan Gohman:** This is updated version of witx, works with some of the canonical ABI stuff. You can see now that we’re using this new syntax for resources. Can define resources. In IO stream, input and output are like TCP but it’s not just for TCP.

Pseudomonas give you an opaque handle to the resource so don’t need to expose name string.

Here’s an example of the new syntax. Getting ready for witx to be more of a first class tool. Uses pull buffer from canonical ABI. Gives us a way to abstract over linear memory vs GC buffer.

Return value is expected. Basically a specialized version of variant. Read isn’t going to tell you what failed. We’re abstracting over the input source because application logic doesn’t need to know, but can talk about how to surface for logging, debugging, etc.

Push buffer and pull buffer really make clear what you’re doing as opposed to in/out. Forward is how we do zero copy IO.

So that’s a brief overview of what we can do with new IT and witx tooling. Some cool new buffer things.

**Sam Clegg:** error is built in core type?

**Dan Gohman:** Error is more like a keyword. Literally saying there’s no type there

0 comments on commit f44df04

Please sign in to comment.