| // Copyright 2017 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| let sab = new SharedArrayBuffer(10 * 4); |
| let memory = new Int32Array(sab); |
| let workers = []; |
| let runningWorkers = 0; |
| |
| function startWorker(script) { |
| let worker = new Worker(script, {type: 'string'}); |
| worker.done = false; |
| worker.idx = workers.length; |
| workers.push(worker); |
| worker.postMessage(memory); |
| ++runningWorkers; |
| }; |
| |
| let shared = ` |
| function wait(memory, index, waitCondition, wakeCondition) { |
| while (memory[index] == waitCondition) { |
| var result = Atomics.wait(memory, index, waitCondition); |
| switch (result) { |
| case 'not-equal': |
| case 'ok': |
| break; |
| default: |
| postMessage('Error: bad result from wait: ' + result); |
| break; |
| } |
| var value = memory[index]; |
| if (value != wakeCondition) { |
| postMessage( |
| 'Error: wait returned not-equal but the memory has a bad value: ' + |
| value); |
| } |
| } |
| var value = memory[index]; |
| if (value != wakeCondition) { |
| postMessage( |
| 'Error: done waiting but the memory has a bad value: ' + value); |
| } |
| } |
| |
| function wake(memory, index) { |
| var result = Atomics.notify(memory, index, 1); |
| if (result != 0 && result != 1) { |
| postMessage('Error: bad result from wake: ' + result); |
| } |
| } |
| `; |
| |
| let worker1 = startWorker(shared + ` |
| onmessage = function(msg) { |
| let memory = msg; |
| const didStartIdx = 0; |
| const shouldGoIdx = 1; |
| const didEndIdx = 2; |
| |
| postMessage("started"); |
| postMessage("memory: " + memory); |
| wait(memory, didStartIdx, 0, 1); |
| memory[shouldGoIdx] = 1; |
| wake(memory, shouldGoIdx); |
| wait(memory, didEndIdx, 0, 1); |
| postMessage("memory: " + memory); |
| postMessage("done"); |
| }; |
| `); |
| |
| let worker2 = startWorker(shared + ` |
| onmessage = function(msg) { |
| let memory = msg; |
| const didStartIdx = 0; |
| const shouldGoIdx = 1; |
| const didEndIdx = 2; |
| |
| postMessage("started"); |
| postMessage("memory: " + memory); |
| Atomics.store(memory, didStartIdx, 1); |
| wake(memory, didStartIdx); |
| wait(memory, shouldGoIdx, 0, 1); |
| Atomics.store(memory, didEndIdx, 1); |
| wake(memory, didEndIdx, 1); |
| postMessage("memory: " + memory); |
| postMessage("done"); |
| }; |
| `); |
| |
| let running = true; |
| while (running) { |
| for (let worker of workers) { |
| if (worker.done) continue; |
| |
| let msg = worker.getMessage(); |
| if (msg) { |
| switch (msg) { |
| case "done": |
| if (worker.done === false) { |
| print("worker #" + worker.idx + " done."); |
| worker.done = true; |
| if (--runningWorkers === 0) { |
| running = false; |
| } |
| } |
| break; |
| |
| default: |
| print("msg from worker #" + worker.idx + ": " + msg); |
| break; |
| } |
| } |
| } |
| } |