Parent: #1
Problem
The sharded no-GIL TSan corpus exposed a data race in api/condition-async-wait.js: one shared-realm thread entered vm.asyncDrive and read Generator.running while another thread completed the prior await drive and wrote running = false. Consecutive already-settled awaits can be drained by different task pumps during this return-tail handoff.
A plain bool provides neither mutual exclusion nor release/acquire publication for the persistent activation state. Holding resume_mutex across the complete async body is not valid because async JS can pump tasks or join while executing and would create reentrancy/lock-order stalls.
Goal
Give each async-function activation a narrow atomic resume-ownership handoff that publishes prior exec/stack/environment state without holding a lock across arbitrary JavaScript execution.
Acceptance criteria
- Generator running state uses an atomic acquire/release ownership protocol for asyncDrive.
- The next promise job waits only for the prior drive return tail and never drops a continuation because running is transiently true.
- Ordinary generator re-entrant resume still throws through the existing resume_mutex policy.
- A deterministic multi-threaded unit witness proves exact serialized increments and is clean under focused TSan.
- api/condition-async-wait.js remains semantically green and the full no-GIL TSan corpus shard reports no race.
- Mutable-state synchronization documentation is updated.