title: Javascript Synchronize SharedArrayBuffer to main thread
body: <p>I have a problem synchronizing a <code>SharedArrayBuffer</code> to the main thread.</p>
  
  <p>Here is the scenario:</p>
  
  <p>I got two worker which handle different aspects of my program. The first worker is responsible for object interaction, the second for calculating visibilities etc and the main thread will do the visualization.</p>
  
  <p>At first the first Worker creates a <code>SharedArrayBuffer</code> with the following layout:</p>
  
  <pre><code>new SharedArrayBuffer(112);
  [   
      Lock:      4 Byte
      MetaInfo:  4 Byte
      Location: 12 Byte
      Scale:    12 Byte
      Rotation: 16 Byte
      Matrix:   64 Byte
  ]
  </code></pre>
  
  <p>He then sends the SAB to the main thread and second Worker and stores the location scale and rotation attributes in the Buffer. Every time he updates the fields he locks the SAB, updates the values and sets the first bit of the MetaInfo fields (transform flag) to true.</p>
  
  <p>The second Worker will compute the matrix from the given location scale and rotation fields if the transform flag is set and save it in the Matrix fields. Afterward the second bit of the MetaInfo fields (matrix flag) will be set to true.</p>
  
  <p>The main thread now needs to read the final matrix if the matrix flag is set.</p>
  
  <p>Here comes the problem: On the workers it is possible to lock the buffer using the <code>Atomics.wait</code> method on the Lock fields. But the main thread lacks such features resulting in stuttering and "hopping". Is there a consistent way to prevent the other worker from writing into the SAB during the reading process?</p>
  
  <p>Here is the code of my <code>SharedArrayBuffer</code> wrapper:</p>
  
  <pre><code>class SharedObject {
      SharedBuffer: SharedArrayBuffer; // the shared array buffer
      Lock: Int32Array;  // view for lockíng the buffer
      MetaInfo: Int32Array; // view for meta info
      Location: Float32Array;
  
      constructor(buffer) {
          // if valid buffer is passed assign it to this object
          if (buffer !== undefined &amp;&amp; buffer instanceof SharedArrayBuffer &amp;&amp; buffer.byteLength == 112) {
              this.SharedBuffer = buffer;
          } else {
              // create new shared array buffer
              this.SharedBuffer = new SharedArrayBuffer(112);
          }
  
          this.Lock = new Int32Array(this.SharedBuffer, 0, 4);
          this.MetaInfo = new Int32Array(this.SharedBuffer, 4, 8);
  
          [ ... init the rest of the views ... ]
  
          // init the lock element
          if (buffer === undefined) {
              Atomics.store(this.Lock, 0, 1);
          }
  
      }
  
      lock() {
          Atomics.wait(this.Lock, 0, 0);
          Atomics.store(this.Lock, 0, 0);
          return true;
      }
  
      free() {
          if (Atomics.wake(this.Lock, 0, 1) == 0) {
              Atomics.store(this.Lock, 0, 1);
          }
          return true;
      }
  
      setFlag(flag) {
          this.MetaInfo[0] = this.MetaInfo[0] | flag;
      }
      isFlagSet(flag) {
          return (this.MetaInfo[0] &amp; flag) &gt; 0;
      }
      resetFlag(flag) {
          this.MetaInfo[0] = this.MetaInfo[0] - (this.MetaInfo[0] &amp; flag);
      }
  }
  </code></pre>
  
  <p>Note the lock and free method are not use able in main thread since:</p>
  
  <blockquote>
    <p>Note: This operation only works with a shared Int32Array and is not allowed on the main thread.</p>
  </blockquote>
  
  <p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/wait" rel="nofollow noreferrer">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/wait</a></p>
  
  <p>Is this setup even possible to have multiple independent fields in one <code>SharedArrayBuffer</code> or should I consider using multiple <code>SharedArrayBuffer</code> for each application.</p>