JSFiddle - React, Tailwind, and code Playground

by msfrisbie

JavaScript

const workerScript = `
const LOCKED = 0;
const UNLOCKED = 1;
const LOCK_IDX = 0;
const DATA_IDX = 1;

self.onmessage = ({data}) => {
  const view = new Int32Array(data);

  console.log('Waiting to obtain lock');

  // Wait while the lock index is locked, timeout at 10000ms
  Atomics.wait(view, LOCK_IDX, LOCKED, 1E5);
  
  console.log('Obtained lock');
  
  // Obtain a lock
  //Atomics.store(view, LOCK_IDX, LOCKED);

  // Add 1 to data index
  Atomics.add(view, DATA_IDX, 1);
    
  console.log('Releasing lock');
    
  // Free the lock
  //Atomics.store(view, LOCK_IDX, UNLOCKED);
    
  // Allow exactly one worker to continue execution
  Atomics.notify(view, LOCK_IDX, 1);
    
  self.postMessage(null);
};
`;

const workerScriptBlobUrl = URL.createObjectURL(new Blob([workerScript]));

const workers = [];
for (let i = 0; i < 4; ++i) {
  workers.push(new Worker(workerScriptBlobUrl));
}

// Log the final value after the last worker completes
let responseCount = 0;
for (const worker of workers) {
  worker.onmessage = () => {
    if (++responseCount == workers.length) {
      console.log(`Final buffer value: ${view[1]}`);
    }
  };
}

// Initialize the SharedArrayBuffer
const sharedArrayBuffer = new SharedArrayBuffer(8);
const view = new Int32Array(sharedArrayBuffer);

// Send the SharedArrayBuffer to each worker
for (const worker of workers) {
  worker.postMessage(sharedArrayBuffer);
}

// Release first lock in 1000ms
setTimeout(() => Atomics.notify(view, 0, 1), 1000);

// Final buffer value: 4