mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 22:32:46 +00:00
Bug 1931315: Rework Atomics.pause to avoid intermittent failures. r=iain
- Perform a single call `setSharedObject`. - Reduce the number of iterations to further decrease the time needed to complete the test. - Simplify the critical section in the worker threads to a non-atomic load-and-store. This avoids interactions with the main-thread, which should help to make the test more reliable. - Check that `Atomics.notify` actually notified all worker threads. Differential Revision: https://phabricator.services.mozilla.com/D229117
This commit is contained in:
parent
2883978598
commit
b55e8ce084
@ -1,25 +1,25 @@
|
||||
// |jit-test| --enable-atomics-pause; skip-if: !Atomics.pause || helperThreadCount() === 0 || getBuildConfiguration("arm64-simulator") === true
|
||||
|
||||
function startWorker(worker, buffer) {
|
||||
setSharedObject(buffer);
|
||||
|
||||
function startWorker(worker) {
|
||||
evalInWorker(`
|
||||
(${worker})(getSharedObject());
|
||||
`);
|
||||
}
|
||||
|
||||
// Index 0: Main Lock
|
||||
// Index 1: Worker Lock
|
||||
// Index 0: Worker Lock
|
||||
// Index 1: Counter
|
||||
// Index 2: Sync
|
||||
// Index 3: Worker State
|
||||
let sab = new SharedArrayBuffer(4 * Int32Array.BYTES_PER_ELEMENT)
|
||||
let i32 = new Int32Array(sab);
|
||||
|
||||
setSharedObject(sab);
|
||||
|
||||
// Number of workers.
|
||||
const N = 4;
|
||||
|
||||
// Number of iterations.
|
||||
const K = 10_000;
|
||||
const K = N * 1000;
|
||||
|
||||
for (let i = 0; i < N; ++i) {
|
||||
startWorker(function(sab) {
|
||||
@ -27,7 +27,7 @@ for (let i = 0; i < N; ++i) {
|
||||
const N = 4;
|
||||
|
||||
// Number of iterations.
|
||||
const K = 10_000;
|
||||
const K = N * 1000;
|
||||
|
||||
let i32 = new Int32Array(sab);
|
||||
|
||||
@ -40,21 +40,24 @@ for (let i = 0; i < N; ++i) {
|
||||
for (let i = 0; i < K / N; ++i) {
|
||||
// Spin-wait loop using a "test, test-and-set" technique.
|
||||
while (true) {
|
||||
while (Atomics.load(i32, 1) !== 0) {
|
||||
while (Atomics.load(i32, 0) !== 0) {
|
||||
Atomics.pause();
|
||||
}
|
||||
if (Atomics.exchange(i32, 1, 1) === 0) {
|
||||
if (Atomics.exchange(i32, 0, 1) === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// "Critical section" - pass control to main thread.
|
||||
// "Critical section" - non-atomic load-and-store.
|
||||
i32[1] += 1;
|
||||
|
||||
// Leave "Critical section".
|
||||
Atomics.store(i32, 0, 0);
|
||||
}
|
||||
|
||||
// Mark worker as finished.
|
||||
Atomics.sub(i32, 3, 1);
|
||||
}, sab);
|
||||
});
|
||||
}
|
||||
|
||||
// Wait until all worker threads have started.
|
||||
@ -63,24 +66,13 @@ while (Atomics.load(i32, 3) !== N) {
|
||||
}
|
||||
|
||||
// Start work in all worker threads.
|
||||
Atomics.notify(i32, 2, N);
|
||||
|
||||
for (let i = 0; i < K; ++i) {
|
||||
// Spin-wait loop using a "test, test-and-set" technique.
|
||||
while (true) {
|
||||
while (Atomics.load(i32, 0) !== 0) {
|
||||
Atomics.pause();
|
||||
}
|
||||
if (Atomics.exchange(i32, 0, 1) === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// "Critical section" - pass control to a worker thread.
|
||||
Atomics.store(i32, 1, 0);
|
||||
let woken = 0;
|
||||
while ((woken += Atomics.notify(i32, 2, N)) !== N) {
|
||||
}
|
||||
|
||||
// Wait until all worker threads have finished.
|
||||
while (Atomics.load(i32, 3) !== 0) {
|
||||
Atomics.pause();
|
||||
}
|
||||
|
||||
assertEq(i32[1], K);
|
||||
|
Loading…
Reference in New Issue
Block a user