Commit 6f59a9ad authored by robliao's avatar robliao Committed by Commit bot

Plumb Task Scheduler Histograms to the Task Scheduler Internals Page

This sets up the plumbing to get data from the Task Scheduler to the
internals page. The first target are some selected histograms.

BUG=553459
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:closure_compilation

Review-Url: https://chromiumcodereview.appspot.com/2420973002
Cr-Commit-Position: refs/heads/master@{#426520}
parent 03623e23
...@@ -450,6 +450,12 @@ void SchedulerWorkerPoolImpl::PostTaskWithSequenceNow( ...@@ -450,6 +450,12 @@ void SchedulerWorkerPoolImpl::PostTaskWithSequenceNow(
} }
} }
void SchedulerWorkerPoolImpl::GetHistograms(
std::vector<const HistogramBase*>* histograms) const {
histograms->push_back(detach_duration_histogram_);
histograms->push_back(num_tasks_between_waits_histogram_);
}
SchedulerWorkerPoolImpl::SchedulerSingleThreadTaskRunner:: SchedulerWorkerPoolImpl::SchedulerSingleThreadTaskRunner::
SchedulerSingleThreadTaskRunner(const TaskTraits& traits, SchedulerSingleThreadTaskRunner(const TaskTraits& traits,
SchedulerWorkerPool* worker_pool, SchedulerWorkerPool* worker_pool,
......
...@@ -102,6 +102,8 @@ class BASE_EXPORT SchedulerWorkerPoolImpl : public SchedulerWorkerPool { ...@@ -102,6 +102,8 @@ class BASE_EXPORT SchedulerWorkerPoolImpl : public SchedulerWorkerPool {
return num_tasks_between_waits_histogram_; return num_tasks_between_waits_histogram_;
} }
void GetHistograms(std::vector<const HistogramBase*>* histograms) const;
private: private:
class SchedulerSingleThreadTaskRunner; class SchedulerSingleThreadTaskRunner;
class SchedulerWorkerDelegateImpl; class SchedulerWorkerDelegateImpl;
......
...@@ -20,6 +20,7 @@ class Location; ...@@ -20,6 +20,7 @@ class Location;
namespace base { namespace base {
class HistogramBase;
class SchedulerWorkerPoolParams; class SchedulerWorkerPoolParams;
// Interface for a task scheduler and static methods to manage the instance used // Interface for a task scheduler and static methods to manage the instance used
...@@ -48,6 +49,9 @@ class BASE_EXPORT TaskScheduler { ...@@ -48,6 +49,9 @@ class BASE_EXPORT TaskScheduler {
const TaskTraits& traits, const TaskTraits& traits,
ExecutionMode execution_mode) = 0; ExecutionMode execution_mode) = 0;
// Returns a vector of all histograms available in this task scheduler.
virtual std::vector<const HistogramBase*> GetHistograms() const = 0;
// Synchronously shuts down the scheduler. Once this is called, only tasks // Synchronously shuts down the scheduler. Once this is called, only tasks
// posted with the BLOCK_SHUTDOWN behavior will be run. When this returns: // posted with the BLOCK_SHUTDOWN behavior will be run. When this returns:
// - All SKIP_ON_SHUTDOWN tasks that were already running have completed their // - All SKIP_ON_SHUTDOWN tasks that were already running have completed their
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/metrics/histogram_base.h"
#include "base/task_scheduler/scheduler_worker_pool_params.h" #include "base/task_scheduler/scheduler_worker_pool_params.h"
#include "base/task_scheduler/sequence_sort_key.h" #include "base/task_scheduler/sequence_sort_key.h"
#include "base/task_scheduler/task.h" #include "base/task_scheduler/task.h"
...@@ -51,6 +52,14 @@ scoped_refptr<TaskRunner> TaskSchedulerImpl::CreateTaskRunnerWithTraits( ...@@ -51,6 +52,14 @@ scoped_refptr<TaskRunner> TaskSchedulerImpl::CreateTaskRunnerWithTraits(
traits, execution_mode); traits, execution_mode);
} }
std::vector<const HistogramBase*> TaskSchedulerImpl::GetHistograms() const {
std::vector<const HistogramBase*> histograms;
for (const auto& worker_pool : worker_pools_)
worker_pool->GetHistograms(&histograms);
return histograms;
}
void TaskSchedulerImpl::Shutdown() { void TaskSchedulerImpl::Shutdown() {
// TODO(fdoray): Increase the priority of BACKGROUND tasks blocking shutdown. // TODO(fdoray): Increase the priority of BACKGROUND tasks blocking shutdown.
task_tracker_.Shutdown(); task_tracker_.Shutdown();
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include <stddef.h> #include <stddef.h>
#include <memory> #include <memory>
#include <string>
#include <vector> #include <vector>
#include "base/base_export.h" #include "base/base_export.h"
...@@ -28,6 +27,7 @@ ...@@ -28,6 +27,7 @@
namespace base { namespace base {
class HistogramBase;
class SchedulerWorkerPoolParams; class SchedulerWorkerPoolParams;
namespace internal { namespace internal {
...@@ -58,6 +58,7 @@ class BASE_EXPORT TaskSchedulerImpl : public TaskScheduler { ...@@ -58,6 +58,7 @@ class BASE_EXPORT TaskSchedulerImpl : public TaskScheduler {
scoped_refptr<TaskRunner> CreateTaskRunnerWithTraits( scoped_refptr<TaskRunner> CreateTaskRunnerWithTraits(
const TaskTraits& traits, const TaskTraits& traits,
ExecutionMode execution_mode) override; ExecutionMode execution_mode) override;
std::vector<const HistogramBase*> GetHistograms() const override;
void Shutdown() override; void Shutdown() override;
void FlushForTesting() override; void FlushForTesting() override;
......
/* Copyright 2016 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
table {
border: 1px solid black;
border-collapse: collapse;
}
td,
th {
border: 1px solid black;
padding: 5px;
text-align: center;
}
...@@ -3,9 +3,16 @@ ...@@ -3,9 +3,16 @@
<head> <head>
<title>Task Scheduler Internals</title> <title>Task Scheduler Internals</title>
<link rel="stylesheet" href="chrome://resources/css/text_defaults.css"> <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
<link rel="stylesheet" href="index.css">
<script src="chrome://resources/js/util.js"></script>
<script src="index.js"></script>
</head> </head>
<body> <body>
<h1>Task Scheduler Internals</h1> <h1>Task Scheduler Internals</h1>
Status: $i18n{status} <div>Status: <span id="status"></span></div>
<div id="details" hidden>
<h2>Histograms</h2>
<div id="histogram-container"></div>
</div>
</body> </body>
</html> </html>
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var TaskSchedulerInternals = {};
/**
* Updates the histograms on the page.
* @param {Array<Object>} histograms Array of histogram objects.
*/
TaskSchedulerInternals.updateHistograms = function(histograms) {
var histogramContainer = $('histogram-container');
for (var i in histograms) {
var histogram = histograms[i];
var title = document.createElement('div');
title.textContent = histogram.name;
histogramContainer.appendChild(title);
if (histogram.buckets.length > 0) {
histogramContainer.appendChild(
TaskSchedulerInternals.createHistogramTable(histogram.buckets));
} else {
var unavailable = document.createElement('div');
unavailable.textContent = 'No Data Recorded';
histogramContainer.appendChild(unavailable);
}
}
};
/**
* Returns a table representation of the histogram buckets.
* @param {Object} buckets The histogram buckets.
* @return {Object} A table element representation of the histogram buckets.
*/
TaskSchedulerInternals.createHistogramTable = function(buckets) {
var table = document.createElement('table');
var headerRow = document.createElement('tr');
var dataRow = document.createElement('tr');
for (var i in buckets) {
var bucket = buckets[i];
var header = document.createElement('th');
header.textContent = bucket.min + '-' + bucket.max;
headerRow.appendChild(header);
var data = document.createElement('td');
data.textContent = bucket.count;
dataRow.appendChild(data);
}
table.appendChild(headerRow);
table.appendChild(dataRow);
return table;
};
/**
* Handles callback from onGetTaskSchedulerData.
* @param {Object} data Dictionary containing all task scheduler metrics.
*/
TaskSchedulerInternals.onGetTaskSchedulerData = function(data) {
$('status').textContent =
data.instantiated ? 'Instantiated' : 'Not Instantiated';
$('details').hidden = !data.instantiated;
if (!data.instantiated)
return;
TaskSchedulerInternals.updateHistograms(data.histograms);
};
document.addEventListener('DOMContentLoaded', function() {
chrome.send('getTaskSchedulerData');
});
...@@ -15,6 +15,12 @@ ...@@ -15,6 +15,12 @@
<include name="IDR_TASK_SCHEDULER_INTERNALS_RESOURCES_INDEX_HTML" <include name="IDR_TASK_SCHEDULER_INTERNALS_RESOURCES_INDEX_HTML"
file="index.html" file="index.html"
type="BINDATA" /> type="BINDATA" />
<include name="IDR_TASK_SCHEDULER_INTERNALS_RESOURCES_INDEX_CSS"
file="index.css"
type="BINDATA" />
<include name="IDR_TASK_SCHEDULER_INTERNALS_RESOURCES_INDEX_JS"
file="index.js"
type="BINDATA" />
</includes> </includes>
</release> </release>
</grit> </grit>
...@@ -4,22 +4,104 @@ ...@@ -4,22 +4,104 @@
#include "chrome/browser/ui/webui/task_scheduler_internals/task_scheduler_internals_ui.h" #include "chrome/browser/ui/webui/task_scheduler_internals/task_scheduler_internals_ui.h"
#include <utility>
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_base.h"
#include "base/metrics/histogram_samples.h"
#include "base/task_scheduler/task_scheduler.h" #include "base/task_scheduler/task_scheduler.h"
#include "base/values.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "chrome/grit/task_scheduler_internals_resources.h" #include "chrome/grit/task_scheduler_internals_resources.h"
#include "content/public/browser/web_ui_data_source.h" #include "content/public/browser/web_ui_data_source.h"
#include "content/public/browser/web_ui_message_handler.h"
namespace {
std::unique_ptr<base::Value> SnapshotHistogramToValue(
const base::HistogramBase* histogram) {
std::unique_ptr<base::ListValue> values =
base::MakeUnique<base::ListValue>();
std::unique_ptr<base::HistogramSamples> samples =
histogram->SnapshotSamples();
std::unique_ptr<base::SampleCountIterator> iterator = samples->Iterator();
while (!iterator->Done()) {
base::HistogramBase::Sample min;
base::HistogramBase::Sample max;
base::HistogramBase::Count count;
iterator->Get(&min, &max, &count);
std::unique_ptr<base::DictionaryValue> bucket =
base::MakeUnique<base::DictionaryValue>();
bucket->SetInteger("min", min);
bucket->SetInteger("max", max);
bucket->SetInteger("count", count);
values->Append(std::move(bucket));
iterator->Next();
}
return std::move(values);
}
class TaskSchedulerDataHandler : public content::WebUIMessageHandler {
public:
TaskSchedulerDataHandler() = default;
// content::WebUIMessageHandler:
void RegisterMessages() override {
web_ui()->RegisterMessageCallback(
"getTaskSchedulerData",
base::Bind(&TaskSchedulerDataHandler::GetTaskSchedulerData,
base::Unretained(this)));
}
private:
void GetTaskSchedulerData(const base::ListValue*) {
base::DictionaryValue data;
base::TaskScheduler* task_scheduler = base::TaskScheduler::GetInstance();
data.SetBoolean("instantiated", !!task_scheduler);
if (task_scheduler) {
std::unique_ptr<base::ListValue> histogram_value =
base::MakeUnique<base::ListValue>();
std::vector<const base::HistogramBase*> histograms =
task_scheduler->GetHistograms();
for (const base::HistogramBase* const histogram : histograms) {
std::unique_ptr<base::DictionaryValue> buckets =
base::MakeUnique<base::DictionaryValue>();
buckets->SetString("name", histogram->histogram_name());
buckets->Set("buckets", SnapshotHistogramToValue(histogram));
histogram_value->Append(std::move(buckets));
}
data.Set("histograms", std::move(histogram_value));
}
web_ui()->CallJavascriptFunctionUnsafe(
"TaskSchedulerInternals.onGetTaskSchedulerData", data);
}
DISALLOW_COPY_AND_ASSIGN(TaskSchedulerDataHandler);
};
} // namespace
TaskSchedulerInternalsUI::TaskSchedulerInternalsUI(content::WebUI* web_ui) TaskSchedulerInternalsUI::TaskSchedulerInternalsUI(content::WebUI* web_ui)
: content::WebUIController(web_ui) { : content::WebUIController(web_ui) {
web_ui->AddMessageHandler(new TaskSchedulerDataHandler());
content::WebUIDataSource* html_source = content::WebUIDataSource* html_source =
content::WebUIDataSource::Create( content::WebUIDataSource::Create(
chrome::kChromeUITaskSchedulerInternalsHost); chrome::kChromeUITaskSchedulerInternalsHost);
html_source->AddResourcePath(
html_source->AddString("status", base::TaskScheduler::GetInstance() "index.css", IDR_TASK_SCHEDULER_INTERNALS_RESOURCES_INDEX_CSS);
? "Instantiated" html_source->AddResourcePath(
: "Not Instantiated"); "index.js", IDR_TASK_SCHEDULER_INTERNALS_RESOURCES_INDEX_JS);
html_source->SetDefaultResource( html_source->SetDefaultResource(
IDR_TASK_SCHEDULER_INTERNALS_RESOURCES_INDEX_HTML); IDR_TASK_SCHEDULER_INTERNALS_RESOURCES_INDEX_HTML);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment