Commit 66fbaed9 authored by Carlos Caballero's avatar Carlos Caballero Committed by Commit Bot

Feature to run Blink main thread using SequenceManager

This will enable us to start trialing the MessageLoop replacement by
SequenceManager.

We only do this in the Blink main thread for now. There is some work
needed around SequenceManager ownership to be done before this can be
enabled in worker threads.


Bug: 891670
Change-Id: I1e59784ff35c87883a66d9b315435bf47cd0f809
Reviewed-on: https://chromium-review.googlesource.com/c/1349316Reviewed-by: default avatarAlex Clarke <alexclarke@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Reviewed-by: default avatarSami Kyöstilä <skyostil@chromium.org>
Commit-Queue: Carlos Caballero <carlscab@google.com>
Cr-Commit-Position: refs/heads/master@{#612185}
parent 769b9087
......@@ -172,9 +172,13 @@ class SequenceManager {
BASE_EXPORT std::unique_ptr<SequenceManager>
CreateSequenceManagerOnCurrentThread();
// Create a SequenceManager for a MessagePump on the current thread.
// Create a SequenceManager using the given MessagePump on the current thread.
// MessagePump instances can be created with
// MessageLoop::CreateMessagePumpForType().
BASE_EXPORT std::unique_ptr<SequenceManager>
CreateSequenceManagerOnCurrentThreadWithPump(MessageLoop::Type type);
CreateSequenceManagerOnCurrentThreadWithPump(
MessageLoop::Type type,
std::unique_ptr<MessagePump> message_pump);
// Create a SequenceManager for a future thread using the provided MessageLoop.
// The SequenceManager can be initialized on the current thread and then needs
......
......@@ -41,11 +41,11 @@ std::unique_ptr<SequenceManager> CreateSequenceManagerOnCurrentThread() {
}
std::unique_ptr<SequenceManager> CreateSequenceManagerOnCurrentThreadWithPump(
MessageLoop::Type type) {
MessageLoop::Type type,
std::unique_ptr<MessagePump> message_pump) {
std::unique_ptr<SequenceManager> sequence_manager =
internal::SequenceManagerImpl::CreateUnboundWithPump(type);
sequence_manager->BindToMessagePump(
MessageLoop::CreateMessagePumpForType(type));
sequence_manager->BindToMessagePump(std::move(message_pump));
return sequence_manager;
}
......
......@@ -37,24 +37,32 @@ namespace {
LazyInstance<ThreadLocalPointer<ScopedTaskEnvironment::LifetimeObserver>>::Leaky
environment_lifetime_observer;
std::unique_ptr<sequence_manager::SequenceManager>
CreateSequenceManagerForMainThreadType(
base::Optional<MessageLoop::Type> GetMessageLoopTypeForMainThreadType(
ScopedTaskEnvironment::MainThreadType main_thread_type) {
switch (main_thread_type) {
case ScopedTaskEnvironment::MainThreadType::DEFAULT:
case ScopedTaskEnvironment::MainThreadType::MOCK_TIME:
return sequence_manager::CreateSequenceManagerOnCurrentThreadWithPump(
MessageLoop::TYPE_DEFAULT);
return MessageLoop::TYPE_DEFAULT;
case ScopedTaskEnvironment::MainThreadType::UI:
case ScopedTaskEnvironment::MainThreadType::UI_MOCK_TIME:
return sequence_manager::CreateSequenceManagerOnCurrentThreadWithPump(
MessageLoop::TYPE_UI);
return MessageLoop::TYPE_UI;
case ScopedTaskEnvironment::MainThreadType::IO:
return sequence_manager::CreateSequenceManagerOnCurrentThreadWithPump(
MessageLoop::TYPE_IO);
return MessageLoop::TYPE_IO;
}
NOTREACHED();
return base::nullopt;
}
std::unique_ptr<sequence_manager::SequenceManager>
CreateSequenceManagerForMainThreadType(
ScopedTaskEnvironment::MainThreadType main_thread_type) {
auto type = GetMessageLoopTypeForMainThreadType(main_thread_type);
if (!type) {
return nullptr;
} else {
return sequence_manager::CreateSequenceManagerOnCurrentThreadWithPump(
*type, MessageLoop::CreateMessagePumpForType(*type));
}
}
} // namespace
......
......@@ -9,6 +9,7 @@
#include "base/command_line.h"
#include "base/debug/debugger.h"
#include "base/debug/leak_annotations.h"
#include "base/feature_list.h"
#include "base/i18n/rtl.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram_macros.h"
......@@ -18,6 +19,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/system/sys_info.h"
#include "base/task/sequence_manager/sequence_manager.h"
#include "base/threading/platform_thread.h"
#include "base/timer/hi_res_timer_manager.h"
#include "base/trace_event/trace_event.h"
......@@ -59,6 +61,10 @@
namespace content {
namespace {
const base::Feature kMainThreadUsesSequenceManager{
"BlinkMainThreadUsesSequenceManager", base::FEATURE_DISABLED_BY_DEFAULT};
// This function provides some ways to test crash and assertion handling
// behavior of the renderer.
static void HandleRendererErrorTestParameters(
......@@ -70,6 +76,18 @@ static void HandleRendererErrorTestParameters(
WaitForDebugger("Renderer");
}
std::unique_ptr<base::MessagePump> CreateMainThreadMessagePump() {
#if defined(OS_MACOSX)
// As long as scrollbars on Mac are painted with Cocoa, the message pump
// needs to be backed by a Foundation-level loop to process NSTimers. See
// http://crbug.com/306348#c24 for details.
return std::make_unique<base::MessagePumpNSRunLoop>();
#else
return base::MessageLoop::CreateMessagePumpForType(
base::MessageLoop::TYPE_DEFAULT);
#endif
}
} // namespace
// mainline routine for running as the Renderer process
......@@ -121,17 +139,6 @@ int RendererMain(const MainFunctionParams& parameters) {
HandleRendererErrorTestParameters(command_line);
RendererMainPlatformDelegate platform(parameters);
#if defined(OS_MACOSX)
// As long as scrollbars on Mac are painted with Cocoa, the message pump
// needs to be backed by a Foundation-level loop to process NSTimers. See
// http://crbug.com/306348#c24 for details.
std::unique_ptr<base::MessagePump> pump(new base::MessagePumpNSRunLoop());
std::unique_ptr<base::MessageLoop> main_message_loop(
new base::MessageLoop(std::move(pump)));
#else
// The main message loop of the renderer services doesn't have IO or UI tasks.
std::unique_ptr<base::MessageLoop> main_message_loop(new base::MessageLoop());
#endif
base::PlatformThread::SetName("CrRendererMain");
......@@ -149,9 +156,20 @@ int RendererMain(const MainFunctionParams& parameters) {
initial_virtual_time = base::Time::FromDoubleT(initial_time);
}
}
std::unique_ptr<blink::scheduler::WebThreadScheduler> main_thread_scheduler(
std::unique_ptr<base::MessageLoop> main_message_loop;
std::unique_ptr<blink::scheduler::WebThreadScheduler> main_thread_scheduler;
if (!base::FeatureList::IsEnabled(kMainThreadUsesSequenceManager)) {
main_message_loop =
std::make_unique<base::MessageLoop>(CreateMainThreadMessagePump());
main_thread_scheduler =
blink::scheduler::WebThreadScheduler::CreateMainThreadScheduler(
initial_virtual_time));
/*message_pump=*/nullptr, initial_virtual_time);
} else {
main_thread_scheduler =
blink::scheduler::WebThreadScheduler::CreateMainThreadScheduler(
CreateMainThreadMessagePump(), initial_virtual_time);
}
platform.PlatformInitialize();
......
......@@ -6,6 +6,7 @@ include_rules = [
"+base/memory/ptr_util.h",
"+base/memory/ref_counted.h",
"+base/message_loop/message_loop.h",
"+base/message_loop/message_pump.h",
"+base/optional.h",
"+base/single_thread_task_runner.h",
"+base/threading/thread.h",
......
......@@ -7,6 +7,7 @@
#include <memory>
#include "base/macros.h"
#include "base/message_loop/message_pump.h"
#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "base/time/time.h"
......@@ -21,7 +22,7 @@
namespace base {
namespace trace_event {
class BlameContext;
}
} // namespace trace_event
} // namespace base
namespace blink {
......@@ -31,7 +32,7 @@ class WebInputEvent;
namespace viz {
struct BeginFrameArgs;
}
} // namespace viz
namespace blink {
namespace scheduler {
......@@ -57,10 +58,13 @@ class BLINK_PLATFORM_EXPORT WebThreadScheduler {
// the main thread. They have default implementation that only does
// NOTREACHED(), and are overridden only by the main thread scheduler.
// If |initial_virtual_time| is specified then the scheduler will be created
// with virtual time enabled and paused, and base::Time will be overridden to
// start at |initial_virtual_time|.
// If |message_pump| is null caller must have registered one using
// base::MessageLoop.
// If |initial_virtual_time| is specified then the
// scheduler will be created with virtual time enabled and paused, and
// base::Time will be overridden to start at |initial_virtual_time|.
static std::unique_ptr<WebThreadScheduler> CreateMainThreadScheduler(
std::unique_ptr<base::MessagePump> message_pump = nullptr,
base::Optional<base::Time> initial_virtual_time = base::nullopt);
// Returns compositor thread scheduler for the compositor thread
......
......@@ -18,15 +18,20 @@ WebThreadScheduler::~WebThreadScheduler() = default;
// static
std::unique_ptr<WebThreadScheduler>
WebThreadScheduler::CreateMainThreadScheduler(
std::unique_ptr<base::MessagePump> message_pump,
base::Optional<base::Time> initial_virtual_time) {
// Ensure categories appear as an option in chrome://tracing.
WarmupTracingCategories();
// Workers might be short-lived, so placing warmup here.
TRACE_EVENT_WARMUP_CATEGORY(TRACE_DISABLED_BY_DEFAULT("worker.scheduler"));
auto sequence_manager =
message_pump
? base::sequence_manager::
CreateSequenceManagerOnCurrentThreadWithPump(
base::MessageLoop::TYPE_DEFAULT, std::move(message_pump))
: base::sequence_manager::CreateSequenceManagerOnCurrentThread();
std::unique_ptr<MainThreadSchedulerImpl> scheduler(
new MainThreadSchedulerImpl(
base::sequence_manager::CreateSequenceManagerOnCurrentThread(),
new MainThreadSchedulerImpl(std::move(sequence_manager),
initial_virtual_time));
return std::move(scheduler);
}
......
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