blob: c50af5f317c2885d66ef52e4c8ba4fca20d67960 [file] [log] [blame]
// 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) {
let worker = new Worker(script, {type: 'string'});
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) {
var result = Atomics.notify(memory, index, 1);
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;
}
}
}
}