Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/child/worker_scheduler_impl.cc

Issue 2806623004: Worker: Introduce per-global-scope task scheduler (Closed)
Patch Set: remove unnecessary comments Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "platform/scheduler/child/worker_scheduler_impl.h" 5 #include "platform/scheduler/child/worker_scheduler_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/metrics/histogram_macros.h" 8 #include "base/metrics/histogram_macros.h"
9 #include "base/trace_event/trace_event.h" 9 #include "base/trace_event/trace_event.h"
10 #include "base/trace_event/trace_event_argument.h" 10 #include "base/trace_event/trace_event_argument.h"
11 #include "platform/Histogram.h"
11 #include "platform/scheduler/base/time_converter.h" 12 #include "platform/scheduler/base/time_converter.h"
12 #include "platform/scheduler/child/scheduler_tqm_delegate.h" 13 #include "platform/scheduler/child/scheduler_tqm_delegate.h"
14 #include "platform/wtf/PtrUtil.h"
13 #include "public/platform/scheduler/base/task_queue.h" 15 #include "public/platform/scheduler/base/task_queue.h"
14 16
15 namespace blink { 17 namespace blink {
16 namespace scheduler { 18 namespace scheduler {
17 19
18 namespace { 20 namespace {
19 // Workers could be short-lived, set a shorter interval than 21 // Workers could be short-lived, set a shorter interval than
20 // the renderer thread. 22 // the renderer thread.
21 constexpr base::TimeDelta kWorkerThreadLoadTrackerReportingInterval = 23 constexpr base::TimeDelta kWorkerThreadLoadTrackerReportingInterval =
22 base::TimeDelta::FromSeconds(1); 24 base::TimeDelta::FromSeconds(1);
23 // Start reporting the load right away. 25 // Start reporting the load right away.
24 constexpr base::TimeDelta kWorkerThreadLoadTrackerWaitingPeriodBeforeReporting = 26 constexpr base::TimeDelta kWorkerThreadLoadTrackerWaitingPeriodBeforeReporting =
25 base::TimeDelta::FromSeconds(0); 27 base::TimeDelta::FromSeconds(0);
26 28
27 void ReportWorkerTaskLoad(base::TimeTicks time, double load) { 29 void ReportWorkerTaskLoad(base::TimeTicks time, double load) {
28 int load_percentage = static_cast<int>(load * 100); 30 int load_percentage = static_cast<int>(load * 100);
29 DCHECK_LE(load_percentage, 100); 31 DCHECK_LE(load_percentage, 100);
30 // TODO(kinuko): Maybe we also want to separately log when the associated 32 // TODO(kinuko): Maybe we also want to separately log when the associated
31 // tab is in foreground and when not. 33 // tab is in foreground and when not.
32 UMA_HISTOGRAM_PERCENTAGE("WorkerScheduler.WorkerThreadLoad", load_percentage); 34 UMA_HISTOGRAM_PERCENTAGE("WorkerScheduler.WorkerThreadLoad", load_percentage);
33 } 35 }
34 36
35 } // namespace 37 } // namespace
36 38
37 WorkerSchedulerImpl::WorkerSchedulerImpl( 39 WorkerSchedulerImpl::WorkerSchedulerImpl(
38 scoped_refptr<SchedulerTqmDelegate> main_task_runner) 40 scoped_refptr<SchedulerTqmDelegate> main_task_runner)
39 : helper_(main_task_runner, 41 : WorkerScheduler(WTF::MakeUnique<SchedulerHelper>(
40 "worker.scheduler", 42 main_task_runner,
41 TRACE_DISABLED_BY_DEFAULT("worker.scheduler"), 43 "worker.scheduler",
42 TRACE_DISABLED_BY_DEFAULT("worker.scheduler.debug")), 44 TRACE_DISABLED_BY_DEFAULT("worker.scheduler"),
43 idle_helper_(&helper_, 45 TRACE_DISABLED_BY_DEFAULT("worker.scheduler.debug"))),
46 idle_helper_(helper_.get(),
44 this, 47 this,
45 "worker.scheduler", 48 "worker.scheduler",
46 TRACE_DISABLED_BY_DEFAULT("worker.scheduler"), 49 TRACE_DISABLED_BY_DEFAULT("worker.scheduler"),
47 "WorkerSchedulerIdlePeriod", 50 "WorkerSchedulerIdlePeriod",
48 base::TimeDelta::FromMilliseconds(300)), 51 base::TimeDelta::FromMilliseconds(300)),
49 idle_canceled_delayed_task_sweeper_("worker.scheduler", 52 idle_canceled_delayed_task_sweeper_("worker.scheduler",
50 &helper_, 53 helper_.get(),
51 idle_helper_.IdleTaskRunner()), 54 idle_helper_.IdleTaskRunner()),
52 load_tracker_(helper_.scheduler_tqm_delegate()->NowTicks(), 55 load_tracker_(helper_->scheduler_tqm_delegate()->NowTicks(),
53 base::Bind(&ReportWorkerTaskLoad), 56 base::Bind(&ReportWorkerTaskLoad),
54 kWorkerThreadLoadTrackerReportingInterval, 57 kWorkerThreadLoadTrackerReportingInterval,
55 kWorkerThreadLoadTrackerWaitingPeriodBeforeReporting) { 58 kWorkerThreadLoadTrackerWaitingPeriodBeforeReporting) {
56 initialized_ = false; 59 initialized_ = false;
57 thread_start_time_ = helper_.scheduler_tqm_delegate()->NowTicks(); 60 thread_start_time_ = helper_->scheduler_tqm_delegate()->NowTicks();
58 load_tracker_.Resume(thread_start_time_); 61 load_tracker_.Resume(thread_start_time_);
59 helper_.AddTaskTimeObserver(this); 62 helper_->AddTaskTimeObserver(this);
60 TRACE_EVENT_OBJECT_CREATED_WITH_ID( 63 TRACE_EVENT_OBJECT_CREATED_WITH_ID(
61 TRACE_DISABLED_BY_DEFAULT("worker.scheduler"), "WorkerScheduler", this); 64 TRACE_DISABLED_BY_DEFAULT("worker.scheduler"), "WorkerScheduler", this);
62 } 65 }
63 66
64 WorkerSchedulerImpl::~WorkerSchedulerImpl() { 67 WorkerSchedulerImpl::~WorkerSchedulerImpl() {
65 TRACE_EVENT_OBJECT_DELETED_WITH_ID( 68 TRACE_EVENT_OBJECT_DELETED_WITH_ID(
66 TRACE_DISABLED_BY_DEFAULT("worker.scheduler"), "WorkerScheduler", this); 69 TRACE_DISABLED_BY_DEFAULT("worker.scheduler"), "WorkerScheduler", this);
67 helper_.RemoveTaskTimeObserver(this); 70 helper_->RemoveTaskTimeObserver(this);
68 } 71 }
69 72
70 void WorkerSchedulerImpl::Init() { 73 void WorkerSchedulerImpl::Init() {
71 initialized_ = true; 74 initialized_ = true;
72 idle_helper_.EnableLongIdlePeriod(); 75 idle_helper_.EnableLongIdlePeriod();
73 } 76 }
74 77
75 scoped_refptr<TaskQueue> WorkerSchedulerImpl::DefaultTaskRunner() { 78 scoped_refptr<TaskQueue> WorkerSchedulerImpl::DefaultTaskRunner() {
76 DCHECK(initialized_); 79 DCHECK(initialized_);
77 return helper_.DefaultTaskRunner(); 80 return helper_->DefaultTaskRunner();
78 } 81 }
79 82
80 scoped_refptr<SingleThreadIdleTaskRunner> 83 scoped_refptr<SingleThreadIdleTaskRunner>
81 WorkerSchedulerImpl::IdleTaskRunner() { 84 WorkerSchedulerImpl::IdleTaskRunner() {
82 DCHECK(initialized_); 85 DCHECK(initialized_);
83 return idle_helper_.IdleTaskRunner(); 86 return idle_helper_.IdleTaskRunner();
84 } 87 }
85 88
86 bool WorkerSchedulerImpl::CanExceedIdleDeadlineIfRequired() const { 89 bool WorkerSchedulerImpl::CanExceedIdleDeadlineIfRequired() const {
87 DCHECK(initialized_); 90 DCHECK(initialized_);
88 return idle_helper_.CanExceedIdleDeadlineIfRequired(); 91 return idle_helper_.CanExceedIdleDeadlineIfRequired();
89 } 92 }
90 93
91 bool WorkerSchedulerImpl::ShouldYieldForHighPriorityWork() { 94 bool WorkerSchedulerImpl::ShouldYieldForHighPriorityWork() {
92 // We don't consider any work as being high priority on workers. 95 // We don't consider any work as being high priority on workers.
93 return false; 96 return false;
94 } 97 }
95 98
96 void WorkerSchedulerImpl::AddTaskObserver( 99 void WorkerSchedulerImpl::AddTaskObserver(
97 base::MessageLoop::TaskObserver* task_observer) { 100 base::MessageLoop::TaskObserver* task_observer) {
98 DCHECK(initialized_); 101 DCHECK(initialized_);
99 helper_.AddTaskObserver(task_observer); 102 helper_->AddTaskObserver(task_observer);
100 } 103 }
101 104
102 void WorkerSchedulerImpl::RemoveTaskObserver( 105 void WorkerSchedulerImpl::RemoveTaskObserver(
103 base::MessageLoop::TaskObserver* task_observer) { 106 base::MessageLoop::TaskObserver* task_observer) {
104 DCHECK(initialized_); 107 DCHECK(initialized_);
105 helper_.RemoveTaskObserver(task_observer); 108 helper_->RemoveTaskObserver(task_observer);
106 } 109 }
107 110
108 void WorkerSchedulerImpl::Shutdown() { 111 void WorkerSchedulerImpl::Shutdown() {
109 DCHECK(initialized_); 112 DCHECK(initialized_);
110 load_tracker_.RecordIdle(helper_.scheduler_tqm_delegate()->NowTicks()); 113 load_tracker_.RecordIdle(helper_->scheduler_tqm_delegate()->NowTicks());
111 base::TimeTicks end_time = helper_.scheduler_tqm_delegate()->NowTicks(); 114 base::TimeTicks end_time = helper_->scheduler_tqm_delegate()->NowTicks();
112 base::TimeDelta delta = end_time - thread_start_time_; 115 base::TimeDelta delta = end_time - thread_start_time_;
113 116
114 // The lifetime could be radically different for different workers, 117 // The lifetime could be radically different for different workers,
115 // some workers could be short-lived (but last at least 1 sec in 118 // some workers could be short-lived (but last at least 1 sec in
116 // Service Workers case) or could be around as long as the tab is open. 119 // Service Workers case) or could be around as long as the tab is open.
117 UMA_HISTOGRAM_CUSTOM_TIMES( 120 UMA_HISTOGRAM_CUSTOM_TIMES(
118 "WorkerThread.Runtime", delta, base::TimeDelta::FromSeconds(1), 121 "WorkerThread.Runtime", delta, base::TimeDelta::FromSeconds(1),
119 base::TimeDelta::FromDays(1), 50 /* bucket count */); 122 base::TimeDelta::FromDays(1), 50 /* bucket count */);
120 helper_.Shutdown(); 123 helper_->Shutdown();
121 } 124 }
122 125
123 SchedulerHelper* WorkerSchedulerImpl::GetSchedulerHelperForTesting() { 126 SchedulerHelper* WorkerSchedulerImpl::GetSchedulerHelperForTesting() {
124 return &helper_; 127 return helper_.get();
125 } 128 }
126 129
127 bool WorkerSchedulerImpl::CanEnterLongIdlePeriod(base::TimeTicks, 130 bool WorkerSchedulerImpl::CanEnterLongIdlePeriod(base::TimeTicks,
128 base::TimeDelta*) { 131 base::TimeDelta*) {
129 return true; 132 return true;
130 } 133 }
131 134
132 base::TimeTicks WorkerSchedulerImpl::CurrentIdleTaskDeadlineForTesting() const { 135 base::TimeTicks WorkerSchedulerImpl::CurrentIdleTaskDeadlineForTesting() const {
133 return idle_helper_.CurrentIdleTaskDeadline(); 136 return idle_helper_.CurrentIdleTaskDeadline();
134 } 137 }
135 138
136 void WorkerSchedulerImpl::WillProcessTask(TaskQueue* task_queue, 139 void WorkerSchedulerImpl::WillProcessTask(TaskQueue* task_queue,
137 double start_time) {} 140 double start_time) {}
138 141
139 void WorkerSchedulerImpl::DidProcessTask(TaskQueue* task_queue, 142 void WorkerSchedulerImpl::DidProcessTask(TaskQueue* task_queue,
140 double start_time, 143 double start_time,
141 double end_time) { 144 double end_time) {
145 DEFINE_THREAD_SAFE_STATIC_LOCAL(
146 CustomCountHistogram, task_time_counter,
147 new CustomCountHistogram("WorkerThread.Task.Time", 0, 10000000, 50));
148 task_time_counter.Count((end_time - start_time) *
149 base::Time::kMicrosecondsPerSecond);
150
142 base::TimeTicks start_time_ticks = 151 base::TimeTicks start_time_ticks =
143 MonotonicTimeInSecondsToTimeTicks(start_time); 152 MonotonicTimeInSecondsToTimeTicks(start_time);
144 base::TimeTicks end_time_ticks = MonotonicTimeInSecondsToTimeTicks(end_time); 153 base::TimeTicks end_time_ticks = MonotonicTimeInSecondsToTimeTicks(end_time);
145 154
146 load_tracker_.RecordTaskTime(start_time_ticks, end_time_ticks); 155 load_tracker_.RecordTaskTime(start_time_ticks, end_time_ticks);
147 } 156 }
148 157
149 void WorkerSchedulerImpl::OnBeginNestedMessageLoop() {} 158 void WorkerSchedulerImpl::OnBeginNestedMessageLoop() {}
150 159
151 } // namespace scheduler 160 } // namespace scheduler
152 } // namespace blink 161 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698