Source code

Revision control

Copy as Markdown

Other Tools

// |reftest| skip-if(!xulRuntime.shell)
if (helperThreadCount() === 0) {
if (typeof reportCompare === "function")
reportCompare(true, true);
quit();
}
// TypedArray constructors which can use radix sort.
const TAConstructors = [
Int16Array,
Uint16Array,
Int32Array,
Uint32Array,
Float32Array,
];
// Use a large enough size to ensure concurrent accesses can be detected.
const size = 0x4000;
function ToAtomicTA(TA) {
switch (TA) {
case Int16Array:
case Int32Array:
case Uint16Array:
case Uint32Array:
return TA;
case Float32Array:
return Uint32Array;
}
throw new Error("Invalid typed array kind");
}
function ascending(a, b) {
return a < b ? -1 : a > b ? 1 : 0;
}
function descending(a, b) {
return -ascending(a, b);
}
for (let TA of TAConstructors) {
let sorted = new TA(size);
// Fill with |1..size| and then sort to account for wrap-arounds.
for (let i = 0; i < size; ++i) {
sorted[i] = i + 1;
}
sorted.sort();
let extra = Math.max(TA.BYTES_PER_ELEMENT, Int32Array.BYTES_PER_ELEMENT);
let buffer = new SharedArrayBuffer(size * TA.BYTES_PER_ELEMENT + extra);
let controller = new Int32Array(buffer, 0, 1);
// Create a copy in descending order.
let ta = new TA(buffer, extra, size);
ta.set(sorted)
ta.sort(descending);
// Worker code expects that the last element changes when sorted.
assertEq(ta[size - 1] === sorted[size - 1], false);
setSharedObject(buffer);
evalInWorker(`
const ToAtomicTA = ${ToAtomicTA};
const TA = ${TA.name};
const AtomicTA = ToAtomicTA(TA);
let size = ${size};
let extra = ${extra};
let buffer = getSharedObject();
let controller = new Int32Array(buffer, 0, 1);
let ta = new AtomicTA(buffer, extra, size);
let value = Atomics.load(ta, size - 1);
// Coordinate with main thread.
while (Atomics.notify(controller, 0, 1) < 1) ;
// Wait until modification of the last element.
//
// Sorting writes in ascending indexed ordered, so when the last element
// was modified, we know that the sort operation has finished.
while (Atomics.load(ta, size - 1) === value) ;
// Set all elements to zero.
ta.fill(0);
// Sleep for 50 ms.
const amount = 0.05;
// Coordinate with main thread.
while (Atomics.notify(controller, 0, 1) < 1) {
sleep(amount);
}
`);
// Wait until worker is set-up.
assertEq(Atomics.wait(controller, 0, 0), "ok");
// Sort the array in ascending order.
ta.sort();
// Wait until worker has finished.
assertEq(Atomics.wait(controller, 0, 0), "ok");
// All elements have been set to zero.
for (let i = 0; i < size; ++i) {
assertEq(ta[i], 0, `${TA.name} at index ${i} for size ${size}`);
}
}
if (typeof reportCompare === "function")
reportCompare(true, true);