зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1633625 - Extract out a load cycle manager r=jonco
Differential Revision: https://phabricator.services.mozilla.com/D73981
This commit is contained in:
Родитель
72ce28c40f
Коммит
96e3f93514
|
@ -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() {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче