-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bug 1763606 - Part 4: Add a test case for concurrent modifications wh…
…en sorting. r=tcampbell Depends on D143287 Differential Revision: https://phabricator.services.mozilla.com/D143288
- Loading branch information
Showing
1 changed file
with
145 additions
and
0 deletions.
There are no files selected for viewing
145 changes: 145 additions & 0 deletions
145
js/src/tests/non262/TypedArray/sort_modifications_concurrent.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
// |reftest| skip-if(!xulRuntime.shell) | ||
|
||
if (helperThreadCount() === 0) { | ||
if (typeof reportCompare === "function") | ||
reportCompare(true, true); | ||
quit(); | ||
} | ||
|
||
const TAConstructors = [ | ||
Int8Array, | ||
Uint8Array, | ||
Int16Array, | ||
Uint16Array, | ||
Int32Array, | ||
Uint32Array, | ||
Uint8ClampedArray, | ||
Float32Array, | ||
Float64Array, | ||
BigInt64Array, | ||
BigUint64Array, | ||
]; | ||
|
||
// Use different size classes to catch any implementation-specific | ||
// optimisations. | ||
const sizes = [ | ||
4, 8, 64, 128, 1024 | ||
]; | ||
|
||
function ToNumeric(TA) { | ||
if (TA === BigInt64Array || TA === BigUint64Array) { | ||
return BigInt; | ||
} | ||
return Number; | ||
} | ||
|
||
function ToAtomicTA(TA) { | ||
switch (TA) { | ||
case Int8Array: | ||
case Int16Array: | ||
case Int32Array: | ||
case Uint8Array: | ||
case Uint16Array: | ||
case Uint32Array: | ||
case BigInt64Array: | ||
case BigUint64Array: | ||
return TA; | ||
case Uint8ClampedArray: | ||
return Uint8Array; | ||
case Float32Array: | ||
return Uint32Array; | ||
case Float64Array: | ||
return BigUint64Array; | ||
} | ||
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 toNumeric = ToNumeric(TA); | ||
for (let size of sizes) { | ||
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] = toNumeric(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 ToNumeric = ${ToNumeric}; | ||
const ToAtomicTA = ${ToAtomicTA}; | ||
const TA = ${TA.name}; | ||
const AtomicTA = ToAtomicTA(TA); | ||
let size = ${size}; | ||
let extra = ${extra}; | ||
let toNumeric = ToNumeric(AtomicTA); | ||
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(toNumeric(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. | ||
let zero = toNumeric(0); | ||
for (let i = 0; i < size; ++i) { | ||
assertEq(ta[i], zero, `${TA.name} at index ${i} for size ${size}`); | ||
} | ||
} | ||
} | ||
|
||
if (typeof reportCompare === "function") | ||
reportCompare(true, true); |