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:
2026-10-28 03:23:43 -04:00
co-authored by Claude Opus 5.5
parent 20963c776e
commit 7468d00efb
35 changed files with 578 additions and 113 deletions
+31
View File
@@ -81,3 +81,34 @@ function dump(run, x0, y0, x1, y1, withTemp) {
}
}
module.exports.dump = dump;
// Node uses exactly the browser worker entry point and scheduler.
async function enableThreads(run, count) {
const { Worker } = require('worker_threads');
const entry = `const {parentPort}=require('worker_threads');
require(${JSON.stringify(__filename)}).load();
parentPort.on('message', data=>threadMessage(data));`;
const pool = { world: run('mat'), workers: [], slots: [], force: true };
try {
const ready = [];
for (let k = 0; k < count; k++) {
const worker = new Worker(entry, {eval:true}), slot = run('threadSlot()');
pool.workers.push(worker); pool.slots.push(slot);
ready.push(new Promise((resolve,reject) => {
const deadline = Date.now()+10000;
worker.once('error',reject);
const poll = () => {
if (Atomics.load(slot.control,0)) resolve();
else if (Date.now()>deadline) reject(Error('Worker startup timed out'));
else setTimeout(poll,1);
};
poll();
}));
worker.postMessage({world:run('threadWorld()'),slot});
}
await Promise.all(ready);
globalThis.__testPool = pool; run('simPool = globalThis.__testPool;'); delete globalThis.__testPool;
return async () => { run('simPool=null;'); await Promise.all(pool.workers.map(w=>w.terminate())); };
} catch (e) { await Promise.all(pool.workers.map(w=>w.terminate())); throw e; }
}
module.exports.enableThreads = enableThreads;