From a5f2758bcfdd2be7d24e6d9c40eacb50e6c93a3e Mon Sep 17 00:00:00 2001 From: shaun0927 <70629228+shaun0927@users.noreply.github.com> Date: Thu, 14 May 2026 11:29:22 +0900 Subject: [PATCH] Stop spinning while waiting for zombie cleanup locks Constraint: Preserve synchronous registry APIs and existing lock timeout/retry semantics. Rejected: Keep a JavaScript busy-spin loop | it wastes CPU during simulator cleanup contention. Confidence: high Scope-risk: narrow Directive: Any future async lock migration should preserve active-simulator protection semantics first. Tested: npm test -- --runTestsByPath tests/unit/zombie-cleanup-lock.test.ts tests/unit/zombie-cleanup-cross-session.test.ts; npm run lint -- --quiet src/reliability/zombie-cleanup.ts tests/unit/zombie-cleanup-lock.test.ts; npm run build Not-tested: Live multi-process lock contention CPU profile. --- src/reliability/zombie-cleanup.ts | 11 +++++++++-- tests/unit/zombie-cleanup-lock.test.ts | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 tests/unit/zombie-cleanup-lock.test.ts diff --git a/src/reliability/zombie-cleanup.ts b/src/reliability/zombie-cleanup.ts index 0d62b144..43b38312 100644 --- a/src/reliability/zombie-cleanup.ts +++ b/src/reliability/zombie-cleanup.ts @@ -12,6 +12,14 @@ const LOCK_STALE_MS = 10000; const LOCK_RETRY_MS = 50; const LOCK_TIMEOUT_MS = 5000; +export function sleepWithoutBusySpin(ms: number): void { + const duration = Math.max(0, Math.floor(ms)); + if (duration === 0) return; + const buffer = new SharedArrayBuffer(4); + const view = new Int32Array(buffer); + Atomics.wait(view, 0, 0, duration); +} + function acquireLock(): boolean { const deadline = Date.now() + LOCK_TIMEOUT_MS; while (Date.now() < deadline) { @@ -34,8 +42,7 @@ function acquireLock(): boolean { releaseLock(); continue; } - const waitUntil = Date.now() + LOCK_RETRY_MS; - while (Date.now() < waitUntil) { /* spin */ } + sleepWithoutBusySpin(LOCK_RETRY_MS); continue; } return false; diff --git a/tests/unit/zombie-cleanup-lock.test.ts b/tests/unit/zombie-cleanup-lock.test.ts new file mode 100644 index 00000000..7ce1b3fa --- /dev/null +++ b/tests/unit/zombie-cleanup-lock.test.ts @@ -0,0 +1,16 @@ +import { sleepWithoutBusySpin } from '../../src/reliability/zombie-cleanup'; + +describe('zombie cleanup registry lock wait helper', () => { + it('returns immediately for non-positive durations', () => { + const start = Date.now(); + sleepWithoutBusySpin(0); + sleepWithoutBusySpin(-10); + expect(Date.now() - start).toBeLessThan(25); + }); + + it('waits for approximately the requested duration without a JavaScript spin loop', () => { + const start = Date.now(); + sleepWithoutBusySpin(15); + expect(Date.now() - start).toBeGreaterThanOrEqual(10); + }); +});