mutual-exclusion.js (2774B)
1 // |jit-test| skip-if: helperThreadCount() === 0 || getBuildConfiguration("arm64-simulator") === true 2 3 // Let a few threads hammer on memory with atomics to provoke errors 4 // in exclusion work. This test is not 100% fail-safe: the test may 5 // pass despite a bug, but this is unlikely. 6 7 // Map an Int32Array on shared memory. The first location is used as 8 // a counter, each worker counts up on exit and the main thread will 9 // wait until the counter reaches the number of workers. The other 10 // elements are contended accumulators where we count up and down very 11 // rapidly and for a long time, any failure in mutual exclusion should 12 // lead to errors in the result. (For example, the test fails almost 13 // immediately when I disable simulation of mutual exclusion in the 14 // ARM simulator.) 15 16 const numWorkers = 4; // You're not meant to change this 17 const iterCount = 255; // Nor this 18 const sabLength = 1024; // Nor this 19 20 const oddResult = (function () { 21 var v = 0; 22 for ( var j=0 ; j < numWorkers ; j++ ) 23 v |= (iterCount << (8 * j)); 24 return v; 25 })(); 26 27 const evenResult = 0; 28 29 const sab = new SharedArrayBuffer(sabLength); 30 31 setSharedObject(sab); 32 33 const iab = new Int32Array(sab); 34 35 function testRun(limit) { 36 console.log("Limit = " + limit); 37 38 // Fork off workers to hammer on memory. 39 for ( var i=0 ; i < numWorkers ; i++ ) { 40 evalInWorker(` 41 const iab = new Int32Array(getSharedObject()); 42 const v = 1 << (8 * ${i}); 43 for ( var i=0 ; i < ${limit} ; i++ ) { 44 for ( var k=0 ; k < ${iterCount} ; k++ ) { 45 if (i & 1) { 46 for ( var j=1 ; j < iab.length ; j++ ) 47 Atomics.sub(iab, j, v); 48 } 49 else { 50 for ( var j=1 ; j < iab.length ; j++ ) 51 Atomics.add(iab, j, v); 52 } 53 } 54 } 55 Atomics.add(iab, 0, 1); 56 `); 57 } 58 59 // Wait... 60 while (Atomics.load(iab, 0) != numWorkers) 61 ; 62 Atomics.store(iab, 0, 0); 63 64 // Check the results and clear the array again. 65 const v = (limit & 1) ? oddResult : evenResult; 66 for ( var i=1 ; i < iab.length ; i++ ) { 67 assertEq(iab[i], v); 68 iab[i] = 0; 69 } 70 } 71 72 // Under some configurations the test can take a while to run (and may 73 // saturate the CPU since it runs four workers); try not to time out. 74 75 var then = new Date(); 76 testRun(1); 77 if (new Date() - then < 20000) { 78 testRun(2); 79 if (new Date() - then < 30000) { 80 testRun(3); 81 } 82 }