diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/src/tests/non262/TypedArray/sort_modifications_concurrent_radixsort.js | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/tests/non262/TypedArray/sort_modifications_concurrent_radixsort.js')
-rw-r--r-- | js/src/tests/non262/TypedArray/sort_modifications_concurrent_radixsort.js | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/js/src/tests/non262/TypedArray/sort_modifications_concurrent_radixsort.js b/js/src/tests/non262/TypedArray/sort_modifications_concurrent_radixsort.js new file mode 100644 index 0000000000..c6de0f1ece --- /dev/null +++ b/js/src/tests/non262/TypedArray/sort_modifications_concurrent_radixsort.js @@ -0,0 +1,116 @@ +// |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); |