Commit 819799e2 authored by skyostil's avatar skyostil Committed by Commit bot

scheduler: Turn expensive task blocking into a finch trial

Turn expensive task blocking into a feature (finch trial) which is
disabled by default.

BUG=574343

Review URL: https://codereview.chromium.org/1587663003

Cr-Commit-Position: refs/heads/master@{#369398}
parent 9b7480c0
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "components/scheduler/renderer/renderer_scheduler.h" #include "components/scheduler/renderer/renderer_scheduler.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/feature_list.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/time/default_tick_clock.h" #include "base/time/default_tick_clock.h"
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
...@@ -15,6 +16,10 @@ ...@@ -15,6 +16,10 @@
#include "components/scheduler/renderer/renderer_scheduler_impl.h" #include "components/scheduler/renderer/renderer_scheduler_impl.h"
namespace scheduler { namespace scheduler {
namespace {
const base::Feature kExpensiveTaskBlockingPolicyFeature{
"SchedulerExpensiveTaskBlocking", base::FEATURE_DISABLED_BY_DEFAULT};
}
RendererScheduler::RendererScheduler() { RendererScheduler::RendererScheduler() {
} }
...@@ -33,16 +38,23 @@ scoped_ptr<RendererScheduler> RendererScheduler::Create() { ...@@ -33,16 +38,23 @@ scoped_ptr<RendererScheduler> RendererScheduler::Create() {
base::trace_event::TraceLog::GetCategoryGroupEnabled( base::trace_event::TraceLog::GetCategoryGroupEnabled(
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")); TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug"));
scoped_ptr<RendererSchedulerImpl> scheduler;
base::MessageLoop* message_loop = base::MessageLoop::current(); base::MessageLoop* message_loop = base::MessageLoop::current();
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kEnableVirtualizedTime)) { if (command_line->HasSwitch(switches::kEnableVirtualizedTime)) {
return make_scoped_ptr(new RendererSchedulerImpl( scheduler.reset(new RendererSchedulerImpl(
VirtualTimeTqmDelegate::Create(message_loop, base::TimeTicks::Now()))); VirtualTimeTqmDelegate::Create(message_loop, base::TimeTicks::Now())));
} else { } else {
return make_scoped_ptr( scheduler.reset(new RendererSchedulerImpl(SchedulerTqmDelegateImpl::Create(
new RendererSchedulerImpl(SchedulerTqmDelegateImpl::Create( message_loop, make_scoped_ptr(new base::DefaultTickClock()))));
message_loop, make_scoped_ptr(new base::DefaultTickClock())))); }
// Runtime features are not currently available in html_viewer.
if (base::FeatureList::GetInstance()) {
scheduler->SetExpensiveTaskBlockingAllowed(
base::FeatureList::IsEnabled(kExpensiveTaskBlockingPolicyFeature));
} }
return make_scoped_ptr<RendererScheduler>(scheduler.release());
} }
// static // static
......
...@@ -127,7 +127,8 @@ RendererSchedulerImpl::MainThreadOnly::MainThreadOnly( ...@@ -127,7 +127,8 @@ RendererSchedulerImpl::MainThreadOnly::MainThreadOnly(
touchstart_expected_soon(false), touchstart_expected_soon(false),
have_seen_a_begin_main_frame(false), have_seen_a_begin_main_frame(false),
has_visible_render_widget_with_touch_handler(false), has_visible_render_widget_with_touch_handler(false),
begin_frame_not_expected_soon(false) {} begin_frame_not_expected_soon(false),
expensive_task_blocking_allowed(true) {}
RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {} RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {}
...@@ -718,6 +719,11 @@ void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) { ...@@ -718,6 +719,11 @@ void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) {
NOTREACHED(); NOTREACHED();
} }
if (!MainThreadOnly().expensive_task_blocking_allowed) {
block_expensive_loading_tasks = false;
block_expensive_timer_tasks = false;
}
// Don't block expensive tasks unless we have actually seen something. // Don't block expensive tasks unless we have actually seen something.
if (!MainThreadOnly().have_seen_a_begin_main_frame) { if (!MainThreadOnly().have_seen_a_begin_main_frame) {
block_expensive_loading_tasks = false; block_expensive_loading_tasks = false;
...@@ -1083,6 +1089,10 @@ void RendererSchedulerImpl::UnregisterTimeDomain(TimeDomain* time_domain) { ...@@ -1083,6 +1089,10 @@ void RendererSchedulerImpl::UnregisterTimeDomain(TimeDomain* time_domain) {
helper_.UnregisterTimeDomain(time_domain); helper_.UnregisterTimeDomain(time_domain);
} }
void RendererSchedulerImpl::SetExpensiveTaskBlockingAllowed(bool allowed) {
MainThreadOnly().expensive_task_blocking_allowed = allowed;
}
base::TickClock* RendererSchedulerImpl::tick_clock() const { base::TickClock* RendererSchedulerImpl::tick_clock() const {
return helper_.scheduler_tqm_delegate().get(); return helper_.scheduler_tqm_delegate().get();
} }
......
...@@ -91,6 +91,8 @@ class SCHEDULER_EXPORT RendererSchedulerImpl ...@@ -91,6 +91,8 @@ class SCHEDULER_EXPORT RendererSchedulerImpl
void RegisterTimeDomain(TimeDomain* time_domain); void RegisterTimeDomain(TimeDomain* time_domain);
void UnregisterTimeDomain(TimeDomain* time_domain); void UnregisterTimeDomain(TimeDomain* time_domain);
void SetExpensiveTaskBlockingAllowed(bool allowed);
// Test helpers. // Test helpers.
SchedulerHelper* GetSchedulerHelperForTesting(); SchedulerHelper* GetSchedulerHelperForTesting();
TaskCostEstimator* GetLoadingTaskCostEstimatorForTesting(); TaskCostEstimator* GetLoadingTaskCostEstimatorForTesting();
...@@ -295,6 +297,7 @@ class SCHEDULER_EXPORT RendererSchedulerImpl ...@@ -295,6 +297,7 @@ class SCHEDULER_EXPORT RendererSchedulerImpl
bool have_seen_a_begin_main_frame; bool have_seen_a_begin_main_frame;
bool has_visible_render_widget_with_touch_handler; bool has_visible_render_widget_with_touch_handler;
bool begin_frame_not_expected_soon; bool begin_frame_not_expected_soon;
bool expensive_task_blocking_allowed;
}; };
struct AnyThread { struct AnyThread {
......
...@@ -2231,6 +2231,32 @@ TEST_F(RendererSchedulerImplTest, ExpensiveTimerTaskBlocked) { ...@@ -2231,6 +2231,32 @@ TEST_F(RendererSchedulerImplTest, ExpensiveTimerTaskBlocked) {
EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1"))); EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1")));
} }
TEST_F(RendererSchedulerImplTest, ExpensiveTimerTaskNotBlockedIfDisallowed) {
std::vector<std::string> run_order;
EnableTaskBlocking();
scheduler_->SetExpensiveTaskBlockingAllowed(false);
scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
DoMainFrame();
SimulateExpensiveTasks(timer_task_runner_);
ForceTouchStartToBeExpectedSoon();
scheduler_->DidHandleInputEventOnCompositorThread(
FakeInputEvent(blink::WebInputEvent::GestureFlingStart),
RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
PostTestTasks(&run_order, "T1 D1");
RunUntilIdle();
EXPECT_EQ(UseCase::MAIN_THREAD_GESTURE,
ForceUpdatePolicyAndGetCurrentUseCase());
EXPECT_TRUE(HaveSeenABeginMainframe());
EXPECT_FALSE(LoadingTasksSeemExpensive());
EXPECT_TRUE(TimerTasksSeemExpensive());
EXPECT_TRUE(TouchStartExpectedSoon());
EXPECT_THAT(run_order, testing::ElementsAre(std::string("T1"),
std::string("D1")));
}
TEST_F(RendererSchedulerImplTest, TEST_F(RendererSchedulerImplTest,
ExpensiveTimerTaskBlockedIfTouchStartNotSeen) { ExpensiveTimerTaskBlockedIfTouchStartNotSeen) {
std::vector<std::string> run_order; std::vector<std::string> run_order;
......
...@@ -154,8 +154,6 @@ int RendererMain(const MainFunctionParams& parameters) { ...@@ -154,8 +154,6 @@ int RendererMain(const MainFunctionParams& parameters) {
#endif #endif
base::PlatformThread::SetName("CrRendererMain"); base::PlatformThread::SetName("CrRendererMain");
scoped_ptr<scheduler::RendererScheduler> renderer_scheduler(
scheduler::RendererScheduler::Create());
bool no_sandbox = parsed_command_line.HasSwitch(switches::kNoSandbox); bool no_sandbox = parsed_command_line.HasSwitch(switches::kNoSandbox);
...@@ -186,6 +184,9 @@ int RendererMain(const MainFunctionParams& parameters) { ...@@ -186,6 +184,9 @@ int RendererMain(const MainFunctionParams& parameters) {
parsed_command_line.GetSwitchValueASCII(switches::kDisableFeatures)); parsed_command_line.GetSwitchValueASCII(switches::kDisableFeatures));
base::FeatureList::SetInstance(std::move(feature_list)); base::FeatureList::SetInstance(std::move(feature_list));
scoped_ptr<scheduler::RendererScheduler> renderer_scheduler(
scheduler::RendererScheduler::Create());
// PlatformInitialize uses FieldTrials, so this must happen later. // PlatformInitialize uses FieldTrials, so this must happen later.
platform.PlatformInitialize(); platform.PlatformInitialize();
......
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