pause-multi.js (1703B)
1 // |jit-test| --enable-atomics-pause; skip-if: !Atomics.pause || helperThreadCount() === 0 || getBuildConfiguration("arm64-simulator") === true 2 3 function startWorker(worker) { 4 evalInWorker(` 5 (${worker})(getSharedObject()); 6 `); 7 } 8 9 // Index 0: Worker Lock 10 // Index 1: Counter 11 // Index 2: Sync 12 // Index 3: Worker State 13 let sab = new SharedArrayBuffer(4 * Int32Array.BYTES_PER_ELEMENT) 14 let i32 = new Int32Array(sab); 15 16 setSharedObject(sab); 17 18 // Number of workers. 19 const N = 4; 20 21 // Number of iterations. 22 const K = N * 1000; 23 24 for (let i = 0; i < N; ++i) { 25 startWorker(function(sab) { 26 // Number of workers. 27 const N = 4; 28 29 // Number of iterations. 30 const K = N * 1000; 31 32 let i32 = new Int32Array(sab); 33 34 // Mark worker as started. 35 Atomics.add(i32, 3, 1); 36 37 // Wait until main thread is ready. 38 Atomics.wait(i32, 2, 0); 39 40 for (let i = 0; i < K / N; ++i) { 41 // Spin-wait loop using a "test, test-and-set" technique. 42 while (true) { 43 while (Atomics.load(i32, 0) !== 0) { 44 Atomics.pause(); 45 } 46 if (Atomics.exchange(i32, 0, 1) === 0) { 47 break; 48 } 49 } 50 51 // "Critical section" - non-atomic load-and-store. 52 i32[1] += 1; 53 54 // Leave "Critical section". 55 Atomics.store(i32, 0, 0); 56 } 57 58 // Mark worker as finished. 59 Atomics.sub(i32, 3, 1); 60 }); 61 } 62 63 // Wait until all worker threads have started. 64 while (Atomics.load(i32, 3) !== N) { 65 Atomics.pause(); 66 } 67 68 // Start work in all worker threads. 69 let woken = 0; 70 while ((woken += Atomics.notify(i32, 2, N)) !== N) { 71 } 72 73 // Wait until all worker threads have finished. 74 while (Atomics.load(i32, 3) !== 0) { 75 Atomics.pause(); 76 } 77 78 assertEq(i32[1], K);