70 lines
1.7 KiB
JavaScript
70 lines
1.7 KiB
JavaScript
|
// Copyright 2021 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.
|
||
|
|
||
|
// Flags: --harmony-sharedarraybuffer
|
||
|
|
||
|
function workerCode1() {
|
||
|
onmessage = function(e) {
|
||
|
const a = new Int32Array(e.sab);
|
||
|
while(true) {
|
||
|
// This worker tries to switch the value from 1 to 2; if it succeeds, it
|
||
|
// also notifies.
|
||
|
const ret = Atomics.compareExchange(a, 0, 1, 2);
|
||
|
if (ret === 1) {
|
||
|
Atomics.notify(a, 0);
|
||
|
}
|
||
|
// Check if we're asked to terminate:
|
||
|
if (Atomics.load(a, 1) == 1) {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function workerCode2() {
|
||
|
const MAX_ROUNDS = 40;
|
||
|
onmessage = function(e) {
|
||
|
const a = new Int32Array(e.sab);
|
||
|
let round = 0;
|
||
|
function nextRound() {
|
||
|
while (true) {
|
||
|
if (round == MAX_ROUNDS) {
|
||
|
// Tell worker1 to terminate.
|
||
|
Atomics.store(a, 1, 1);
|
||
|
postMessage('done');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// This worker changes the value to 1, and waits for it to change to 2
|
||
|
// via Atomics.waitAsync.
|
||
|
Atomics.store(a, 0, 1);
|
||
|
|
||
|
const res = Atomics.waitAsync(a, 0, 1);
|
||
|
if (res.async) {
|
||
|
res.value.then(() => { ++round; nextRound();},
|
||
|
()=> {});
|
||
|
return;
|
||
|
}
|
||
|
// Else: continue looping. (This happens when worker1 changed the value
|
||
|
// back to 2 before waitAsync started.)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
nextRound();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
let sab = new SharedArrayBuffer(8);
|
||
|
|
||
|
let w1 = new Worker(workerCode1, {type: 'function'});
|
||
|
w1.postMessage({sab: sab});
|
||
|
|
||
|
let w2 = new Worker(workerCode2, {type: 'function'});
|
||
|
w2.postMessage({sab: sab});
|
||
|
|
||
|
// Wait for worker2.
|
||
|
w2.getMessage();
|
||
|
w1.terminate();
|
||
|
w2.terminate();
|