tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }