505cccb9e9
Previously we only supported strings and not filenames. This changes the default to filename and adds a new `type: string` which can be passed `options` to allow for strings to be passed in test code. See: https://developer.mozilla.org/en-US/docs/Web/API/Worker/Worker Bug: v8:8020 Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng Change-Id: Ie8818885c5c5c071b6614852322cb45aeb01a647 Reviewed-on: https://chromium-review.googlesource.com/1185980 Commit-Queue: Sam Clegg <sbc@chromium.org> Reviewed-by: Ben Smith <binji@chromium.org> Cr-Commit-Position: refs/heads/master@{#56056}
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), {type: 'string'});
|
|
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;
|
|
|
|
})();
|