summaryrefslogtreecommitdiffstats
path: root/js/src/tests/shell/futex.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/shell/futex.js')
-rw-r--r--js/src/tests/shell/futex.js117
1 files changed, 117 insertions, 0 deletions
diff --git a/js/src/tests/shell/futex.js b/js/src/tests/shell/futex.js
new file mode 100644
index 0000000000..f3ad8c0a3e
--- /dev/null
+++ b/js/src/tests/shell/futex.js
@@ -0,0 +1,117 @@
+// |reftest| slow skip-if(!xulRuntime.shell)
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var DEBUG = false;
+
+function dprint(s) {
+ if (DEBUG) print(s);
+}
+
+var hasSharedArrayBuffer = !!(this.SharedArrayBuffer &&
+ this.getSharedObject &&
+ this.setSharedObject);
+
+// Futex test
+
+// Only run if helper threads are available.
+if (hasSharedArrayBuffer && helperThreadCount() !== 0) {
+
+var mem = new Int32Array(new SharedArrayBuffer(1024));
+
+////////////////////////////////////////////////////////////
+
+// wait() returns "not-equal" if the value is not the expected one.
+
+mem[0] = 42;
+
+assertEq(Atomics.wait(mem, 0, 33), "not-equal");
+
+// wait() returns "timed-out" if it times out
+
+assertEq(Atomics.wait(mem, 0, 42, 100), "timed-out");
+
+////////////////////////////////////////////////////////////
+
+// Main is sharing the buffer with the worker; the worker is clearing
+// the buffer.
+
+mem[0] = 42;
+mem[1] = 37;
+mem[2] = DEBUG;
+
+setSharedObject(mem.buffer);
+
+evalInWorker(`
+var mem = new Int32Array(getSharedObject());
+function dprint(s) {
+ if (mem[2]) print(s);
+}
+assertEq(mem[0], 42); // what was written in the main thread
+assertEq(mem[1], 37); // is read in the worker
+mem[1] = 1337;
+dprint("Sleeping for 2 seconds");
+sleep(2);
+dprint("Waking the main thread now");
+setSharedObject(null);
+assertEq(Atomics.notify(mem, 0, 1), 1); // Can fail spuriously but very unlikely
+`);
+
+var then = Date.now();
+assertEq(Atomics.wait(mem, 0, 42), "ok");
+dprint("Woke up as I should have in " + (Date.now() - then)/1000 + "s");
+assertEq(mem[1], 1337); // what was written in the worker is read in the main thread
+assertEq(getSharedObject(), null); // The worker's clearing of the mbx is visible
+
+////////////////////////////////////////////////////////////
+
+// Test the default argument to Atomics.notify()
+
+setSharedObject(mem.buffer);
+
+evalInWorker(`
+var mem = new Int32Array(getSharedObject());
+sleep(2); // Probably long enough to avoid a spurious error next
+assertEq(Atomics.notify(mem, 0), 1); // Last argument to notify should default to +Infinity
+`);
+
+var then = Date.now();
+dprint("Main thread waiting on wakeup (2s)");
+assertEq(Atomics.wait(mem, 0, 42), "ok");
+dprint("Woke up as I should have in " + (Date.now() - then)/1000 + "s");
+
+////////////////////////////////////////////////////////////
+
+// A tricky case: while in the wait there will be an interrupt, and in
+// the interrupt handler we will execute a wait. This is
+// explicitly prohibited (for now), so there should be a catchable exception.
+
+var exn = false;
+timeout(2, function () {
+ dprint("In the interrupt, starting inner wait with timeout 2s");
+ try {
+ Atomics.wait(mem, 0, 42); // Should throw
+ } catch (e) {
+ dprint("Got the interrupt exception!");
+ exn = true;
+ }
+ return true;
+});
+try {
+ dprint("Starting outer wait");
+ assertEq(Atomics.wait(mem, 0, 42, 5000), "timed-out");
+}
+finally {
+ timeout(-1);
+}
+assertEq(exn, true);
+
+////////////////////////////////////////////////////////////
+
+} // if (hasSharedArrayBuffer && helperThreadCount() !== 0) { ... }
+
+dprint("Done");
+reportCompare(true,true);