73d56f3c1a
The test was taking more than a minute before CL https://crrev.com/c/2259933. Afterwards, it takes a lot longer, but I could never reproduce a hang locally. Let's re-enable and mark SLOW to increase the chance that it runs to completion. We can then see how much slower it really got. Also add some output that helps triaging in case it really hangs. R=ahaas@chromium.org Bug: v8:9506 Change-Id: I09a935ca0018517d45c6c008a099b8052bc45c47 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2273117 Commit-Queue: Clemens Backes <clemensb@chromium.org> Reviewed-by: Andreas Haas <ahaas@chromium.org> Cr-Commit-Position: refs/heads/master@{#68582}
129 lines
4.0 KiB
JavaScript
129 lines
4.0 KiB
JavaScript
// Copyright 2019 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.
|
|
|
|
// A test utility for pinging objects back and forth among a pool of workers.
|
|
// Use by calling {RunWorkerPingTest} with a {config} object.
|
|
{
|
|
// Reference config object for demonstrating the interface.
|
|
let config = {
|
|
numThings: 4, // size of circular buffer
|
|
numWorkers: 4, // number of workers
|
|
numMessages: 100, // number of messages sent to each worker
|
|
allocInterval: 11, // interval for allocating new things per worker
|
|
traceScript: false, // print the script
|
|
traceAlloc: false, // print each allocation attempt
|
|
traceIteration: 10, // print diagnostics every so many iterations
|
|
abortOnFail: false, // kill worker if allocation fails
|
|
|
|
// Note that because the functions are appended to a worker script
|
|
// *as source*, they need to be named properly.
|
|
|
|
// The function that allocates things. Required.
|
|
AllocThing: function AllocThing(id) {
|
|
return new Array(2);
|
|
},
|
|
// Before message send behavior. Optional.
|
|
BeforeSend: function BeforeSend(msg) { },
|
|
// Before message reception behavior. Optional.
|
|
BeforeReceive: function BeforeReceive(msg) { },
|
|
}
|
|
}
|
|
|
|
function RunWorkerPingTest(config) {
|
|
let workers = [];
|
|
let beforeSend = (typeof config.BeforeSend == "function") ?
|
|
config.BeforeSend :
|
|
function BeforeSend(msg) { };
|
|
let beforeReceive = (typeof config.BeforeReceive == "function") ?
|
|
config.BeforeReceive :
|
|
function BeforeReceive(msg) { };
|
|
|
|
// Each worker has a circular buffer of size {config.numThings}, recording
|
|
// received things into the buffer and responding with a previous thing.
|
|
// Every {config.allocInterval}, a worker creates a new thing by
|
|
// {config.AllocThing}.
|
|
|
|
let script =
|
|
`const kNumThings = ${config.numThings};
|
|
const kAllocInterval = ${config.allocInterval};
|
|
let index = 0;
|
|
let total = 0;
|
|
let id = 0;
|
|
let things = new Array(kNumThings);
|
|
for (let i = 0; i < kNumThings; i++) {
|
|
things[i] = TryAllocThing();
|
|
}
|
|
|
|
function TryAllocThing() {
|
|
try {
|
|
let thing = AllocThing(id++);
|
|
${config.traceAlloc ? "print(\"alloc success\");" : ""}
|
|
return thing;
|
|
} catch(e) {
|
|
${config.abortOnFail ? "postMessage({error: e.toString()}); throw e;" : "" }
|
|
${config.traceAlloc ? "print(\"alloc fail: \" + e);" : ""}
|
|
}
|
|
}
|
|
|
|
onmessage = function(msg) {
|
|
BeforeReceive(msg);
|
|
if (msg.thing !== undefined) {
|
|
let reply = things[index];
|
|
if ((total % kAllocInterval) == 0) {
|
|
reply = TryAllocThing();
|
|
}
|
|
things[index] = msg.thing;
|
|
postMessage({thing : reply});
|
|
index = (index + 1) % kNumThings;
|
|
total++;
|
|
}
|
|
}
|
|
${config.AllocThing.toString()}
|
|
${beforeReceive.toString()}
|
|
`;
|
|
|
|
if (config.traceScript) {
|
|
print("========== Worker script ==========");
|
|
print(script);
|
|
print("===================================");
|
|
}
|
|
|
|
for (let i = 0; i < config.numWorkers; i++) {
|
|
let worker = new Worker(script, {type : 'string'});
|
|
workers.push(worker);
|
|
}
|
|
|
|
let time = performance.now();
|
|
|
|
// The main thread posts {config.numMessages} messages to {config.numWorkers}
|
|
// workers, with each message containing a "thing" created by {config.AllocThing}.
|
|
let thing = config.AllocThing(-1);
|
|
for (let i = 0; i < config.numMessages; i++) {
|
|
if ((i % config.traceIteration) == 0) {
|
|
let now = performance.now();
|
|
print(`iteration ${i}, Δ = ${(now - time).toFixed(3)} ms`);
|
|
time = now;
|
|
}
|
|
|
|
for (let worker of workers) {
|
|
let msg = {thing: thing};
|
|
beforeSend(msg);
|
|
worker.postMessage(msg);
|
|
msg = worker.getMessage();
|
|
if (msg.thing) {
|
|
thing = msg.thing;
|
|
} else if (msg.error) {
|
|
print('Error in worker:', msg.error);
|
|
worker.terminate();
|
|
throw msg.error;
|
|
}
|
|
}
|
|
}
|
|
print('Terminating workers.');
|
|
for (let worker of workers) {
|
|
worker.terminate();
|
|
}
|
|
print('Workers terminated.');
|
|
}
|