futex.js (3328B)
1 // |reftest| slow skip-if(!xulRuntime.shell) 2 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 3 /* 4 * Any copyright is dedicated to the Public Domain. 5 * http://creativecommons.org/licenses/publicdomain/ 6 */ 7 8 var DEBUG = false; 9 10 function dprint(s) { 11 if (DEBUG) print(s); 12 } 13 14 var hasSharedArrayBuffer = !!(this.SharedArrayBuffer && 15 this.getSharedObject && 16 this.setSharedObject); 17 18 // Futex test 19 20 // Only run if helper threads are available. 21 if (hasSharedArrayBuffer && helperThreadCount() !== 0) { 22 23 var mem = new Int32Array(new SharedArrayBuffer(1024)); 24 25 //////////////////////////////////////////////////////////// 26 27 // wait() returns "not-equal" if the value is not the expected one. 28 29 mem[0] = 42; 30 31 assertEq(Atomics.wait(mem, 0, 33), "not-equal"); 32 33 // wait() returns "timed-out" if it times out 34 35 assertEq(Atomics.wait(mem, 0, 42, 100), "timed-out"); 36 37 //////////////////////////////////////////////////////////// 38 39 // Main is sharing the buffer with the worker; the worker is clearing 40 // the buffer. 41 42 mem[0] = 42; 43 mem[1] = 37; 44 mem[2] = DEBUG; 45 46 setSharedObject(mem.buffer); 47 48 evalInWorker(` 49 var mem = new Int32Array(getSharedObject()); 50 function dprint(s) { 51 if (mem[2]) print(s); 52 } 53 assertEq(mem[0], 42); // what was written in the main thread 54 assertEq(mem[1], 37); // is read in the worker 55 mem[1] = 1337; 56 dprint("Sleeping for 2 seconds"); 57 sleep(2); 58 dprint("Waking the main thread now"); 59 setSharedObject(null); 60 assertEq(Atomics.notify(mem, 0, 1), 1); // Can fail spuriously but very unlikely 61 `); 62 63 var then = Date.now(); 64 assertEq(Atomics.wait(mem, 0, 42), "ok"); 65 dprint("Woke up as I should have in " + (Date.now() - then)/1000 + "s"); 66 assertEq(mem[1], 1337); // what was written in the worker is read in the main thread 67 assertEq(getSharedObject(), null); // The worker's clearing of the mbx is visible 68 69 //////////////////////////////////////////////////////////// 70 71 // Test the default argument to Atomics.notify() 72 73 setSharedObject(mem.buffer); 74 75 evalInWorker(` 76 var mem = new Int32Array(getSharedObject()); 77 sleep(2); // Probably long enough to avoid a spurious error next 78 assertEq(Atomics.notify(mem, 0), 1); // Last argument to notify should default to +Infinity 79 `); 80 81 var then = Date.now(); 82 dprint("Main thread waiting on wakeup (2s)"); 83 assertEq(Atomics.wait(mem, 0, 42), "ok"); 84 dprint("Woke up as I should have in " + (Date.now() - then)/1000 + "s"); 85 86 //////////////////////////////////////////////////////////// 87 88 // A tricky case: while in the wait there will be an interrupt, and in 89 // the interrupt handler we will execute a wait. This is 90 // explicitly prohibited (for now), so there should be a catchable exception. 91 92 var exn = false; 93 timeout(2, function () { 94 dprint("In the interrupt, starting inner wait with timeout 2s"); 95 try { 96 Atomics.wait(mem, 0, 42); // Should throw 97 } catch (e) { 98 dprint("Got the interrupt exception!"); 99 exn = true; 100 } 101 return true; 102 }); 103 try { 104 dprint("Starting outer wait"); 105 assertEq(Atomics.wait(mem, 0, 42, 5000), "timed-out"); 106 } 107 finally { 108 timeout(-1); 109 } 110 assertEq(exn, true); 111 112 //////////////////////////////////////////////////////////// 113 114 } // if (hasSharedArrayBuffer && helperThreadCount() !== 0) { ... } 115 116 dprint("Done"); 117 reportCompare(true,true);