06c77160b5
R=binji@chromium.org, franzih@chromium.org Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng Change-Id: Ib6db8ec0b9980399e53e4b39f5c10150ca72f555 Reviewed-on: https://chromium-review.googlesource.com/1033426 Commit-Queue: Ben Smith <binji@chromium.org> Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Ben Smith <binji@chromium.org> Cr-Commit-Position: refs/heads/master@{#52897}
119 lines
2.8 KiB
JavaScript
119 lines
2.8 KiB
JavaScript
// 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.
|
|
|
|
$262.agent = (function () {
|
|
|
|
var workers = [];
|
|
var i32a = null;
|
|
var pendingReports = [];
|
|
|
|
// Agents call Atomics.wait on this location to sleep.
|
|
var SLEEP_LOC = 0;
|
|
// 1 if the started worker is ready, 0 otherwise.
|
|
var START_LOC = 1;
|
|
// The number of workers that have received the broadcast.
|
|
var BROADCAST_LOC = 2;
|
|
// Each worker has a count of outstanding reports; worker N uses memory
|
|
// location [WORKER_REPORT_LOC + N].
|
|
var WORKER_REPORT_LOC = 3;
|
|
|
|
function workerScript(script) {
|
|
return `
|
|
var index;
|
|
var i32a = null;
|
|
var broadcasts = [];
|
|
var pendingReceiver = null;
|
|
|
|
function handleBroadcast() {
|
|
if (pendingReceiver && broadcasts.length > 0) {
|
|
pendingReceiver.apply(null, broadcasts.shift());
|
|
pendingReceiver = null;
|
|
}
|
|
};
|
|
|
|
var onmessage = function(msg) {
|
|
switch (msg.kind) {
|
|
case 'start':
|
|
i32a = msg.i32a;
|
|
index = msg.index;
|
|
(0, eval)(\`${script}\`);
|
|
break;
|
|
|
|
case 'broadcast':
|
|
Atomics.add(i32a, ${BROADCAST_LOC}, 1);
|
|
broadcasts.push([msg.sab, msg.id]);
|
|
handleBroadcast();
|
|
break;
|
|
}
|
|
};
|
|
|
|
var $262 = {
|
|
agent: {
|
|
receiveBroadcast(receiver) {
|
|
pendingReceiver = receiver;
|
|
handleBroadcast();
|
|
},
|
|
|
|
report(msg) {
|
|
postMessage(String(msg));
|
|
Atomics.add(i32a, ${WORKER_REPORT_LOC} + index, 1);
|
|
},
|
|
|
|
sleep(s) { Atomics.wait(i32a, ${SLEEP_LOC}, 0, s); },
|
|
|
|
leaving() {},
|
|
|
|
monotonicNow() {
|
|
return performance.now();
|
|
}
|
|
}
|
|
};`;
|
|
}
|
|
|
|
var agent = {
|
|
start(script) {
|
|
if (i32a === null) {
|
|
i32a = new Int32Array(new SharedArrayBuffer(256));
|
|
}
|
|
var w = new Worker(workerScript(script));
|
|
w.index = workers.length;
|
|
w.postMessage({kind: 'start', i32a: i32a, index: w.index});
|
|
workers.push(w);
|
|
},
|
|
|
|
broadcast(sab, id) {
|
|
if (!(sab instanceof SharedArrayBuffer)) {
|
|
throw new TypeError('sab must be a SharedArrayBuffer.');
|
|
}
|
|
|
|
Atomics.store(i32a, BROADCAST_LOC, 0);
|
|
|
|
for (var w of workers) {
|
|
w.postMessage({kind: 'broadcast', sab: sab, id: id|0});
|
|
}
|
|
|
|
while (Atomics.load(i32a, BROADCAST_LOC) != workers.length) {}
|
|
},
|
|
|
|
getReport() {
|
|
for (var w of workers) {
|
|
while (Atomics.load(i32a, WORKER_REPORT_LOC + w.index) > 0) {
|
|
pendingReports.push(w.getMessage());
|
|
Atomics.sub(i32a, WORKER_REPORT_LOC + w.index, 1);
|
|
}
|
|
}
|
|
|
|
return pendingReports.shift() || null;
|
|
},
|
|
|
|
sleep(s) { Atomics.wait(i32a, SLEEP_LOC, 0, s); },
|
|
|
|
monotonicNow() {
|
|
return performance.now();
|
|
}
|
|
};
|
|
return agent;
|
|
|
|
})();
|