Multi-core simulation: grain movement and heat across a worker pool (t88 phase 3)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
// Browser transport only; the simulation owns the schedule and shared state.
|
||||
let threadStarting = null;
|
||||
async function startThreads() {
|
||||
const count = Math.max(1, Math.min(16, Math.floor(SET.workerCap) || 16, (navigator.hardwareConcurrency || 3) - 2));
|
||||
if (simPool && simPool.world === mat && simPool.workers.length === count) return;
|
||||
if (threadStarting) await threadStarting;
|
||||
if (simPool && simPool.world === mat && simPool.workers.length === count) return;
|
||||
threadStarting = (async () => {
|
||||
if (simPool) for (const worker of simPool.workers) worker.terminate();
|
||||
simPool = null;
|
||||
if (!(mat.buffer instanceof SharedArrayBuffer)) throw Error('Shared memory is unavailable');
|
||||
const url = URL.createObjectURL(new Blob([SIM_WORKER_SOURCE, '\nonmessage=e=>threadMessage(e.data);'], {type:'text/javascript'}));
|
||||
const pool = { world: mat, workers: [], slots: [] };
|
||||
try {
|
||||
const ready = [];
|
||||
for (let k = 0; k < count; k++) {
|
||||
const worker = new Worker(url), slot = threadSlot();
|
||||
pool.workers.push(worker); pool.slots.push(slot);
|
||||
ready.push(new Promise((resolve,reject) => {
|
||||
const deadline = performance.now() + 10000;
|
||||
worker.onerror = e => {
|
||||
const error = Error(e.message || 'Simulation worker failed');
|
||||
threadFailure(slot, error); reject(error);
|
||||
};
|
||||
const poll = () => {
|
||||
if (Atomics.load(slot.control,0)) resolve();
|
||||
else if (performance.now() > deadline) reject(Error('Simulation worker startup timed out'));
|
||||
else setTimeout(poll, 1);
|
||||
};
|
||||
poll();
|
||||
}));
|
||||
worker.postMessage({world:threadWorld(),slot});
|
||||
}
|
||||
await Promise.all(ready); simPool = pool;
|
||||
} catch (e) { for (const worker of pool.workers) worker.terminate(); throw e; }
|
||||
finally { URL.revokeObjectURL(url); }
|
||||
})();
|
||||
try { await threadStarting; } finally { threadStarting = null; }
|
||||
}
|
||||
Reference in New Issue
Block a user