Bug 1633625 - Extract out a load cycle manager r=jonco

Differential Revision: https://phabricator.services.mozilla.com/D73981
This commit is contained in:
Steve Fink 2020-05-08 16:44:58 +00:00
Родитель 72ce28c40f
Коммит 96e3f93514
2 изменённых файлов: 117 добавлений и 32 удалений

Просмотреть файл

@ -5,6 +5,7 @@
// Global defaults // Global defaults
var gDefaultGarbagePiles = "8M"; var gDefaultGarbagePiles = "8M";
var gDefaultGarbagePerFrame = "8K"; var gDefaultGarbagePerFrame = "8K";
var gDefaultTestDuration = 8.0;
function parse_units(v) { function parse_units(v) {
if (!v.length) { if (!v.length) {
@ -81,6 +82,47 @@ class AllocationLoad {
} }
} }
class LoadCycle {
constructor(tests_to_run, duration) {
this.queue = [...tests_to_run];
this.duration = duration;
this.idx = -1;
}
get current() {
return this.queue[this.idx];
}
start(now = performance.now()) {
this.idx = 0;
this.cycleStart = this.started = now;
}
tick(now = performance.now()) {
if (this.currentLoadElapsed(now) < this.duration) {
return;
}
this.idx++;
this.started = now;
if (this.idx >= this.queue.length) {
this.idx = -1;
}
}
done() {
return this.idx == -1;
}
cycleElapsed(now = performance.now()) {
return now - this.cycleStart;
}
currentLoadElapsed(now = performance.now()) {
return now - this.started;
}
}
class AllocationLoadManager { class AllocationLoadManager {
constructor(tests) { constructor(tests) {
this._loads = new Map(); this._loads = new Map();
@ -89,6 +131,17 @@ class AllocationLoadManager {
} }
this._active = undefined; this._active = undefined;
this._paused = false; this._paused = false;
this._eventsSinceLastTick = 0;
// Public API
this.cycle = null;
this.testDurationMS = gDefaultTestDuration * 1000;
// Constants
this.CYCLE_STARTED = 1;
this.CYCLE_STOPPED = 2;
this.LOAD_ENDED = 4;
this.LOAD_STARTED = 8;
} }
activeLoad() { activeLoad() {
@ -132,20 +185,58 @@ class AllocationLoadManager {
} }
} }
tick() { tick(now = performance.now()) {
this.lastActive = this._active;
let events = this._eventsSinceLastTick;
this._eventsSinceLastTick = 0;
if (this.cycle) {
const prev = this.cycle.current;
this.cycle.tick(now);
if (this.cycle.current != prev) {
if (this.cycle.current) {
this.setActiveLoadByName(this.cycle.current);
} else {
this.deactivateLoad();
}
events |= this.LOAD_ENDED;
if (this.cycle.done()) {
events |= this.CYCLE_STOPPED;
this.cycle = null;
} else {
events |= this.LOAD_STARTED;
}
}
}
if (this._active && !this._paused) { if (this._active && !this._paused) {
this._active.tick(); this._active.tick();
} }
return events;
}
startCycle(tests_to_run, now = performance.now()) {
this.cycle = new LoadCycle(tests_to_run, this.testDurationMS);
this.cycle.start(now);
this.setActiveLoadByName(this.cycle.current);
this._eventsSinceLastTick |= this.CYCLE_STARTED | this.LOAD_STARTED;
}
cycleStopped() {
return !this.cycle || this.cycle.done();
}
cycleCurrentLoadRemaining(now = performance.now()) {
return this.cycleStopped()
? 0
: this.testDurationMS - this.cycle.currentLoadElapsed(now);
} }
} }
// Current test state. // Current test state.
var gLoadMgr = undefined; var gLoadMgr = undefined;
var testDuration = undefined; // ms
var testStart = undefined; // ms
var testQueue = [];
function format_gcBytes(bytes) { function format_gcBytes(bytes) {
if (bytes < 4000) { if (bytes < 4000) {
return `${bytes} bytes`; return `${bytes} bytes`;
@ -171,7 +262,7 @@ function compute_test_score(histogram) {
for (let [delay, count] of histogram) { for (let [delay, count] of histogram) {
score += Math.abs((delay - 1000 / 60) * count); score += Math.abs((delay - 1000 / 60) * count);
} }
score = score / (testDuration / 1000); score = score / (gLoadMgr.testDurationMS / 1000);
return Math.round(score * 1000) / 1000; return Math.round(score * 1000) / 1000;
} }

Просмотреть файл

@ -431,17 +431,20 @@ function handler(timestamp) {
return; return;
} }
if (testState === "running" && timestamp - testStart > testDuration) { const events = gLoadMgr.tick(timestamp);
end_test(timestamp); if (events & gLoadMgr.LOAD_ENDED) {
end_test(timestamp, gLoadMgr.lastActive);
if (!gLoadMgr.cycleStopped()) {
start_test();
}
} }
if (testState == "running") { if (testState == "running") {
document.getElementById("test-progress").textContent = document.getElementById("test-progress").textContent =
((testDuration - (timestamp - testStart)) / 1000).toFixed(1) + " sec"; (gLoadMgr.cycleCurrentLoadRemaining(timestamp) / 1000).toFixed(1) +
" sec";
} }
gLoadMgr.tick();
const delay = gFrameTimer.on_frame_finished(timestamp); const delay = gFrameTimer.on_frame_finished(timestamp);
update_histogram(gHistogram, delay); update_histogram(gHistogram, delay);
@ -592,15 +595,9 @@ function run_all_tests() {
function start_test_cycle(tests_to_run) { function start_test_cycle(tests_to_run) {
// Convert from an iterable to an array for pop. // Convert from an iterable to an array for pop.
testQueue = []; gLoadMgr.startCycle(tests_to_run);
for (var key of tests_to_run) {
testQueue.push(key);
}
testState = "running"; testState = "running";
testStart = performance.now();
gHistogram.clear(); gHistogram.clear();
start_test(testQueue.shift());
reset_draw_state(); reset_draw_state();
} }
@ -615,24 +612,19 @@ function update_load_state_indicator() {
document.getElementById("load-running").textContent = loadState; document.getElementById("load-running").textContent = loadState;
} }
function start_test(testName) { function start_test() {
change_load(testName); console.log(`Running test: ${gLoadMgr.activeLoad().name}`);
console.log(`Running test: ${testName}`); document.getElementById("test-selection").value = gLoadMgr.activeLoad().name;
document.getElementById("test-selection").value = testName;
update_load_state_indicator(); update_load_state_indicator();
} }
function end_test(timestamp) { function end_test(timestamp, load) {
document.getElementById("test-progress").textContent = "(not running)"; document.getElementById("test-progress").textContent = "(not running)";
report_test_result(gLoadMgr.activeLoad(), gHistogram); report_test_result(load, gHistogram);
gHistogram.clear(); gHistogram.clear();
console.log(`Ending test ${gLoadMgr.activeLoad().name}`); console.log(`Ending test ${load.name}`);
if (testQueue.length) { if (gLoadMgr.cycleStopped()) {
start_test(testQueue.shift());
testStart = timestamp;
} else {
testState = "idle"; testState = "idle";
testStart = 0;
} }
reset_draw_state(); reset_draw_state();
} }
@ -699,8 +691,10 @@ function change_load(new_load_name) {
function duration_changed() { function duration_changed() {
var durationInput = document.getElementById("test-duration"); var durationInput = document.getElementById("test-duration");
testDuration = parseInt(durationInput.value) * 1000; gLoadMgr.testDurationMS = parseInt(durationInput.value) * 1000;
console.log(`Updated test duration to: ${testDuration / 1000} seconds`); console.log(
`Updated test duration to: ${gLoadMgr.testDurationMS / 1000} seconds`
);
} }
function onLoadChange() { function onLoadChange() {