-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathupstream-sync-streams-schedule-agnostic.patch
More file actions
53 lines (50 loc) · 2.85 KB
/
Copy pathupstream-sync-streams-schedule-agnostic.patch
File metadata and controls
53 lines (50 loc) · 2.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
diff --git a/test/async/sync-streams.wast b/test/async/sync-streams.wast
index 7d31a10..83c7c6b 100644
--- a/test/async/sync-streams.wast
+++ b/test/async/sync-streams.wast
@@ -137,14 +137,36 @@
(call $stream.drop-readable (local.get $rx))
;; ($rx, $tx) = stream.new
- ;; $C.set($rx) blocks on stream.read, so the async call returns STARTED
+ ;; $C.set($rx) blocks on stream.read. $C's exclusivity gate is still
+ ;; held by the resolved-but-parked $C.get task, so whether this call
+ ;; reports STARTING or STARTED is host scheduler policy, not
+ ;; semantics: a host may decide entry eagerly at the call instant
+ ;; (STARTING) or defer the decision until runnable work queued ahead
+ ;; of the call has drained (STARTED). Accept both; on STARTING, wait
+ ;; for the subtask to be admitted (STARTED) before touching the
+ ;; stream.
(local.set $ret64 (call $stream.new))
(local.set $rx (i32.wrap_i64 (local.get $ret64)))
(local.set $tx (i32.wrap_i64 (i64.shr_u (local.get $ret64) (i64.const 32))))
(local.set $ret (call $set (local.get $rx)))
- (if (i32.ne (i32.const 1 (; STARTED ;)) (i32.and (local.get $ret) (i32.const 0xf)))
- (then unreachable))
(local.set $subtask (i32.shr_u (local.get $ret) (i32.const 4)))
+ (local.set $ws (call $waitable-set.new))
+ (call $waitable.join (local.get $subtask) (local.get $ws))
+ (if (i32.eq (i32.const 0 (; STARTING ;)) (i32.and (local.get $ret) (i32.const 0xf)))
+ (then
+ ;; admitted only after the parked $C.get task exits: wait for
+ ;; STARTED. RETURNED cannot arrive first: $C.set reads from a
+ ;; stream nothing has written to yet.
+ (local.set $ret (call $waitable-set.wait (local.get $ws) (i32.const 0)))
+ (if (i32.ne (i32.const 1 (; SUBTASK ;)) (local.get $ret))
+ (then unreachable))
+ (if (i32.ne (local.get $subtask) (i32.load (i32.const 0)))
+ (then unreachable))
+ (if (i32.ne (i32.const 1 (; STARTED ;)) (i32.load (i32.const 4)))
+ (then unreachable)))
+ (else
+ (if (i32.ne (i32.const 1 (; STARTED ;)) (i32.and (local.get $ret) (i32.const 0xf)))
+ (then unreachable))))
;; (stream.write $tx $bufp 4) will succeed without blocking
(local.set $bufp (i32.const 16))
@@ -156,8 +178,6 @@
(call $stream.drop-writable (local.get $tx))
;; wait for $C.set to finish, which implies all its checks passed
- (local.set $ws (call $waitable-set.new))
- (call $waitable.join (local.get $subtask) (local.get $ws))
(local.set $ret (call $waitable-set.wait (local.get $ws) (i32.const 0)))
(if (i32.ne (i32.const 1 (; SUBTASK ;)) (local.get $ret))
(then unreachable))