Skip to content

Commit 305b46c

Browse files
committed
Add cooperative threads
1 parent 4474667 commit 305b46c

2 files changed

Lines changed: 56 additions & 96 deletions

File tree

design/mvp/CanonicalABI.md

Lines changed: 44 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ being specified here.
3737
* [`canon resource.new`](#canon-resourcenew)
3838
* [`canon resource.drop`](#canon-resourcedrop)
3939
* [`canon resource.rep`](#canon-resourcerep)
40+
* [`canon thread.new_indirect`](#-canon-threadnew_indirect) 🧵
4041
* [`canon context.get`](#-canon-contextget) 🔀
4142
* [`canon context.set`](#-canon-contextset) 🔀
4243
* [`canon backpressure.set`](#-canon-backpressureset) 🔀
@@ -58,9 +59,7 @@ being specified here.
5859
* [`canon error-context.new`](#-canon-error-contextnew) 📝
5960
* [`canon error-context.debug-message`](#-canon-error-contextdebug-message) 📝
6061
* [`canon error-context.drop`](#-canon-error-contextdrop) 📝
61-
* [`canon thread.spawn_ref`](#-canon-threadspawn_ref) 🧵
62-
* [`canon thread.spawn_indirect`](#-canon-threadspawn_indirect) 🧵
63-
* [`canon thread.available_parallelism`](#-canon-threadavailable_parallelism) 🧵
62+
* [`canon thread.available_parallelism`](#-canon-threadavailable_parallelism)
6463

6564
## Supporting definitions
6665

@@ -3410,6 +3409,46 @@ Note that the "locally-defined" requirement above ensures that only the
34103409
component instance defining a resource can access its representation.
34113410

34123411

3412+
### 🧵 `canon thread.new_indirect`
3413+
3414+
TODO: rewrite
3415+
3416+
For a canonical definition:
3417+
```wat
3418+
(canon thread.new_indirect $shared? $ft $tbl (core func $f))
3419+
```
3420+
validation specifies:
3421+
* `$ft` must refer to a `shared` function type; initially, only the type
3422+
`(shared (func (param $c i32)))` is allowed (see explanation in
3423+
`thread.spawn_ref` above)
3424+
* `$tbl` must refer to a shared table whose element type matches `(ref null
3425+
(shared func))`
3426+
* `$spawn_indirect` is given type `(func (param $i i32) (param $c i32) (result
3427+
$e i32))`.
3428+
3429+
Calling `$spawn_indirect` retrieves a reference to function `$f` from table
3430+
`$tbl` and checks that `$f` is of type `$ft`. If that succeeds, it spawns a
3431+
thread which:
3432+
- invokes `$f` with `$c`
3433+
- executes `$f` until completion or trap in a `shared` context as described by
3434+
the [shared-everything threads] proposal.
3435+
3436+
In pseudocode, `$spawn_indirect` looks like:
3437+
3438+
```python
3439+
async def canon_thread_new_indirect(shared, ft, ftbl, thread, i, c):
3440+
inst = thread.task.inst
3441+
trap_if(not inst.may_leave)
3442+
assert(not shared)
3443+
f = ftbl.get(i)
3444+
trap_if(f is None)
3445+
trap_if(f.type != ft)
3446+
new_thread = Thread(thread.task, f(c))
3447+
return [inst.table.add(thread)]
3448+
```
3449+
TODO
3450+
3451+
34133452
### 🔀 `canon context.get`
34143453

34153454
For a canonical definition:
@@ -4212,6 +4251,7 @@ async def canon_error_context_debug_message(opts, task, i, ptr):
42124251
Note that `ptr` points to an 8-byte region of memory into which will be stored
42134252
the pointer and length of the debug string (allocated via `opts.realloc`).
42144253

4254+
42154255
### 📝 `canon error-context.drop`
42164256

42174257
For a canonical definition:
@@ -4232,99 +4272,7 @@ async def canon_error_context_drop(task, i):
42324272
```
42334273

42344274

4235-
### 🧵 `canon thread.spawn_ref`
4236-
4237-
For a canonical definition:
4238-
```wat
4239-
(canon thread.spawn_ref $ft (core func $spawn_ref))
4240-
```
4241-
validation specifies:
4242-
* `$ft` must refer to a `shared` function type; initially, only the type
4243-
`(shared (func (param $c i32)))` is allowed (see explanation below)
4244-
* `$spawn_ref` is given type `(func (param $f (ref null $ft)) (param $c i32)
4245-
(result $e i32))`.
4246-
4247-
> Note: ideally, a thread could be spawned with [arbitrary thread parameters].
4248-
> Currently, that would require additional work in the toolchain to support so,
4249-
> for simplicity, the current proposal simply fixes a single `i32` parameter
4250-
> type. However, `thread.spawn_ref` could be extended to allow arbitrary thread
4251-
> parameters in the future, once it's concretely beneficial to the toolchain.
4252-
> The inclusion of `$ft` ensures backwards compatibility for when arbitrary
4253-
> parameters are allowed.
4254-
4255-
Calling `$spawn_ref` checks that the reference `$f` is not null. Then, it spawns
4256-
a thread which:
4257-
- invokes `$f` with `$c`
4258-
- executes `$f` until completion or trap in a `shared` context as described by
4259-
the [shared-everything threads] proposal.
4260-
4261-
In pseudocode, `$spawn_ref` looks like:
4262-
4263-
```python
4264-
def canon_thread_spawn_ref(f, c):
4265-
trap_if(f is None)
4266-
if DETERMINISTIC_PROFILE:
4267-
return [-1]
4268-
4269-
def thread_start():
4270-
try:
4271-
f(c)
4272-
except CoreWebAssemblyException:
4273-
trap()
4274-
4275-
if spawn(thread_start):
4276-
return [0]
4277-
else:
4278-
return [-1]
4279-
```
4280-
4281-
4282-
### 🧵 `canon thread.spawn_indirect`
4283-
4284-
For a canonical definition:
4285-
```wat
4286-
(canon thread.spawn_indirect $ft $tbl (core func $spawn_indirect))
4287-
```
4288-
validation specifies:
4289-
* `$ft` must refer to a `shared` function type; initially, only the type
4290-
`(shared (func (param $c i32)))` is allowed (see explanation in
4291-
`thread.spawn_ref` above)
4292-
* `$tbl` must refer to a shared table whose element type matches `(ref null
4293-
(shared func))`
4294-
* `$spawn_indirect` is given type `(func (param $i i32) (param $c i32) (result
4295-
$e i32))`.
4296-
4297-
Calling `$spawn_indirect` retrieves a reference to function `$f` from table
4298-
`$tbl` and checks that `$f` is of type `$ft`. If that succeeds, it spawns a
4299-
thread which:
4300-
- invokes `$f` with `$c`
4301-
- executes `$f` until completion or trap in a `shared` context as described by
4302-
the [shared-everything threads] proposal.
4303-
4304-
In pseudocode, `$spawn_indirect` looks like:
4305-
4306-
```python
4307-
def canon_thread_spawn_indirect(ft, tbl, i, c):
4308-
f = tbl[i]
4309-
trap_if(f is None)
4310-
trap_if(f.type != ft)
4311-
if DETERMINISTIC_PROFILE:
4312-
return [-1]
4313-
4314-
def thread_start():
4315-
try:
4316-
f(c)
4317-
except CoreWebAssemblyException:
4318-
trap()
4319-
4320-
if spawn(thread_start):
4321-
return [0]
4322-
else:
4323-
return [-1]
4324-
```
4325-
4326-
4327-
### 🧵 `canon thread.available_parallelism`
4275+
### `canon thread.available_parallelism`
43284276

43294277
For a canonical definition:
43304278
```wat

design/mvp/canonical-abi/definitions.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2110,6 +2110,18 @@ async def canon_resource_rep(rt, thread, i):
21102110
trap_if(h.rt is not rt)
21112111
return [h.rep]
21122112

2113+
### 🧵 `canon thread.new_indirect`
2114+
2115+
async def canon_thread_new_indirect(shared, ft, ftbl, thread, i, c):
2116+
inst = thread.task.inst
2117+
trap_if(not inst.may_leave)
2118+
assert(not shared)
2119+
f = ftbl.get(i)
2120+
trap_if(f is None)
2121+
trap_if(f.type != ft)
2122+
new_thread = Thread(thread.task, f(c))
2123+
return [inst.table.add(thread)]
2124+
21132125
### 🔀 `canon context.get`
21142126

21152127
async def canon_context_get(t, i, thread):

0 commit comments

Comments
 (0)