summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/TypedArray/sort_modifications_concurrent_radixsort.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/src/tests/non262/TypedArray/sort_modifications_concurrent_radixsort.js116
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);