Commit bb4ba82e authored by Nate Chapin's avatar Nate Chapin Committed by Commit Bot

Support WorkerSchedulers for nested workers

Currently, FrameSchedulerImpl keeps a set of throttling observers that
it notifies when throttling state changes. This includes each worker's
WorkerSchedulerProxy.

This CL moves throttling observers to the base class,
FrameOrWorkerScheduler, allowing each nested worker to register its
WorkerSchedulerProxy with its parent WorkerScheduler, so the
WorkerScheduler can then propagate throttling state to the nested
worker.

Bug: 829119
Change-Id: If005e3ec781b2fc0ecd3ba1ba73fa4b0e6ef1a0f
Reviewed-on: https://chromium-review.googlesource.com/994060Reviewed-by: default avatarPavel Feldman <pfeldman@chromium.org>
Reviewed-by: default avatarHiroki Nakagawa <nhiroki@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Commit-Queue: Nate Chapin <japhet@chromium.org>
Cr-Commit-Position: refs/heads/master@{#562052}
parent 0dd64bcc
...@@ -42,7 +42,7 @@ class TaskTimeObserver; ...@@ -42,7 +42,7 @@ class TaskTimeObserver;
namespace blink { namespace blink {
class FrameScheduler; class FrameOrWorkerScheduler;
class ThreadScheduler; class ThreadScheduler;
// Always an integer value. // Always an integer value.
...@@ -53,13 +53,13 @@ struct BLINK_PLATFORM_EXPORT WebThreadCreationParams { ...@@ -53,13 +53,13 @@ struct BLINK_PLATFORM_EXPORT WebThreadCreationParams {
WebThreadCreationParams& SetThreadNameForTest(const char* name); WebThreadCreationParams& SetThreadNameForTest(const char* name);
// Sets a scheduler for the frame which was responsible for the creation // Sets a scheduler for the context which was responsible for the creation
// of this thread. // of this thread.
WebThreadCreationParams& SetFrameScheduler(FrameScheduler*); WebThreadCreationParams& SetFrameOrWorkerScheduler(FrameOrWorkerScheduler*);
WebThreadType thread_type; WebThreadType thread_type;
const char* name; const char* name;
FrameScheduler* frame_scheduler; // NOT OWNED FrameOrWorkerScheduler* frame_or_worker_scheduler; // NOT OWNED
base::Thread::Options thread_options; base::Thread::Options thread_options;
}; };
......
...@@ -151,11 +151,6 @@ class EmptyFrameScheduler final : public FrameScheduler { ...@@ -151,11 +151,6 @@ class EmptyFrameScheduler final : public FrameScheduler {
return Platform::Current()->MainThread()->GetTaskRunner(); return Platform::Current()->MainThread()->GetTaskRunner();
} }
std::unique_ptr<ThrottlingObserverHandle> AddThrottlingObserver(
ObserverType,
Observer*) override {
return nullptr;
}
void SetFrameVisible(bool) override {} void SetFrameVisible(bool) override {}
bool IsFrameVisible() const override { return false; } bool IsFrameVisible() const override { return false; }
bool IsPageVisible() const override { return false; } bool IsPageVisible() const override { return false; }
......
...@@ -41,20 +41,18 @@ ...@@ -41,20 +41,18 @@
#include "third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.h" #include "third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.h"
#include "third_party/blink/renderer/core/workers/global_scope_creation_params.h" #include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
#include "third_party/blink/renderer/core/workers/worker_backing_thread.h" #include "third_party/blink/renderer/core/workers/worker_backing_thread.h"
#include "third_party/blink/renderer/platform/web_thread_supporting_gc.h"
namespace blink { namespace blink {
namespace { namespace {
FrameScheduler* GetFrameScheduler(ThreadableLoadingContext* loading_context) { FrameOrWorkerScheduler* GetFrameOrWorkerScheduler(
ThreadableLoadingContext* loading_context) {
// |loading_context| can be null in unittests. // |loading_context| can be null in unittests.
if (!loading_context) if (!loading_context)
return nullptr; return nullptr;
if (!loading_context->GetExecutionContext()->IsDocument()) return loading_context->GetExecutionContext()->GetScheduler();
return nullptr;
return ToDocument(loading_context->GetExecutionContext())
->GetFrame()
->GetFrameScheduler();
} }
} // namespace } // namespace
...@@ -72,7 +70,8 @@ DedicatedWorkerThread::DedicatedWorkerThread( ...@@ -72,7 +70,8 @@ DedicatedWorkerThread::DedicatedWorkerThread(
: WorkerThread(loading_context, worker_object_proxy), : WorkerThread(loading_context, worker_object_proxy),
worker_backing_thread_(WorkerBackingThread::Create( worker_backing_thread_(WorkerBackingThread::Create(
WebThreadCreationParams(GetThreadType()) WebThreadCreationParams(GetThreadType())
.SetFrameScheduler(GetFrameScheduler(loading_context)))), .SetFrameOrWorkerScheduler(
GetFrameOrWorkerScheduler(loading_context)))),
worker_object_proxy_(worker_object_proxy) {} worker_object_proxy_(worker_object_proxy) {}
DedicatedWorkerThread::~DedicatedWorkerThread() = default; DedicatedWorkerThread::~DedicatedWorkerThread() = default;
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/non_main_thread_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h"
#include "third_party/blink/renderer/platform/waitable_event.h" #include "third_party/blink/renderer/platform/waitable_event.h"
#include "third_party/blink/renderer/platform/web_thread_supporting_gc.h" #include "third_party/blink/renderer/platform/web_thread_supporting_gc.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h"
...@@ -418,7 +418,9 @@ void WorkerThread::InitializeSchedulerOnWorkerThread( ...@@ -418,7 +418,9 @@ void WorkerThread::InitializeSchedulerOnWorkerThread(
static_cast<scheduler::WebThreadImplForWorkerScheduler&>( static_cast<scheduler::WebThreadImplForWorkerScheduler&>(
GetWorkerBackingThread().BackingThread().PlatformThread()); GetWorkerBackingThread().BackingThread().PlatformThread());
worker_scheduler_ = std::make_unique<scheduler::WorkerScheduler>( worker_scheduler_ = std::make_unique<scheduler::WorkerScheduler>(
web_thread_for_worker.GetNonMainThreadScheduler()); static_cast<scheduler::WorkerThreadScheduler*>(
web_thread_for_worker.GetNonMainThreadScheduler()),
web_thread_for_worker.worker_scheduler_proxy());
waitable_event->Signal(); waitable_event->Signal();
} }
......
...@@ -68,6 +68,7 @@ blink_platform_sources("scheduler") { ...@@ -68,6 +68,7 @@ blink_platform_sources("scheduler") {
"child/worker_scheduler_proxy.h", "child/worker_scheduler_proxy.h",
"child/worker_task_queue.cc", "child/worker_task_queue.cc",
"child/worker_task_queue.h", "child/worker_task_queue.h",
"common/frame_or_worker_scheduler.cc",
"common/scheduler_helper.cc", "common/scheduler_helper.cc",
"common/scheduler_helper.h", "common/scheduler_helper.h",
"common/thread_scheduler.cc", "common/thread_scheduler.cc",
......
...@@ -23,10 +23,10 @@ WebThreadImplForWorkerScheduler::WebThreadImplForWorkerScheduler( ...@@ -23,10 +23,10 @@ WebThreadImplForWorkerScheduler::WebThreadImplForWorkerScheduler(
const WebThreadCreationParams& params) const WebThreadCreationParams& params)
: thread_(new base::Thread(params.name ? params.name : std::string())), : thread_(new base::Thread(params.name ? params.name : std::string())),
thread_type_(params.thread_type), thread_type_(params.thread_type),
worker_scheduler_proxy_( worker_scheduler_proxy_(params.frame_or_worker_scheduler
params.frame_scheduler ? std::make_unique<WorkerSchedulerProxy>(
? std::make_unique<WorkerSchedulerProxy>(params.frame_scheduler) params.frame_or_worker_scheduler)
: nullptr) { : nullptr) {
bool started = thread_->StartWithOptions(params.thread_options); bool started = thread_->StartWithOptions(params.thread_options);
CHECK(started); CHECK(started);
thread_task_runner_ = thread_->task_runner(); thread_task_runner_ = thread_->task_runner();
......
...@@ -55,15 +55,18 @@ class PLATFORM_EXPORT WebThreadImplForWorkerScheduler ...@@ -55,15 +55,18 @@ class PLATFORM_EXPORT WebThreadImplForWorkerScheduler
return non_main_thread_scheduler_.get(); return non_main_thread_scheduler_.get();
} }
scheduler::WorkerSchedulerProxy* worker_scheduler_proxy() const {
return worker_scheduler_proxy_.get();
}
protected: protected:
virtual std::unique_ptr<NonMainThreadScheduler> virtual std::unique_ptr<NonMainThreadScheduler>
CreateNonMainThreadScheduler(); CreateNonMainThreadScheduler();
base::Thread* GetThread() const { return thread_.get(); } base::Thread* GetThread() const { return thread_.get(); }
scheduler::WorkerSchedulerProxy* worker_scheduler_proxy() const { // protected instead of private for unit tests.
return worker_scheduler_proxy_.get(); scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner_;
}
private: private:
void AddTaskObserverInternal( void AddTaskObserverInternal(
...@@ -78,7 +81,6 @@ class PLATFORM_EXPORT WebThreadImplForWorkerScheduler ...@@ -78,7 +81,6 @@ class PLATFORM_EXPORT WebThreadImplForWorkerScheduler
const WebThreadType thread_type_; const WebThreadType thread_type_;
std::unique_ptr<scheduler::WorkerSchedulerProxy> worker_scheduler_proxy_; std::unique_ptr<scheduler::WorkerSchedulerProxy> worker_scheduler_proxy_;
std::unique_ptr<scheduler::NonMainThreadScheduler> non_main_thread_scheduler_; std::unique_ptr<scheduler::NonMainThreadScheduler> non_main_thread_scheduler_;
scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner_;
scoped_refptr<base::sequence_manager::TaskQueue> task_queue_; scoped_refptr<base::sequence_manager::TaskQueue> task_queue_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
scoped_refptr<scheduler::SingleThreadIdleTaskRunner> idle_task_runner_; scoped_refptr<scheduler::SingleThreadIdleTaskRunner> idle_task_runner_;
......
...@@ -5,24 +5,34 @@ ...@@ -5,24 +5,34 @@
#include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h" #include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h"
#include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h"
#include "third_party/blink/renderer/platform/scheduler/public/non_main_thread_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h"
namespace blink { namespace blink {
namespace scheduler { namespace scheduler {
WorkerScheduler::WorkerScheduler( WorkerScheduler::WorkerScheduler(WorkerThreadScheduler* worker_thread_scheduler,
NonMainThreadScheduler* non_main_thread_scheduler) WorkerSchedulerProxy* proxy)
: default_task_queue_(non_main_thread_scheduler->CreateTaskRunner()), : default_task_queue_(worker_thread_scheduler->CreateTaskRunner()),
throttleable_task_queue_(non_main_thread_scheduler->CreateTaskRunner()), throttleable_task_queue_(worker_thread_scheduler->CreateTaskRunner()),
thread_scheduler_(non_main_thread_scheduler) { thread_scheduler_(worker_thread_scheduler),
weak_factory_(this) {
thread_scheduler_->RegisterWorkerScheduler(this); thread_scheduler_->RegisterWorkerScheduler(this);
if (WakeUpBudgetPool* wake_up_budget_pool = if (WakeUpBudgetPool* wake_up_budget_pool =
thread_scheduler_->wake_up_budget_pool()) { thread_scheduler_->wake_up_budget_pool()) {
wake_up_budget_pool->AddQueue(thread_scheduler_->GetTickClock()->NowTicks(), wake_up_budget_pool->AddQueue(thread_scheduler_->GetTickClock()->NowTicks(),
throttleable_task_queue_.get()); throttleable_task_queue_.get());
} }
// |proxy| can be nullptr in unit tests.
if (proxy)
proxy->OnWorkerSchedulerCreated(GetWeakPtr());
}
base::WeakPtr<WorkerScheduler> WorkerScheduler::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
} }
WorkerScheduler::~WorkerScheduler() { WorkerScheduler::~WorkerScheduler() {
...@@ -36,6 +46,11 @@ WorkerScheduler::OnActiveConnectionCreated() { ...@@ -36,6 +46,11 @@ WorkerScheduler::OnActiveConnectionCreated() {
return nullptr; return nullptr;
} }
FrameOrWorkerScheduler::ThrottlingState
WorkerScheduler::CalculateThrottlingState(ObserverType) const {
return thread_scheduler_->throttling_state();
}
void WorkerScheduler::Dispose() { void WorkerScheduler::Dispose() {
if (TaskQueueThrottler* throttler = if (TaskQueueThrottler* throttler =
thread_scheduler_->task_queue_throttler()) { thread_scheduler_->task_queue_throttler()) {
...@@ -117,10 +132,11 @@ scoped_refptr<base::SingleThreadTaskRunner> WorkerScheduler::GetTaskRunner( ...@@ -117,10 +132,11 @@ scoped_refptr<base::SingleThreadTaskRunner> WorkerScheduler::GetTaskRunner(
} }
void WorkerScheduler::OnThrottlingStateChanged( void WorkerScheduler::OnThrottlingStateChanged(
FrameScheduler::ThrottlingState throttling_state) { ThrottlingState throttling_state) {
if (throttling_state_ == throttling_state) if (throttling_state_ == throttling_state)
return; return;
throttling_state_ = throttling_state; throttling_state_ = throttling_state;
thread_scheduler_->OnThrottlingStateChanged(throttling_state);
if (TaskQueueThrottler* throttler = if (TaskQueueThrottler* throttler =
thread_scheduler_->task_queue_throttler()) { thread_scheduler_->task_queue_throttler()) {
...@@ -130,6 +146,7 @@ void WorkerScheduler::OnThrottlingStateChanged( ...@@ -130,6 +146,7 @@ void WorkerScheduler::OnThrottlingStateChanged(
throttler->DecreaseThrottleRefCount(throttleable_task_queue_.get()); throttler->DecreaseThrottleRefCount(throttleable_task_queue_.get());
} }
} }
NotifyThrottlingObservers();
} }
scoped_refptr<base::sequence_manager::TaskQueue> scoped_refptr<base::sequence_manager::TaskQueue>
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_WORKER_SCHEDULER_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_WORKER_SCHEDULER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_WORKER_SCHEDULER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_WORKER_SCHEDULER_H_
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h"
...@@ -15,7 +16,8 @@ namespace blink { ...@@ -15,7 +16,8 @@ namespace blink {
namespace scheduler { namespace scheduler {
class NonMainThreadScheduler; class WorkerSchedulerProxy;
class WorkerThreadScheduler;
// A scheduler provides per-global-scope task queues. This is constructed when a // A scheduler provides per-global-scope task queues. This is constructed when a
// global scope is created and destructed when it's closed. // global scope is created and destructed when it's closed.
...@@ -23,7 +25,8 @@ class NonMainThreadScheduler; ...@@ -23,7 +25,8 @@ class NonMainThreadScheduler;
// Unless stated otherwise, all methods must be called on the worker thread. // Unless stated otherwise, all methods must be called on the worker thread.
class PLATFORM_EXPORT WorkerScheduler : public FrameOrWorkerScheduler { class PLATFORM_EXPORT WorkerScheduler : public FrameOrWorkerScheduler {
public: public:
explicit WorkerScheduler(NonMainThreadScheduler* non_main_thread_scheduler); WorkerScheduler(WorkerThreadScheduler* worker_thread_scheduler,
WorkerSchedulerProxy* proxy);
~WorkerScheduler() override; ~WorkerScheduler() override;
std::unique_ptr<ActiveConnectionHandle> OnActiveConnectionCreated() override; std::unique_ptr<ActiveConnectionHandle> OnActiveConnectionCreated() override;
...@@ -37,25 +40,34 @@ class PLATFORM_EXPORT WorkerScheduler : public FrameOrWorkerScheduler { ...@@ -37,25 +40,34 @@ class PLATFORM_EXPORT WorkerScheduler : public FrameOrWorkerScheduler {
// This must be called only from WorkerThread::GetTaskRunner(). // This must be called only from WorkerThread::GetTaskRunner().
scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(TaskType) const; scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(TaskType) const;
void OnThrottlingStateChanged( WorkerThreadScheduler* GetWorkerThreadScheduler() const {
FrameScheduler::ThrottlingState throtting_state); return thread_scheduler_;
}
void OnThrottlingStateChanged(ThrottlingState throttling_state);
ThrottlingState CalculateThrottlingState(ObserverType) const override;
protected: protected:
scoped_refptr<base::sequence_manager::TaskQueue> DefaultTaskQueue(); scoped_refptr<base::sequence_manager::TaskQueue> DefaultTaskQueue();
scoped_refptr<base::sequence_manager::TaskQueue> ThrottleableTaskQueue(); scoped_refptr<base::sequence_manager::TaskQueue> ThrottleableTaskQueue();
private: private:
base::WeakPtr<WorkerScheduler> GetWeakPtr();
scoped_refptr<base::sequence_manager::TaskQueue> default_task_queue_; scoped_refptr<base::sequence_manager::TaskQueue> default_task_queue_;
scoped_refptr<base::sequence_manager::TaskQueue> throttleable_task_queue_; scoped_refptr<base::sequence_manager::TaskQueue> throttleable_task_queue_;
FrameScheduler::ThrottlingState throttling_state_ = FrameScheduler::ThrottlingState throttling_state_ =
FrameScheduler::ThrottlingState::kNotThrottled; FrameScheduler::ThrottlingState::kNotThrottled;
NonMainThreadScheduler* thread_scheduler_; // NOT OWNED WorkerThreadScheduler* thread_scheduler_; // NOT OWNED
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
bool is_disposed_ = false; bool is_disposed_ = false;
#endif #endif
base::WeakPtrFactory<WorkerScheduler> weak_factory_;
}; };
} // namespace scheduler } // namespace scheduler
......
...@@ -4,36 +4,41 @@ ...@@ -4,36 +4,41 @@
#include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy.h" #include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy.h"
#include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h"
namespace blink { namespace blink {
namespace scheduler { namespace scheduler {
WorkerSchedulerProxy::WorkerSchedulerProxy(FrameScheduler* frame_scheduler) { WorkerSchedulerProxy::WorkerSchedulerProxy(FrameOrWorkerScheduler* scheduler) {
throttling_observer_handle_ = frame_scheduler->AddThrottlingObserver( DCHECK(scheduler);
FrameScheduler::ObserverType::kWorkerScheduler, this); throttling_observer_handle_ = scheduler->AddThrottlingObserver(
parent_frame_type_ = GetFrameOriginType(frame_scheduler); FrameOrWorkerScheduler::ObserverType::kWorkerScheduler, this);
if (FrameScheduler* frame_scheduler = scheduler->ToFrameScheduler()) {
parent_frame_type_ = GetFrameOriginType(frame_scheduler);
}
} }
WorkerSchedulerProxy::~WorkerSchedulerProxy() { WorkerSchedulerProxy::~WorkerSchedulerProxy() {
DCHECK(IsMainThread()); DETACH_FROM_THREAD(parent_thread_checker_);
} }
void WorkerSchedulerProxy::OnWorkerSchedulerCreated( void WorkerSchedulerProxy::OnWorkerSchedulerCreated(
base::WeakPtr<WorkerThreadScheduler> worker_scheduler) { base::WeakPtr<WorkerScheduler> worker_scheduler) {
DCHECK(!IsMainThread()) DCHECK(!IsMainThread())
<< "OnWorkerSchedulerCreated should be called from the worker thread"; << "OnWorkerSchedulerCreated should be called from the worker thread";
DCHECK(!worker_scheduler_) << "OnWorkerSchedulerCreated is called twice"; DCHECK(!worker_scheduler_) << "OnWorkerSchedulerCreated is called twice";
DCHECK(worker_scheduler) << "WorkerScheduler is expected to exist"; DCHECK(worker_scheduler) << "WorkerScheduler is expected to exist";
worker_scheduler_ = std::move(worker_scheduler); worker_scheduler_ = std::move(worker_scheduler);
worker_thread_task_runner_ = worker_scheduler_->ControlTaskQueue(); worker_thread_task_runner_ =
worker_scheduler_->GetWorkerThreadScheduler()->ControlTaskQueue();
initialized_ = true; initialized_ = true;
} }
void WorkerSchedulerProxy::OnThrottlingStateChanged( void WorkerSchedulerProxy::OnThrottlingStateChanged(
FrameScheduler::ThrottlingState throttling_state) { FrameScheduler::ThrottlingState throttling_state) {
DCHECK(IsMainThread()); DCHECK_CALLED_ON_VALID_THREAD(parent_thread_checker_);
if (throttling_state_ == throttling_state) if (throttling_state_ == throttling_state)
return; return;
throttling_state_ = throttling_state; throttling_state_ = throttling_state;
...@@ -42,9 +47,8 @@ void WorkerSchedulerProxy::OnThrottlingStateChanged( ...@@ -42,9 +47,8 @@ void WorkerSchedulerProxy::OnThrottlingStateChanged(
return; return;
worker_thread_task_runner_->PostTask( worker_thread_task_runner_->PostTask(
FROM_HERE, FROM_HERE, base::BindOnce(&WorkerScheduler::OnThrottlingStateChanged,
base::BindOnce(&WorkerThreadScheduler::OnThrottlingStateChanged, worker_scheduler_, throttling_state));
worker_scheduler_, throttling_state));
} }
} // namespace scheduler } // namespace scheduler
......
...@@ -8,62 +8,69 @@ ...@@ -8,62 +8,69 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/child/page_visibility_state.h" #include "third_party/blink/renderer/platform/scheduler/child/page_visibility_state.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/wtf.h" #include "third_party/blink/renderer/platform/wtf/wtf.h"
namespace blink { namespace blink {
namespace scheduler { namespace scheduler {
class WorkerThreadScheduler; class WorkerScheduler;
// Helper class for communication between frame scheduler (main thread) and // Helper class for communication between parent scheduler (may be a frame
// worker scheduler (worker thread). // scheduler on the main thread or another woker scheduler on a worker thread)
// and worker scheduler (worker thread).
// //
// It's owned by DedicatedWorkerThread and is created and destroyed // It's owned by DedicatedWorkerThread and is created and destroyed
// on the main thread. It's passed to WorkerScheduler during its construction. // on the parent thread. It's passed to WorkerScheduler during its
// Given that DedicatedWorkerThread object outlives worker thread, this class // construction. Given that DedicatedWorkerThread object outlives worker thread,
// outlives worker thread too. // this class outlives worker thread too.
class PLATFORM_EXPORT WorkerSchedulerProxy : public FrameScheduler::Observer { class PLATFORM_EXPORT WorkerSchedulerProxy
: public FrameOrWorkerScheduler::Observer {
public: public:
explicit WorkerSchedulerProxy(FrameScheduler* scheduler); explicit WorkerSchedulerProxy(FrameOrWorkerScheduler* scheduler);
~WorkerSchedulerProxy() override; ~WorkerSchedulerProxy() override;
void OnWorkerSchedulerCreated( void OnWorkerSchedulerCreated(
base::WeakPtr<WorkerThreadScheduler> worker_scheduler); base::WeakPtr<WorkerScheduler> worker_scheduler);
void OnThrottlingStateChanged( void OnThrottlingStateChanged(
FrameScheduler::ThrottlingState throttling_state) override; FrameOrWorkerScheduler::ThrottlingState throttling_state) override;
// Should be accessed only from the main thread or during init. // Accessed only during init.
FrameScheduler::ThrottlingState throttling_state() const { FrameOrWorkerScheduler::ThrottlingState throttling_state() const {
DCHECK(IsMainThread() || !initialized_); DCHECK(!initialized_);
return throttling_state_; return throttling_state_;
} }
FrameOriginType parent_frame_type() const { // Accessed only during init.
DCHECK(IsMainThread() || !initialized_); base::Optional<FrameOriginType> parent_frame_type() const {
DCHECK(!initialized_);
return parent_frame_type_; return parent_frame_type_;
} }
private: private:
// Can be accessed only from the worker thread. // Can be accessed only from the worker thread.
base::WeakPtr<WorkerThreadScheduler> worker_scheduler_; base::WeakPtr<WorkerScheduler> worker_scheduler_;
// Const after init on the worker thread. // Const after init on the worker thread.
scoped_refptr<base::SingleThreadTaskRunner> worker_thread_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> worker_thread_task_runner_;
FrameScheduler::ThrottlingState throttling_state_ = FrameOrWorkerScheduler::ThrottlingState throttling_state_ =
FrameScheduler::ThrottlingState::kNotThrottled; FrameOrWorkerScheduler::ThrottlingState::kNotThrottled;
std::unique_ptr<FrameScheduler::ThrottlingObserverHandle> std::unique_ptr<FrameOrWorkerScheduler::ThrottlingObserverHandle>
throttling_observer_handle_; throttling_observer_handle_;
bool initialized_ = false; bool initialized_ = false;
FrameOriginType parent_frame_type_; base::Optional<FrameOriginType> parent_frame_type_;
THREAD_CHECKER(parent_thread_checker_);
DISALLOW_COPY_AND_ASSIGN(WorkerSchedulerProxy); DISALLOW_COPY_AND_ASSIGN(WorkerSchedulerProxy);
}; };
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h"
#include "third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h"
...@@ -52,15 +53,37 @@ class WebThreadImplForWorkerSchedulerForTest ...@@ -52,15 +53,37 @@ class WebThreadImplForWorkerSchedulerForTest
WaitableEvent* throtting_state_changed) WaitableEvent* throtting_state_changed)
: WebThreadImplForWorkerScheduler( : WebThreadImplForWorkerScheduler(
WebThreadCreationParams(WebThreadType::kTestThread) WebThreadCreationParams(WebThreadType::kTestThread)
.SetFrameScheduler(frame_scheduler)), .SetFrameOrWorkerScheduler(frame_scheduler)),
throtting_state_changed_(throtting_state_changed) {} throtting_state_changed_(throtting_state_changed) {}
~WebThreadImplForWorkerSchedulerForTest() override {
base::WaitableEvent completion(
base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
thread_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&WebThreadImplForWorkerSchedulerForTest::
DisposeWorkerSchedulerOnThread,
base::Unretained(this), &completion));
completion.Wait();
}
void DisposeWorkerSchedulerOnThread(base::WaitableEvent* completion) {
DCHECK(thread_task_runner_->BelongsToCurrentThread());
if (worker_scheduler_) {
worker_scheduler_->Dispose();
worker_scheduler_ = nullptr;
}
completion->Signal();
}
std::unique_ptr<NonMainThreadScheduler> CreateNonMainThreadScheduler() std::unique_ptr<NonMainThreadScheduler> CreateNonMainThreadScheduler()
override { override {
auto scheduler = std::make_unique<WorkerThreadSchedulerForTest>( auto scheduler = std::make_unique<WorkerThreadSchedulerForTest>(
base::sequence_manager::TaskQueueManager::TakeOverCurrentThread(), base::sequence_manager::TaskQueueManager::TakeOverCurrentThread(),
worker_scheduler_proxy(), throtting_state_changed_); worker_scheduler_proxy(), throtting_state_changed_);
scheduler_ = scheduler.get(); scheduler_ = scheduler.get();
worker_scheduler_ = std::make_unique<scheduler::WorkerScheduler>(
scheduler_, worker_scheduler_proxy());
return scheduler; return scheduler;
} }
...@@ -69,6 +92,7 @@ class WebThreadImplForWorkerSchedulerForTest ...@@ -69,6 +92,7 @@ class WebThreadImplForWorkerSchedulerForTest
private: private:
WaitableEvent* throtting_state_changed_; // NOT OWNED WaitableEvent* throtting_state_changed_; // NOT OWNED
WorkerThreadSchedulerForTest* scheduler_ = nullptr; // NOT OWNED WorkerThreadSchedulerForTest* scheduler_ = nullptr; // NOT OWNED
std::unique_ptr<WorkerScheduler> worker_scheduler_ = nullptr;
}; };
std::unique_ptr<WebThreadImplForWorkerSchedulerForTest> CreateWorkerThread( std::unique_ptr<WebThreadImplForWorkerSchedulerForTest> CreateWorkerThread(
......
...@@ -65,7 +65,7 @@ class WorkerSchedulerForTest : public WorkerScheduler { ...@@ -65,7 +65,7 @@ class WorkerSchedulerForTest : public WorkerScheduler {
public: public:
explicit WorkerSchedulerForTest( explicit WorkerSchedulerForTest(
WorkerThreadSchedulerForTest* thread_scheduler) WorkerThreadSchedulerForTest* thread_scheduler)
: WorkerScheduler(thread_scheduler) {} : WorkerScheduler(thread_scheduler, nullptr) {}
using WorkerScheduler::DefaultTaskQueue; using WorkerScheduler::DefaultTaskQueue;
using WorkerScheduler::ThrottleableTaskQueue; using WorkerScheduler::ThrottleableTaskQueue;
......
// Copyright 2018 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.
#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
namespace blink {
// static
const char* FrameOrWorkerScheduler::ThrottlingStateToString(
ThrottlingState state) {
switch (state) {
case ThrottlingState::kNotThrottled:
return "not throttled";
case ThrottlingState::kHidden:
return "hidden";
case ThrottlingState::kThrottled:
return "throttled";
case ThrottlingState::kStopped:
return "frozen";
default:
NOTREACHED();
return nullptr;
}
}
FrameOrWorkerScheduler::ThrottlingObserverHandle::ThrottlingObserverHandle(
FrameOrWorkerScheduler* scheduler,
Observer* observer)
: scheduler_(scheduler->GetWeakPtr()), observer_(observer) {}
FrameOrWorkerScheduler::ThrottlingObserverHandle::~ThrottlingObserverHandle() {
if (scheduler_)
scheduler_->RemoveThrottlingObserver(observer_);
}
FrameOrWorkerScheduler::FrameOrWorkerScheduler() : weak_factory_(this) {}
FrameOrWorkerScheduler::~FrameOrWorkerScheduler() {
weak_factory_.InvalidateWeakPtrs();
}
std::unique_ptr<FrameOrWorkerScheduler::ThrottlingObserverHandle>
FrameOrWorkerScheduler::AddThrottlingObserver(ObserverType type,
Observer* observer) {
DCHECK(observer);
observer->OnThrottlingStateChanged(CalculateThrottlingState(type));
throttling_observers_[observer] = type;
return std::make_unique<ThrottlingObserverHandle>(this, observer);
}
void FrameOrWorkerScheduler::RemoveThrottlingObserver(Observer* observer) {
DCHECK(observer);
const auto found = throttling_observers_.find(observer);
DCHECK(throttling_observers_.end() != found);
throttling_observers_.erase(found);
}
void FrameOrWorkerScheduler::NotifyThrottlingObservers() {
for (const auto& observer : throttling_observers_) {
observer.first->OnThrottlingStateChanged(
CalculateThrottlingState(observer.second));
}
}
base::WeakPtr<FrameOrWorkerScheduler> FrameOrWorkerScheduler::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
} // namespace blink
...@@ -24,23 +24,6 @@ ...@@ -24,23 +24,6 @@
namespace blink { namespace blink {
// static
const char* FrameScheduler::ThrottlingStateToString(ThrottlingState state) {
switch (state) {
case ThrottlingState::kNotThrottled:
return "not throttled";
case ThrottlingState::kHidden:
return "hidden";
case ThrottlingState::kThrottled:
return "throttled";
case ThrottlingState::kStopped:
return "frozen";
default:
NOTREACHED();
return nullptr;
}
}
namespace scheduler { namespace scheduler {
using base::sequence_manager::TaskQueue; using base::sequence_manager::TaskQueue;
...@@ -88,19 +71,10 @@ FrameSchedulerImpl::ActiveConnectionHandleImpl::ActiveConnectionHandleImpl( ...@@ -88,19 +71,10 @@ FrameSchedulerImpl::ActiveConnectionHandleImpl::ActiveConnectionHandleImpl(
} }
FrameSchedulerImpl::ActiveConnectionHandleImpl::~ActiveConnectionHandleImpl() { FrameSchedulerImpl::ActiveConnectionHandleImpl::~ActiveConnectionHandleImpl() {
if (frame_scheduler_) if (frame_scheduler_) {
frame_scheduler_->DidCloseActiveConnection(); static_cast<FrameSchedulerImpl*>(frame_scheduler_.get())
} ->DidCloseActiveConnection();
}
FrameSchedulerImpl::ThrottlingObserverHandleImpl::ThrottlingObserverHandleImpl(
FrameSchedulerImpl* frame_scheduler,
Observer* observer)
: frame_scheduler_(frame_scheduler->GetWeakPtr()), observer_(observer) {}
FrameSchedulerImpl::ThrottlingObserverHandleImpl::
~ThrottlingObserverHandleImpl() {
if (frame_scheduler_)
frame_scheduler_->RemoveThrottlingObserver(observer_);
} }
FrameSchedulerImpl::FrameSchedulerImpl( FrameSchedulerImpl::FrameSchedulerImpl(
...@@ -158,8 +132,7 @@ FrameSchedulerImpl::FrameSchedulerImpl( ...@@ -158,8 +132,7 @@ FrameSchedulerImpl::FrameSchedulerImpl(
"FrameScheduler.KeepActive", "FrameScheduler.KeepActive",
this, this,
&tracing_controller_, &tracing_controller_,
KeepActiveStateToString), KeepActiveStateToString) {}
weak_factory_(this) {}
namespace { namespace {
...@@ -175,8 +148,6 @@ void CleanUpQueue(MainThreadTaskQueue* queue) { ...@@ -175,8 +148,6 @@ void CleanUpQueue(MainThreadTaskQueue* queue) {
} // namespace } // namespace
FrameSchedulerImpl::~FrameSchedulerImpl() { FrameSchedulerImpl::~FrameSchedulerImpl() {
weak_factory_.InvalidateWeakPtrs();
RemoveThrottleableQueueFromBackgroundCPUTimeBudgetPool(); RemoveThrottleableQueueFromBackgroundCPUTimeBudgetPool();
CleanUpQueue(loading_task_queue_.get()); CleanUpQueue(loading_task_queue_.get());
...@@ -219,22 +190,6 @@ void FrameSchedulerImpl:: ...@@ -219,22 +190,6 @@ void FrameSchedulerImpl::
throttleable_task_queue_.get()); throttleable_task_queue_.get());
} }
std::unique_ptr<FrameScheduler::ThrottlingObserverHandle>
FrameSchedulerImpl::AddThrottlingObserver(ObserverType type,
Observer* observer) {
DCHECK(observer);
observer->OnThrottlingStateChanged(CalculateThrottlingState(type));
throttling_observers_[observer] = type;
return std::make_unique<ThrottlingObserverHandleImpl>(this, observer);
}
void FrameSchedulerImpl::RemoveThrottlingObserver(Observer* observer) {
DCHECK(observer);
const auto found = throttling_observers_.find(observer);
DCHECK(throttling_observers_.end() != found);
throttling_observers_.erase(found);
}
void FrameSchedulerImpl::SetFrameVisible(bool frame_visible) { void FrameSchedulerImpl::SetFrameVisible(bool frame_visible) {
DCHECK(parent_page_scheduler_); DCHECK(parent_page_scheduler_);
if (frame_visible_ == frame_visible) if (frame_visible_ == frame_visible)
...@@ -606,13 +561,6 @@ void FrameSchedulerImpl::UpdateQueuePolicy( ...@@ -606,13 +561,6 @@ void FrameSchedulerImpl::UpdateQueuePolicy(
voter->SetQueueEnabled(!queue_paused && !queue_frozen); voter->SetQueueEnabled(!queue_paused && !queue_frozen);
} }
void FrameSchedulerImpl::NotifyThrottlingObservers() {
for (const auto& observer : throttling_observers_) {
observer.first->OnThrottlingStateChanged(
CalculateThrottlingState(observer.second));
}
}
FrameScheduler::ThrottlingState FrameSchedulerImpl::CalculateThrottlingState( FrameScheduler::ThrottlingState FrameSchedulerImpl::CalculateThrottlingState(
ObserverType type) const { ObserverType type) const {
// Detached frames are not throttled. // Detached frames are not throttled.
...@@ -675,10 +623,6 @@ void FrameSchedulerImpl::UpdateThrottling() { ...@@ -675,10 +623,6 @@ void FrameSchedulerImpl::UpdateThrottling() {
} }
} }
base::WeakPtr<FrameSchedulerImpl> FrameSchedulerImpl::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
bool FrameSchedulerImpl::IsExemptFromBudgetBasedThrottling() const { bool FrameSchedulerImpl::IsExemptFromBudgetBasedThrottling() const {
return has_active_connection(); return has_active_connection();
} }
......
...@@ -59,9 +59,6 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler { ...@@ -59,9 +59,6 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler {
~FrameSchedulerImpl() override; ~FrameSchedulerImpl() override;
// FrameScheduler implementation: // FrameScheduler implementation:
std::unique_ptr<ThrottlingObserverHandle> AddThrottlingObserver(
ObserverType,
Observer*) override;
void SetFrameVisible(bool frame_visible) override; void SetFrameVisible(bool frame_visible) override;
bool IsFrameVisible() const override; bool IsFrameVisible() const override;
bool IsPageVisible() const override; bool IsPageVisible() const override;
...@@ -109,36 +106,21 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler { ...@@ -109,36 +106,21 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler {
~ActiveConnectionHandleImpl() override; ~ActiveConnectionHandleImpl() override;
private: private:
base::WeakPtr<FrameSchedulerImpl> frame_scheduler_; base::WeakPtr<FrameOrWorkerScheduler> frame_scheduler_;
DISALLOW_COPY_AND_ASSIGN(ActiveConnectionHandleImpl); DISALLOW_COPY_AND_ASSIGN(ActiveConnectionHandleImpl);
}; };
class ThrottlingObserverHandleImpl : public ThrottlingObserverHandle {
public:
ThrottlingObserverHandleImpl(FrameSchedulerImpl* frame_scheduler,
Observer* observer);
~ThrottlingObserverHandleImpl() override;
private:
base::WeakPtr<FrameSchedulerImpl> frame_scheduler_;
Observer* observer_;
DISALLOW_COPY_AND_ASSIGN(ThrottlingObserverHandleImpl);
};
void DetachFromPageScheduler(); void DetachFromPageScheduler();
void RemoveThrottleableQueueFromBackgroundCPUTimeBudgetPool(); void RemoveThrottleableQueueFromBackgroundCPUTimeBudgetPool();
void ApplyPolicyToThrottleableQueue(); void ApplyPolicyToThrottleableQueue();
bool ShouldThrottleTimers() const; bool ShouldThrottleTimers() const;
FrameScheduler::ThrottlingState CalculateThrottlingState( FrameScheduler::ThrottlingState CalculateThrottlingState(
ObserverType type) const; ObserverType type) const override;
void RemoveThrottlingObserver(Observer* observer);
void UpdateQueuePolicy( void UpdateQueuePolicy(
const scoped_refptr<MainThreadTaskQueue>& queue, const scoped_refptr<MainThreadTaskQueue>& queue,
base::sequence_manager::TaskQueue::QueueEnabledVoter* voter); base::sequence_manager::TaskQueue::QueueEnabledVoter* voter);
void UpdateThrottling(); void UpdateThrottling();
void NotifyThrottlingObservers();
void DidOpenActiveConnection(); void DidOpenActiveConnection();
void DidCloseActiveConnection(); void DidCloseActiveConnection();
...@@ -150,8 +132,6 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler { ...@@ -150,8 +132,6 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler {
scoped_refptr<base::sequence_manager::TaskQueue> PausableTaskQueue(); scoped_refptr<base::sequence_manager::TaskQueue> PausableTaskQueue();
scoped_refptr<base::sequence_manager::TaskQueue> UnpausableTaskQueue(); scoped_refptr<base::sequence_manager::TaskQueue> UnpausableTaskQueue();
base::WeakPtr<FrameSchedulerImpl> GetWeakPtr();
const FrameScheduler::FrameType frame_type_; const FrameScheduler::FrameType frame_type_;
TraceableVariableController tracing_controller_; TraceableVariableController tracing_controller_;
...@@ -174,8 +154,6 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler { ...@@ -174,8 +154,6 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler {
MainThreadSchedulerImpl* main_thread_scheduler_; // NOT OWNED MainThreadSchedulerImpl* main_thread_scheduler_; // NOT OWNED
PageSchedulerImpl* parent_page_scheduler_; // NOT OWNED PageSchedulerImpl* parent_page_scheduler_; // NOT OWNED
base::trace_event::BlameContext* blame_context_; // NOT OWNED base::trace_event::BlameContext* blame_context_; // NOT OWNED
// Observers are not owned by the scheduler.
std::unordered_map<Observer*, ObserverType> throttling_observers_;
FrameScheduler::ThrottlingState throttling_state_; FrameScheduler::ThrottlingState throttling_state_;
TraceableState<bool, kTracingCategoryNameInfo> frame_visible_; TraceableState<bool, kTracingCategoryNameInfo> frame_visible_;
TraceableState<bool, kTracingCategoryNameInfo> frame_paused_; TraceableState<bool, kTracingCategoryNameInfo> frame_paused_;
...@@ -196,7 +174,6 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler { ...@@ -196,7 +174,6 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler {
page_visibility_for_tracing_; page_visibility_for_tracing_;
TraceableState<bool, kTracingCategoryNameInfo> page_keep_active_for_tracing_; TraceableState<bool, kTracingCategoryNameInfo> page_keep_active_for_tracing_;
base::WeakPtrFactory<FrameSchedulerImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(FrameSchedulerImpl); DISALLOW_COPY_AND_ASSIGN(FrameSchedulerImpl);
}; };
......
...@@ -5,16 +5,62 @@ ...@@ -5,16 +5,62 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_FRAME_OR_WORKER_SCHEDULER_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_FRAME_OR_WORKER_SCHEDULER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_FRAME_OR_WORKER_SCHEDULER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_FRAME_OR_WORKER_SCHEDULER_H_
#include <unordered_map>
#include "base/memory/weak_ptr.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/allocator.h"
namespace blink { namespace blink {
class FrameScheduler;
// This is the base class of FrameScheduler and WorkerScheduler. // This is the base class of FrameScheduler and WorkerScheduler.
class FrameOrWorkerScheduler { class PLATFORM_EXPORT FrameOrWorkerScheduler {
USING_FAST_MALLOC(FrameOrWorkerScheduler); USING_FAST_MALLOC(FrameOrWorkerScheduler);
public: public:
virtual ~FrameOrWorkerScheduler() = default; // Observer type that regulates conditions to invoke callbacks.
enum class ObserverType { kLoader, kWorkerScheduler };
// Represents throttling state.
// TODO(altimin): Move it into standalone LifecycleState.
enum class ThrottlingState {
// Frame is active and should not be throttled.
kNotThrottled,
// Frame has just been backgrounded and can be throttled non-aggressively.
kHidden,
// Frame spent some time in background and can be fully throttled.
kThrottled,
// Frame is stopped, no tasks associated with it can run.
kStopped,
};
static const char* ThrottlingStateToString(ThrottlingState state);
// Observer interface to receive scheduling policy change events.
class Observer {
public:
virtual ~Observer() = default;
// Notified when throttling state is changed. May be called consecutively
// with the same value.
virtual void OnThrottlingStateChanged(ThrottlingState) = 0;
};
class PLATFORM_EXPORT ThrottlingObserverHandle {
public:
ThrottlingObserverHandle(FrameOrWorkerScheduler* scheduler,
Observer* observer);
~ThrottlingObserverHandle();
private:
base::WeakPtr<FrameOrWorkerScheduler> scheduler_;
Observer* observer_;
DISALLOW_COPY_AND_ASSIGN(ThrottlingObserverHandle);
};
virtual ~FrameOrWorkerScheduler();
class ActiveConnectionHandle { class ActiveConnectionHandle {
public: public:
...@@ -30,6 +76,34 @@ class FrameOrWorkerScheduler { ...@@ -30,6 +76,34 @@ class FrameOrWorkerScheduler {
// this handle must be destroyed. // this handle must be destroyed.
virtual std::unique_ptr<ActiveConnectionHandle> virtual std::unique_ptr<ActiveConnectionHandle>
OnActiveConnectionCreated() = 0; OnActiveConnectionCreated() = 0;
// Adds an Observer instance to be notified on scheduling policy changed.
// When an Observer is added, the initial state will be notified synchronously
// through the Observer interface.
// A RAII handle is returned and observer is unregistered when the handle is
// destroyed.
std::unique_ptr<ThrottlingObserverHandle> AddThrottlingObserver(ObserverType,
Observer*);
virtual FrameScheduler* ToFrameScheduler() { return nullptr; }
protected:
FrameOrWorkerScheduler();
void NotifyThrottlingObservers();
virtual ThrottlingState CalculateThrottlingState(ObserverType) const {
return ThrottlingState::kNotThrottled;
}
base::WeakPtr<FrameOrWorkerScheduler> GetWeakPtr();
private:
void RemoveThrottlingObserver(Observer* observer);
// Observers are not owned by the scheduler.
std::unordered_map<Observer*, ObserverType> throttling_observers_;
base::WeakPtrFactory<FrameOrWorkerScheduler> weak_factory_;
}; };
} // namespace blink } // namespace blink
......
...@@ -23,59 +23,12 @@ class FrameScheduler : public FrameOrWorkerScheduler { ...@@ -23,59 +23,12 @@ class FrameScheduler : public FrameOrWorkerScheduler {
public: public:
~FrameScheduler() override = default; ~FrameScheduler() override = default;
// Observer type that regulates conditions to invoke callbacks.
enum class ObserverType { kLoader, kWorkerScheduler };
// Represents throttling state.
// TODO(altimin): Move it into standalone LifecycleState.
enum class ThrottlingState {
// Frame is active and should not be throttled.
kNotThrottled,
// Frame has just been backgrounded and can be throttled non-aggressively.
kHidden,
// Frame spent some time in background and can be fully throttled.
kThrottled,
// Frame is stopped, no tasks associated with it can run.
kStopped,
};
PLATFORM_EXPORT static const char* ThrottlingStateToString(
ThrottlingState state);
// Represents the type of frame: main (top-level) vs not. // Represents the type of frame: main (top-level) vs not.
enum class FrameType { enum class FrameType {
kMainFrame, kMainFrame,
kSubframe, kSubframe,
}; };
// Observer interface to receive scheduling policy change events.
class Observer {
public:
virtual ~Observer() = default;
// Notified when throttling state is changed. May be called consecutively
// with the same value.
virtual void OnThrottlingStateChanged(ThrottlingState) = 0;
};
class ThrottlingObserverHandle {
public:
ThrottlingObserverHandle() = default;
virtual ~ThrottlingObserverHandle() = default;
private:
DISALLOW_COPY_AND_ASSIGN(ThrottlingObserverHandle);
};
// Adds an Observer instance to be notified on scheduling policy changed.
// When an Observer is added, the initial state will be notified synchronously
// through the Observer interface.
// A RAII handle is returned and observer is unregistered when the handle is
// destroyed.
virtual std::unique_ptr<ThrottlingObserverHandle> AddThrottlingObserver(
ObserverType,
Observer*) = 0;
// The scheduler may throttle tasks associated with offscreen frames. // The scheduler may throttle tasks associated with offscreen frames.
virtual void SetFrameVisible(bool) = 0; virtual void SetFrameVisible(bool) = 0;
virtual bool IsFrameVisible() const = 0; virtual bool IsFrameVisible() const = 0;
...@@ -168,6 +121,8 @@ class FrameScheduler : public FrameOrWorkerScheduler { ...@@ -168,6 +121,8 @@ class FrameScheduler : public FrameOrWorkerScheduler {
// use GetPageScheduler()->IsExemptFromBudgetBasedThrottling for the status // use GetPageScheduler()->IsExemptFromBudgetBasedThrottling for the status
// of the page. // of the page.
virtual bool IsExemptFromBudgetBasedThrottling() const = 0; virtual bool IsExemptFromBudgetBasedThrottling() const = 0;
FrameScheduler* ToFrameScheduler() override { return this; }
}; };
} // namespace blink } // namespace blink
......
...@@ -104,11 +104,6 @@ class FakeFrameScheduler : public FrameScheduler { ...@@ -104,11 +104,6 @@ class FakeFrameScheduler : public FrameScheduler {
}; };
// FrameScheduler implementation: // FrameScheduler implementation:
std::unique_ptr<ThrottlingObserverHandle> AddThrottlingObserver(
ObserverType,
Observer*) override {
return nullptr;
}
void SetFrameVisible(bool) override {} void SetFrameVisible(bool) override {}
bool IsFrameVisible() const override { return is_frame_visible_; } bool IsFrameVisible() const override { return is_frame_visible_; }
bool IsPageVisible() const override { return is_page_visible_; } bool IsPageVisible() const override { return is_page_visible_; }
......
...@@ -75,16 +75,13 @@ WorkerThreadScheduler::WorkerThreadScheduler( ...@@ -75,16 +75,13 @@ WorkerThreadScheduler::WorkerThreadScheduler(
worker_metrics_helper_(thread_type), worker_metrics_helper_(thread_type),
default_task_runner_(TaskQueueWithTaskType::Create( default_task_runner_(TaskQueueWithTaskType::Create(
helper_->DefaultWorkerTaskQueue(), helper_->DefaultWorkerTaskQueue(),
TaskType::kWorkerThreadTaskQueueDefault)), TaskType::kWorkerThreadTaskQueueDefault)) {
weak_factory_(this) {
thread_start_time_ = helper_->NowTicks(); thread_start_time_ = helper_->NowTicks();
load_tracker_.Resume(thread_start_time_); load_tracker_.Resume(thread_start_time_);
helper_->AddTaskTimeObserver(this); helper_->AddTaskTimeObserver(this);
if (proxy) { if (proxy && proxy->parent_frame_type())
worker_metrics_helper_.SetParentFrameType(proxy->parent_frame_type()); worker_metrics_helper_.SetParentFrameType(*proxy->parent_frame_type());
proxy->OnWorkerSchedulerCreated(GetWeakPtr());
}
if (thread_type == WebThreadType::kDedicatedWorkerThread && if (thread_type == WebThreadType::kDedicatedWorkerThread &&
base::FeatureList::IsEnabled(kDedicatedWorkerThrottling)) { base::FeatureList::IsEnabled(kDedicatedWorkerThrottling)) {
...@@ -237,10 +234,6 @@ scoped_refptr<WorkerTaskQueue> WorkerThreadScheduler::ControlTaskQueue() { ...@@ -237,10 +234,6 @@ scoped_refptr<WorkerTaskQueue> WorkerThreadScheduler::ControlTaskQueue() {
return helper_->ControlWorkerTaskQueue(); return helper_->ControlWorkerTaskQueue();
} }
base::WeakPtr<WorkerThreadScheduler> WorkerThreadScheduler::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
void WorkerThreadScheduler::CreateTaskQueueThrottler() { void WorkerThreadScheduler::CreateTaskQueueThrottler() {
if (task_queue_throttler_) if (task_queue_throttler_)
return; return;
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_WORKER_WORKER_THREAD_SCHEDULER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_WORKER_WORKER_THREAD_SCHEDULER_H_
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "third_party/blink/public/platform/web_thread_type.h" #include "third_party/blink/public/platform/web_thread_type.h"
...@@ -74,6 +73,12 @@ class PLATFORM_EXPORT WorkerThreadScheduler ...@@ -74,6 +73,12 @@ class PLATFORM_EXPORT WorkerThreadScheduler
virtual void OnThrottlingStateChanged( virtual void OnThrottlingStateChanged(
FrameScheduler::ThrottlingState throttling_state); FrameScheduler::ThrottlingState throttling_state);
FrameScheduler::ThrottlingState throttling_state() const {
return throttling_state_;
}
void RegisterWorkerScheduler(WorkerScheduler* worker_scheduler) override;
// Returns the control task queue. Tasks posted to this queue are executed // Returns the control task queue. Tasks posted to this queue are executed
// with the highest priority. Care must be taken to avoid starvation of other // with the highest priority. Care must be taken to avoid starvation of other
// task queues. // task queues.
...@@ -92,19 +97,11 @@ class PLATFORM_EXPORT WorkerThreadScheduler ...@@ -92,19 +97,11 @@ class PLATFORM_EXPORT WorkerThreadScheduler
void OnIdlePeriodEnded() override {} void OnIdlePeriodEnded() override {}
void OnPendingTasksChanged(bool new_state) override {} void OnPendingTasksChanged(bool new_state) override {}
FrameScheduler::ThrottlingState throttling_state() const {
return throttling_state_;
}
void RegisterWorkerScheduler(WorkerScheduler* worker_scheduler) override;
void CreateTaskQueueThrottler(); void CreateTaskQueueThrottler();
private: private:
void MaybeStartLongIdlePeriod(); void MaybeStartLongIdlePeriod();
base::WeakPtr<WorkerThreadScheduler> GetWeakPtr();
IdleHelper idle_helper_; IdleHelper idle_helper_;
IdleCanceledDelayedTaskSweeper idle_canceled_delayed_task_sweeper_; IdleCanceledDelayedTaskSweeper idle_canceled_delayed_task_sweeper_;
ThreadLoadTracker load_tracker_; ThreadLoadTracker load_tracker_;
...@@ -119,8 +116,6 @@ class PLATFORM_EXPORT WorkerThreadScheduler ...@@ -119,8 +116,6 @@ class PLATFORM_EXPORT WorkerThreadScheduler
scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
base::WeakPtrFactory<WorkerThreadScheduler> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(WorkerThreadScheduler); DISALLOW_COPY_AND_ASSIGN(WorkerThreadScheduler);
}; };
......
...@@ -19,7 +19,7 @@ namespace blink { ...@@ -19,7 +19,7 @@ namespace blink {
WebThreadCreationParams::WebThreadCreationParams(WebThreadType thread_type) WebThreadCreationParams::WebThreadCreationParams(WebThreadType thread_type)
: thread_type(thread_type), : thread_type(thread_type),
name(GetNameForThreadType(thread_type)), name(GetNameForThreadType(thread_type)),
frame_scheduler(nullptr) {} frame_or_worker_scheduler(nullptr) {}
WebThreadCreationParams& WebThreadCreationParams::SetThreadNameForTest( WebThreadCreationParams& WebThreadCreationParams::SetThreadNameForTest(
const char* thread_name) { const char* thread_name) {
...@@ -27,9 +27,9 @@ WebThreadCreationParams& WebThreadCreationParams::SetThreadNameForTest( ...@@ -27,9 +27,9 @@ WebThreadCreationParams& WebThreadCreationParams::SetThreadNameForTest(
return *this; return *this;
} }
WebThreadCreationParams& WebThreadCreationParams::SetFrameScheduler( WebThreadCreationParams& WebThreadCreationParams::SetFrameOrWorkerScheduler(
FrameScheduler* scheduler) { FrameOrWorkerScheduler* scheduler) {
frame_scheduler = scheduler; frame_or_worker_scheduler = scheduler;
return *this; return *this;
} }
......
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