// |jit-test| skip-if: helperThreadCount() === 0 || getBuildConfiguration()["arm64-simulator"] === true // Let a few threads hammer on memory with atomics to provoke errors // in exclusion work. This test is not 100% fail-safe: the test may // pass despite a bug, but this is unlikely. // Map an Int32Array on shared memory. The first location is used as // a counter, each worker counts up on exit and the main thread will // wait until the counter reaches the number of workers. The other // elements are contended accumulators where we count up and down very // rapidly and for a long time, any failure in mutual exclusion should // lead to errors in the result. (For example, the test fails almost // immediately when I disable simulation of mutual exclusion in the // ARM simulator.) const numWorkers = 4; // You're not meant to change this const iterCount = 255; // Nor this const sabLength = 1024; // Nor this const oddResult = (function () { var v = 0; for ( var j=0 ; j < numWorkers ; j++ ) v |= (iterCount << (8 * j)); return v; })(); const evenResult = 0; const sab = new SharedArrayBuffer(sabLength); setSharedObject(sab); const iab = new Int32Array(sab); function testRun(limit) { console.log("Limit = " + limit); // Fork off workers to hammer on memory. for ( var i=0 ; i < numWorkers ; i++ ) { evalInWorker(` const iab = new Int32Array(getSharedObject()); const v = 1 << (8 * ${i}); for ( var i=0 ; i < ${limit} ; i++ ) { for ( var k=0 ; k < ${iterCount} ; k++ ) { if (i & 1) { for ( var j=1 ; j < iab.length ; j++ ) Atomics.sub(iab, j, v); } else { for ( var j=1 ; j < iab.length ; j++ ) Atomics.add(iab, j, v); } } } Atomics.add(iab, 0, 1); `); } // Wait... while (Atomics.load(iab, 0) != numWorkers) ; Atomics.store(iab, 0, 0); // Check the results and clear the array again. const v = (limit & 1) ? oddResult : evenResult; for ( var i=1 ; i < iab.length ; i++ ) { assertEq(iab[i], v); iab[i] = 0; } } // Under some configurations the test can take a while to run (and may // saturate the CPU since it runs four workers); try not to time out. var then = new Date(); testRun(1); if (new Date() - then < 20000) { testRun(2); if (new Date() - then < 30000) { testRun(3); } }