CM#705 (merged upstream; migration map polyengine#173) changed the sync-call mini-scheduler's semantics beyond the may_enter removal: the exclusive thread is no longer excluded from the resume candidate set, and callback-task threads parked on the exclusive lock become resumable during a sync call. polyengine's driveSyncLift (runtime/src/task/scheduler.ts) implements the pinned (pre-#705) form — candidates exclude inst.exclusiveThread — and the adjacent backpressure behavior produces pre-#705 subtask codes.
New/changed corpus rows pinning the merged semantics (xfailed under class cm705-sync-sched until this issue closes):
test/async/during-sync-call-exclusive-resume.wast (new; replaces the deleted during-sync-call-no-exclusive-resume.wast with inverted semantics): a parked callback-task thread holding/waiting on the exclusive lock must be resumable mid-sync-call.
test/async/during-sync-scheduling-candidates.wast (new, 484 lines): candidate-set membership per thread kind; §3 (parked callback-task threads, incl. driven from a sibling), §4 (callback thread blocked mid-frame holding the lock), §5 (sync-lifted async-typed function's thread blocked mid-frame) expect resumability the current scheduler refuses.
test/async/during-sync-call-may-block-if-other-ready-threads.wast (rewritten): appended third component needs mid-sync-call resumption of a parked callback-task thread.
test/async/during-sync-call-no-sibling-resume.wast: the pinned rule (only same-instance threads) is unchanged, but the expected trap is now "cannot block a synchronous task before returning" where we produce the deadlock message — verify/align the trap site.
test/async/sync-streams.wast (changed by the #705 commit): an async-lowered call into a callee whose exclusive lock is held now returns STARTING (queued by automatic backpressure) instead of STARTED, and the rendezvous completion codes swap (COMPLETED|4 / DROPPED|4). Requires the queuing behavior, not just the candidate set.
Scope of the fix:
- Drop the
t !== task.inst.exclusiveThread exclusion in driveSyncLift; align the candidate set with merged canon_lift (all ready threads of the callee instance).
- Adopt the surrounding merged semantics the new rows exercise: exclusive-lock interaction with the mini-scheduler, backpressure queuing of async-lowered entries while the lock is held (STARTING), and the trap-message alignment in the no-sibling case.
- Retire the
cm705-sync-sched xfail class; the stale-xfail detector enforces completeness.
Authority: design/mvp/canonical-abi/definitions.py at the advanced pin (tie-breaker), Concurrency.md §Reentrance/§Blocking as merged in CM#705. Scheduler core is single-owner territory (AGENTS.md): coder-hard at most, close orchestrator review.
CM#705 (merged upstream; migration map polyengine#173) changed the sync-call mini-scheduler's semantics beyond the may_enter removal: the exclusive thread is no longer excluded from the resume candidate set, and callback-task threads parked on the exclusive lock become resumable during a sync call. polyengine's
driveSyncLift(runtime/src/task/scheduler.ts) implements the pinned (pre-#705) form — candidates excludeinst.exclusiveThread— and the adjacent backpressure behavior produces pre-#705 subtask codes.New/changed corpus rows pinning the merged semantics (xfailed under class
cm705-sync-scheduntil this issue closes):test/async/during-sync-call-exclusive-resume.wast(new; replaces the deletedduring-sync-call-no-exclusive-resume.wastwith inverted semantics): a parked callback-task thread holding/waiting on the exclusive lock must be resumable mid-sync-call.test/async/during-sync-scheduling-candidates.wast(new, 484 lines): candidate-set membership per thread kind; §3 (parked callback-task threads, incl. driven from a sibling), §4 (callback thread blocked mid-frame holding the lock), §5 (sync-lifted async-typed function's thread blocked mid-frame) expect resumability the current scheduler refuses.test/async/during-sync-call-may-block-if-other-ready-threads.wast(rewritten): appended third component needs mid-sync-call resumption of a parked callback-task thread.test/async/during-sync-call-no-sibling-resume.wast: the pinned rule (only same-instance threads) is unchanged, but the expected trap is now "cannot block a synchronous task before returning" where we produce the deadlock message — verify/align the trap site.test/async/sync-streams.wast(changed by the #705 commit): an async-lowered call into a callee whose exclusive lock is held now returns STARTING (queued by automatic backpressure) instead of STARTED, and the rendezvous completion codes swap (COMPLETED|4 / DROPPED|4). Requires the queuing behavior, not just the candidate set.Scope of the fix:
t !== task.inst.exclusiveThreadexclusion indriveSyncLift; align the candidate set with mergedcanon_lift(all ready threads of the callee instance).cm705-sync-schedxfail class; the stale-xfail detector enforces completeness.Authority:
design/mvp/canonical-abi/definitions.pyat the advanced pin (tie-breaker), Concurrency.md §Reentrance/§Blocking as merged in CM#705. Scheduler core is single-owner territory (AGENTS.md): coder-hard at most, close orchestrator review.