Commit 18daee42 authored by Oystein Eftevaag's avatar Oystein Eftevaag Committed by Commit Bot

Perfetto: Defer taskrunner creation to be on-demand

Also queue up any tasks posted to the Perfetto task-runner-wrapper
until the Chrome taskscheduler has been created.

R=eseckler@chromium.org
TBR=yusukes@chromium.org

Change-Id: Ie9a2dd26ee529add9ce86709eef5876edbd7de27
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1553670
Commit-Queue: oysteine <oysteine@chromium.org>
Reviewed-by: default avataroysteine <oysteine@chromium.org>
Reviewed-by: default avatarEric Seckler <eseckler@chromium.org>
Cr-Commit-Position: refs/heads/master@{#652655}
parent 01f1f6a9
......@@ -110,8 +110,9 @@ class ArcTracingDataSource : public tracing::ProducerClient::DataSourceBase {
ArcTracingDataSource()
: DataSourceBase(tracing::mojom::kArcTraceDataSourceName),
perfetto_task_runner_(
tracing::ProducerClient::Get()->GetTaskRunner()->task_runner()) {
perfetto_task_runner_(tracing::ProducerClient::Get()
->GetTaskRunner()
->GetOrCreateTaskRunner()) {
tracing::ProducerClient::Get()->AddDataSource(this);
}
......@@ -258,7 +259,7 @@ class ArcTracingDataSource : public tracing::ProducerClient::DataSourceBase {
return true;
}
base::SequencedTaskRunner* perfetto_task_runner_;
scoped_refptr<base::SequencedTaskRunner> perfetto_task_runner_;
std::set<ArcTracingBridge*> bridges_;
// In case StopTracing() is called before tracing was started for all bridges,
// this stores a callback to StopTracing() that's executed when all bridges
......
......@@ -200,7 +200,7 @@ class CrOSDataSource : public tracing::ProducerClient::DataSourceBase {
session_started_ = false;
producer_client_ = nullptr;
producer_client->GetTaskRunner()->task_runner()->PostTask(
producer_client->GetTaskRunner()->GetOrCreateTaskRunner()->PostTask(
FROM_HERE, std::move(stop_complete_callback));
}
......
......@@ -77,8 +77,10 @@ class ThreadedPerfettoService : public mojom::TracingSession {
{
base::RunLoop wait_for_destruction;
ProducerClient::GetTaskRunner()->task_runner()->PostTaskAndReply(
FROM_HERE, base::DoNothing(), wait_for_destruction.QuitClosure());
ProducerClient::GetTaskRunner()
->GetOrCreateTaskRunner()
->PostTaskAndReply(FROM_HERE, base::DoNothing(),
wait_for_destruction.QuitClosure());
wait_for_destruction.Run();
}
}
......
......@@ -179,7 +179,7 @@ TEST_F(PerfettoIntegrationTest, CommitDataRequestIsMaybeComplete) {
client_enabled_callback.Run();
base::RunLoop wait_for_packet_write;
client->GetTaskRunner()->task_runner()->PostTaskAndReply(
client->GetTaskRunner()->GetOrCreateTaskRunner()->PostTaskAndReply(
FROM_HERE,
base::BindOnce(&TestDataSource::WritePacketBigly,
base::Unretained(client->data_source())),
......
......@@ -267,7 +267,7 @@ MockProducer::~MockProducer() {
}
void MockProducer::WritePacketBigly(base::OnceClosure on_write_complete) {
producer_client_->GetTaskRunner()->task_runner()->PostTaskAndReply(
producer_client_->GetTaskRunner()->GetOrCreateTaskRunner()->PostTaskAndReply(
FROM_HERE,
base::BindOnce(&TestDataSource::WritePacketBigly,
base::Unretained(producer_client_->data_source())),
......
......@@ -19,15 +19,6 @@
namespace tracing {
namespace {
scoped_refptr<base::SequencedTaskRunner> CreateTaskRunner() {
return base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::USER_BLOCKING});
}
} // namespace
ScopedPerfettoPostTaskBlocker::ScopedPerfettoPostTaskBlocker(bool enable)
: enabled_(enable) {
if (enabled_) {
......@@ -75,8 +66,8 @@ ProducerClient::~ProducerClient() {
// static
void ProducerClient::DeleteSoonForTesting(
std::unique_ptr<ProducerClient> producer_client) {
GetTaskRunner()->task_runner()->DeleteSoon(FROM_HERE,
std::move(producer_client));
GetTaskRunner()->GetOrCreateTaskRunner()->DeleteSoon(
FROM_HERE, std::move(producer_client));
}
// We never destroy the taskrunner as we may need it for cleanup
......@@ -84,14 +75,14 @@ void ProducerClient::DeleteSoonForTesting(
// is deleted.
// static
PerfettoTaskRunner* ProducerClient::GetTaskRunner() {
static base::NoDestructor<PerfettoTaskRunner> task_runner(CreateTaskRunner());
static base::NoDestructor<PerfettoTaskRunner> task_runner(nullptr);
return task_runner.get();
}
// static
void ProducerClient::ResetTaskRunnerForTesting() {
DETACH_FROM_SEQUENCE(ProducerClient::Get()->sequence_checker_);
GetTaskRunner()->ResetTaskRunnerForTesting(CreateTaskRunner());
GetTaskRunner()->ResetTaskRunnerForTesting(nullptr);
}
void ProducerClient::Connect(mojom::PerfettoServicePtr perfetto_service) {
......@@ -110,7 +101,7 @@ void ProducerClient::CreateMojoMessagepipes(
auto origin_task_runner = base::SequencedTaskRunnerHandle::Get();
DCHECK(origin_task_runner);
mojom::ProducerClientPtr producer_client;
GetTaskRunner()->task_runner()->PostTask(
GetTaskRunner()->GetOrCreateTaskRunner()->PostTask(
FROM_HERE,
base::BindOnce(&ProducerClient::CreateMojoMessagepipesOnSequence,
base::Unretained(this), origin_task_runner,
......@@ -160,7 +151,7 @@ void ProducerClient::CreateMojoMessagepipesOnSequence(
}
void ProducerClient::AddDataSource(DataSourceBase* data_source) {
GetTaskRunner()->task_runner()->PostTask(
GetTaskRunner()->GetOrCreateTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(&ProducerClient::AddDataSourceOnSequence,
base::Unretained(this), data_source));
}
......
......@@ -8,6 +8,8 @@
#include <utility>
#include "base/bind.h"
#include "base/task/post_task.h"
#include "base/task/thread_pool/thread_pool.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread_local_storage.h"
......@@ -27,20 +29,21 @@ void PerfettoTaskRunner::PostTask(std::function<void()> task) {
// sequence as we're now posting a new task from.
{
base::AutoLock lock(lock_);
if (posttask_is_blocked_for_thread_.Get()) {
if (!base::ThreadPool::GetInstance() ||
posttask_is_blocked_for_thread_.Get()) {
deferred_tasks_.emplace_back(std::move(task));
return;
}
while (!deferred_tasks_.empty()) {
task_runner_->PostTask(
GetOrCreateTaskRunner()->PostTask(
FROM_HERE, base::BindOnce([](std::function<void()> task) { task(); },
deferred_tasks_.front()));
deferred_tasks_.pop_front();
}
}
task_runner_->PostTask(
GetOrCreateTaskRunner()->PostTask(
FROM_HERE,
base::BindOnce([](std::function<void()> task) { task(); }, task));
}
......@@ -56,13 +59,14 @@ void PerfettoTaskRunner::PostDelayedTask(std::function<void()> task,
// side, where PostTask sometimes requires blocking. If this DCHECK ever
// triggers, support for deferring delayed tasks need to be added.
DCHECK(!posttask_is_blocked_for_thread_.Get());
task_runner_->PostDelayedTask(
GetOrCreateTaskRunner()->PostDelayedTask(
FROM_HERE,
base::BindOnce([](std::function<void()> task) { task(); }, task),
base::TimeDelta::FromMilliseconds(delay_ms));
}
bool PerfettoTaskRunner::RunsTasksOnCurrentThread() const {
DCHECK(task_runner_);
return task_runner_->RunsTasksInCurrentSequence();
}
......@@ -119,4 +123,15 @@ void PerfettoTaskRunner::OnDeferredTasksDrainTimer() {
}
}
scoped_refptr<base::SequencedTaskRunner>
PerfettoTaskRunner::GetOrCreateTaskRunner() {
if (!task_runner_) {
DCHECK(base::ThreadPool::GetInstance());
task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::USER_BLOCKING});
}
return task_runner_;
}
} // namespace tracing
......@@ -37,11 +37,12 @@ class COMPONENT_EXPORT(TRACING_CPP) PerfettoTaskRunner
// use case.
bool RunsTasksOnCurrentThread() const override;
scoped_refptr<base::SequencedTaskRunner> GetOrCreateTaskRunner();
// Not used in Chrome.
void AddFileDescriptorWatch(int fd, std::function<void()>) override;
void RemoveFileDescriptorWatch(int fd) override;
base::SequencedTaskRunner* task_runner() { return task_runner_.get(); }
// Tests will shut down all task runners in between runs, so we need
// to re-create any static instances on each SetUp();
......
......@@ -165,7 +165,7 @@ TEST_F(PerfettoTaskRunnerTest, SequentialDeferredTasksByTimer) {
// Start the timer which eventually will tick and post the previously
// deferred tasks. Note that this is posted directly to the taskqueue
// rather than the Perfetto wrapper, so it won't be deferred.
task_runner()->task_runner()->PostTask(
task_runner()->GetOrCreateTaskRunner()->PostTask(
FROM_HERE,
base::BindOnce(&PerfettoTaskRunner::StartDeferredTasksDrainTimer,
base::Unretained(task_runner())));
......
......@@ -528,7 +528,7 @@ void TraceEventDataSource::ReturnTraceWriter(
// shutdown and we can't safely call TaskRunnerHandle::Get() at that point
// (which can happen as the TraceWriter destructor might make a Mojo call
// and trigger it).
ProducerClient::GetTaskRunner()->task_runner()->DeleteSoon(
ProducerClient::GetTaskRunner()->GetOrCreateTaskRunner()->DeleteSoon(
FROM_HERE, std::move(trace_writer));
}
}
......
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