2017-09-08 18:01:20 +00:00
|
|
|
// Copyright 2017 the V8 project authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
let sab = new SharedArrayBuffer(10 * 4);
|
|
|
|
let memory = new Int32Array(sab);
|
|
|
|
let workers = [];
|
|
|
|
let runningWorkers = 0;
|
|
|
|
|
|
|
|
function startWorker(script) {
|
2018-09-19 23:30:04 +00:00
|
|
|
let worker = new Worker(script, {type: 'string'});
|
2017-09-08 18:01:20 +00:00
|
|
|
worker.done = false;
|
|
|
|
worker.idx = workers.length;
|
|
|
|
workers.push(worker);
|
|
|
|
worker.postMessage(memory);
|
|
|
|
++runningWorkers;
|
|
|
|
};
|
|
|
|
|
|
|
|
let shared = `
|
|
|
|
function wait(memory, index, waitCondition, wakeCondition) {
|
|
|
|
while (memory[index] == waitCondition) {
|
|
|
|
var result = Atomics.wait(memory, index, waitCondition);
|
|
|
|
switch (result) {
|
|
|
|
case 'not-equal':
|
|
|
|
case 'ok':
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
postMessage('Error: bad result from wait: ' + result);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
var value = memory[index];
|
|
|
|
if (value != wakeCondition) {
|
|
|
|
postMessage(
|
|
|
|
'Error: wait returned not-equal but the memory has a bad value: ' +
|
|
|
|
value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var value = memory[index];
|
|
|
|
if (value != wakeCondition) {
|
|
|
|
postMessage(
|
|
|
|
'Error: done waiting but the memory has a bad value: ' + value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function wake(memory, index) {
|
2020-07-31 22:02:36 +00:00
|
|
|
var result = Atomics.notify(memory, index, 1);
|
2017-09-08 18:01:20 +00:00
|
|
|
if (result != 0 && result != 1) {
|
|
|
|
postMessage('Error: bad result from wake: ' + result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`;
|
|
|
|
|
|
|
|
let worker1 = startWorker(shared + `
|
|
|
|
onmessage = function(msg) {
|
|
|
|
let memory = msg;
|
|
|
|
const didStartIdx = 0;
|
|
|
|
const shouldGoIdx = 1;
|
|
|
|
const didEndIdx = 2;
|
|
|
|
|
|
|
|
postMessage("started");
|
|
|
|
postMessage("memory: " + memory);
|
|
|
|
wait(memory, didStartIdx, 0, 1);
|
|
|
|
memory[shouldGoIdx] = 1;
|
|
|
|
wake(memory, shouldGoIdx);
|
|
|
|
wait(memory, didEndIdx, 0, 1);
|
|
|
|
postMessage("memory: " + memory);
|
|
|
|
postMessage("done");
|
|
|
|
};
|
|
|
|
`);
|
|
|
|
|
|
|
|
let worker2 = startWorker(shared + `
|
|
|
|
onmessage = function(msg) {
|
|
|
|
let memory = msg;
|
|
|
|
const didStartIdx = 0;
|
|
|
|
const shouldGoIdx = 1;
|
|
|
|
const didEndIdx = 2;
|
|
|
|
|
|
|
|
postMessage("started");
|
|
|
|
postMessage("memory: " + memory);
|
|
|
|
Atomics.store(memory, didStartIdx, 1);
|
|
|
|
wake(memory, didStartIdx);
|
|
|
|
wait(memory, shouldGoIdx, 0, 1);
|
|
|
|
Atomics.store(memory, didEndIdx, 1);
|
|
|
|
wake(memory, didEndIdx, 1);
|
|
|
|
postMessage("memory: " + memory);
|
|
|
|
postMessage("done");
|
|
|
|
};
|
|
|
|
`);
|
|
|
|
|
|
|
|
let running = true;
|
|
|
|
while (running) {
|
|
|
|
for (let worker of workers) {
|
|
|
|
if (worker.done) continue;
|
|
|
|
|
|
|
|
let msg = worker.getMessage();
|
|
|
|
if (msg) {
|
|
|
|
switch (msg) {
|
|
|
|
case "done":
|
|
|
|
if (worker.done === false) {
|
|
|
|
print("worker #" + worker.idx + " done.");
|
|
|
|
worker.done = true;
|
|
|
|
if (--runningWorkers === 0) {
|
|
|
|
running = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
print("msg from worker #" + worker.idx + ": " + msg);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|