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

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.h

Issue 2742383005: [scheduler] Untangle BudgetPool from TaskQueueThrottler. (Closed)
Patch Set: Addressed comments from skyostil@ Created 3 years, 9 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 #ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_RENDERER_TASK_QUEUE_THROTTL ER_H_ 5 #ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_RENDERER_TASK_QUEUE_THROTTL ER_H_
6 #define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_RENDERER_TASK_QUEUE_THROTTL ER_H_ 6 #define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_RENDERER_TASK_QUEUE_THROTTL ER_H_
7 7
8 #include <set> 8 #include <set>
9 #include <unordered_map> 9 #include <unordered_map>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/optional.h" 13 #include "base/optional.h"
14 #include "base/threading/thread_checker.h" 14 #include "base/threading/thread_checker.h"
15 #include "platform/scheduler/base/cancelable_closure_holder.h" 15 #include "platform/scheduler/base/cancelable_closure_holder.h"
16 #include "platform/scheduler/base/time_domain.h" 16 #include "platform/scheduler/base/time_domain.h"
17 #include "platform/scheduler/renderer/budget_pool.h"
17 #include "public/platform/WebViewScheduler.h" 18 #include "public/platform/WebViewScheduler.h"
18 19
19 namespace base { 20 namespace base {
20 namespace trace_event { 21 namespace trace_event {
21 class TracedValue; 22 class TracedValue;
22 } 23 }
23 } 24 }
24 25
25 namespace blink { 26 namespace blink {
26 namespace scheduler { 27 namespace scheduler {
27 28
28 class BudgetPool; 29 class BudgetPool;
29 class RendererSchedulerImpl; 30 class RendererSchedulerImpl;
30 class ThrottledTimeDomain; 31 class ThrottledTimeDomain;
31 class CPUTimeBudgetPool; 32 class CPUTimeBudgetPool;
32 33
34 // Interface for BudgetPool to interact with TaskQueueThrottler.
35 class BLINK_PLATFORM_EXPORT BudgetPoolController {
36 public:
37 virtual ~BudgetPoolController() {}
38
39 // To be used by BudgetPool only, use BudgetPool::{Add,Remove}Queue
40 // methods instead.
41 virtual void AddQueueToBudgetPool(TaskQueue* queue,
42 BudgetPool* budget_pool) = 0;
43 virtual void RemoveQueueFromBudgetPool(TaskQueue* queue,
44 BudgetPool* budget_pool) = 0;
45
46 // Deletes the budget pool.
47 virtual void UnregisterBudgetPool(BudgetPool* budget_pool) = 0;
48
49 // Insert a fence to prevent tasks from running and schedule a wakeup at
50 // an appropriate time.
51 virtual void BlockQueue(base::TimeTicks now, TaskQueue* queue) = 0;
52
53 // Schedule a call to unblock queue at an appropriate moment.
54 virtual void UnblockQueue(base::TimeTicks now, TaskQueue* queue) = 0;
55
56 // Returns true if the |queue| is throttled (i.e. added to TaskQueueThrottler
57 // and throttling is not disabled).
58 virtual bool IsThrottled(TaskQueue* queue) const = 0;
59 };
60
33 // The job of the TaskQueueThrottler is to control when tasks posted on 61 // The job of the TaskQueueThrottler is to control when tasks posted on
34 // throttled queues get run. The TaskQueueThrottler: 62 // throttled queues get run. The TaskQueueThrottler:
35 // - runs throttled tasks once per second, 63 // - runs throttled tasks once per second,
36 // - controls time budget for task queues grouped in CPUTimeBudgetPools. 64 // - controls time budget for task queues grouped in CPUTimeBudgetPools.
37 // 65 //
38 // This is done by disabling throttled queues and running 66 // This is done by disabling throttled queues and running
39 // a special "heart beat" function |PumpThrottledTasks| which when run 67 // a special "heart beat" function |PumpThrottledTasks| which when run
40 // temporarily enables throttled queues and inserts a fence to ensure tasks 68 // temporarily enables throttled queues and inserts a fence to ensure tasks
41 // posted from a throttled task run next time the queue is pumped. 69 // posted from a throttled task run next time the queue is pumped.
42 // 70 //
43 // Of course the TaskQueueThrottler isn't the only sub-system that wants to 71 // Of course the TaskQueueThrottler isn't the only sub-system that wants to
44 // enable or disable queues. E.g. RendererSchedulerImpl also does this for 72 // enable or disable queues. E.g. RendererSchedulerImpl also does this for
45 // policy reasons. To prevent the systems from fighting, clients of 73 // policy reasons. To prevent the systems from fighting, clients of
46 // TaskQueueThrottler must use SetQueueEnabled rather than calling the function 74 // TaskQueueThrottler must use SetQueueEnabled rather than calling the function
47 // directly on the queue. 75 // directly on the queue.
48 // 76 //
49 // There may be more than one system that wishes to throttle a queue (e.g. 77 // There may be more than one system that wishes to throttle a queue (e.g.
50 // renderer suspension vs tab level suspension) so the TaskQueueThrottler keeps 78 // renderer suspension vs tab level suspension) so the TaskQueueThrottler keeps
51 // a count of the number of systems that wish a queue to be throttled. 79 // a count of the number of systems that wish a queue to be throttled.
52 // See IncreaseThrottleRefCount & DecreaseThrottleRefCount. 80 // See IncreaseThrottleRefCount & DecreaseThrottleRefCount.
53 // 81 //
54 // This class is main-thread only. 82 // This class is main-thread only.
55 class BLINK_PLATFORM_EXPORT TaskQueueThrottler : public TimeDomain::Observer { 83 class BLINK_PLATFORM_EXPORT TaskQueueThrottler : public TimeDomain::Observer,
84 BudgetPoolController {
Sami 2017/03/15 15:08:08 nit: public inheritance plz
altimin 2017/03/15 18:20:56 Done.
56 public: 85 public:
57 // TODO(altimin): Do not pass tracing category as const char*, 86 // TODO(altimin): Do not pass tracing category as const char*,
58 // hard-code string instead. 87 // hard-code string instead.
59 TaskQueueThrottler(RendererSchedulerImpl* renderer_scheduler, 88 TaskQueueThrottler(RendererSchedulerImpl* renderer_scheduler,
60 const char* tracing_category); 89 const char* tracing_category);
61 90
62 ~TaskQueueThrottler() override; 91 ~TaskQueueThrottler() override;
63 92
64 // TimeDomain::Observer implementation: 93 // TimeDomain::Observer implementation:
65 void OnTimeDomainHasImmediateWork(TaskQueue*) override; 94 void OnTimeDomainHasImmediateWork(TaskQueue*) override;
66 void OnTimeDomainHasDelayedWork(TaskQueue*) override; 95 void OnTimeDomainHasDelayedWork(TaskQueue*) override;
67 96
97 // BudgetPoolController implementation:
98 void AddQueueToBudgetPool(TaskQueue* queue, BudgetPool* budget_pool) override;
99 void RemoveQueueFromBudgetPool(TaskQueue* queue,
100 BudgetPool* budget_pool) override;
101 void UnregisterBudgetPool(BudgetPool* budget_pool) override;
102 void BlockQueue(base::TimeTicks now, TaskQueue* queue) override;
103 void UnblockQueue(base::TimeTicks now, TaskQueue* queue) override;
104 bool IsThrottled(TaskQueue* queue) const override;
105
68 // Increments the throttled refcount and causes |task_queue| to be throttled 106 // Increments the throttled refcount and causes |task_queue| to be throttled
69 // if its not already throttled. 107 // if its not already throttled.
70 void IncreaseThrottleRefCount(TaskQueue* task_queue); 108 void IncreaseThrottleRefCount(TaskQueue* task_queue);
71 109
72 // If the refcouint is non-zero it's decremented. If the throttled refcount 110 // If the refcouint is non-zero it's decremented. If the throttled refcount
73 // becomes zero then |task_queue| is unthrottled. If the refcount was already 111 // becomes zero then |task_queue| is unthrottled. If the refcount was already
74 // zero this function does nothing. 112 // zero this function does nothing.
75 void DecreaseThrottleRefCount(TaskQueue* task_queue); 113 void DecreaseThrottleRefCount(TaskQueue* task_queue);
76 114
77 // Removes |task_queue| from |queue_details| and from appropriate budget pool. 115 // Removes |task_queue| from |queue_details| and from appropriate budget pool.
78 void UnregisterTaskQueue(TaskQueue* task_queue); 116 void UnregisterTaskQueue(TaskQueue* task_queue);
79 117
80 // Returns true if the |task_queue| is throttled.
81 bool IsThrottled(TaskQueue* task_queue) const;
82
83 // Disable throttling for all queues, this setting takes precedence over 118 // Disable throttling for all queues, this setting takes precedence over
84 // all other throttling settings. Designed to be used when a global event 119 // all other throttling settings. Designed to be used when a global event
85 // disabling throttling happens (e.g. audio is playing). 120 // disabling throttling happens (e.g. audio is playing).
86 void DisableThrottling(); 121 void DisableThrottling();
87 122
88 // Enable back global throttling. 123 // Enable back global throttling.
89 void EnableThrottling(); 124 void EnableThrottling();
90 125
91 const ThrottledTimeDomain* time_domain() const { return time_domain_.get(); } 126 const ThrottledTimeDomain* time_domain() const { return time_domain_.get(); }
92 127
93 static base::TimeTicks AlignedThrottledRunTime( 128 static base::TimeTicks AlignedThrottledRunTime(
94 base::TimeTicks unthrottled_runtime); 129 base::TimeTicks unthrottled_runtime);
95 130
96 const scoped_refptr<TaskQueue>& task_runner() const { return task_runner_; } 131 const scoped_refptr<TaskQueue>& task_runner() const { return task_runner_; }
97 132
98 // Returned object is owned by |TaskQueueThrottler|. 133 // Returned object is owned by |TaskQueueThrottler|.
99 CPUTimeBudgetPool* CreateCPUTimeBudgetPool( 134 CPUTimeBudgetPool* CreateCPUTimeBudgetPool(
100 const char* name, 135 const char* name,
101 base::Optional<base::TimeDelta> max_budget_level, 136 base::Optional<base::TimeDelta> max_budget_level,
102 base::Optional<base::TimeDelta> max_throttling_duration); 137 base::Optional<base::TimeDelta> max_throttling_duration);
103 138
104 // Accounts for given task for cpu-based throttling needs. 139 // Accounts for given task for cpu-based throttling needs.
105 void OnTaskRunTimeReported(TaskQueue* task_queue, 140 void OnTaskRunTimeReported(TaskQueue* task_queue,
106 base::TimeTicks start_time, 141 base::TimeTicks start_time,
107 base::TimeTicks end_time); 142 base::TimeTicks end_time);
108 143
109 void AsValueInto(base::trace_event::TracedValue* state, 144 void AsValueInto(base::trace_event::TracedValue* state,
110 base::TimeTicks now) const; 145 base::TimeTicks now) const;
111
112 private: 146 private:
113 friend class BudgetPool;
114 friend class CPUTimeBudgetPool;
115
116 struct Metadata { 147 struct Metadata {
117 Metadata() : throttling_ref_count(0), time_budget_pool(nullptr) {} 148 Metadata() : throttling_ref_count(0), budget_pool(nullptr) {}
118 149
119 size_t throttling_ref_count; 150 size_t throttling_ref_count;
120 151
121 CPUTimeBudgetPool* time_budget_pool; 152 BudgetPool* budget_pool;
122 }; 153 };
123 using TaskQueueMap = std::unordered_map<TaskQueue*, Metadata>; 154 using TaskQueueMap = std::unordered_map<TaskQueue*, Metadata>;
124 155
125 void PumpThrottledTasks(); 156 void PumpThrottledTasks();
126 157
127 // Note |unthrottled_runtime| might be in the past. When this happens we 158 // Note |unthrottled_runtime| might be in the past. When this happens we
128 // compute the delay to the next runtime based on now rather than 159 // compute the delay to the next runtime based on now rather than
129 // unthrottled_runtime. 160 // unthrottled_runtime.
130 void MaybeSchedulePumpThrottledTasks( 161 void MaybeSchedulePumpThrottledTasks(
131 const tracked_objects::Location& from_here, 162 const tracked_objects::Location& from_here,
132 base::TimeTicks now, 163 base::TimeTicks now,
133 base::TimeTicks runtime); 164 base::TimeTicks runtime);
134 165
135 CPUTimeBudgetPool* GetTimeBudgetPoolForQueue(TaskQueue* queue); 166 BudgetPool* GetBudgetPoolForQueue(TaskQueue* queue);
136
137 // Schedule pumping because of given task queue.
138 void MaybeSchedulePumpQueue(
139 const tracked_objects::Location& from_here,
140 base::TimeTicks now,
141 TaskQueue* queue,
142 base::Optional<base::TimeTicks> next_possible_run_time);
143 167
144 // Return next possible time when queue is allowed to run in accordance 168 // Return next possible time when queue is allowed to run in accordance
145 // with throttling policy. 169 // with throttling policy.
146 base::TimeTicks GetNextAllowedRunTime(base::TimeTicks now, TaskQueue* queue); 170 base::TimeTicks GetNextAllowedRunTime(base::TimeTicks now, TaskQueue* queue);
147 171
148 void MaybeDeleteQueueMetadata(TaskQueueMap::iterator it); 172 void MaybeDeleteQueueMetadata(TaskQueueMap::iterator it);
149 173
174 // Schedule a call PumpThrottledTasks at an appropriate moment for this queue.
175 void SchedulePumpQueue(const tracked_objects::Location& from_here,
176 base::TimeTicks now,
177 TaskQueue* queue);
178
150 TaskQueueMap queue_details_; 179 TaskQueueMap queue_details_;
151 base::Callback<void(TaskQueue*)> forward_immediate_work_callback_; 180 base::Callback<void(TaskQueue*)> forward_immediate_work_callback_;
152 scoped_refptr<TaskQueue> task_runner_; 181 scoped_refptr<TaskQueue> task_runner_;
153 RendererSchedulerImpl* renderer_scheduler_; // NOT OWNED 182 RendererSchedulerImpl* renderer_scheduler_; // NOT OWNED
154 base::TickClock* tick_clock_; // NOT OWNED 183 base::TickClock* tick_clock_; // NOT OWNED
155 const char* tracing_category_; // NOT OWNED 184 const char* tracing_category_; // NOT OWNED
156 std::unique_ptr<ThrottledTimeDomain> time_domain_; 185 std::unique_ptr<ThrottledTimeDomain> time_domain_;
157 186
158 CancelableClosureHolder pump_throttled_tasks_closure_; 187 CancelableClosureHolder pump_throttled_tasks_closure_;
159 base::Optional<base::TimeTicks> pending_pump_throttled_tasks_runtime_; 188 base::Optional<base::TimeTicks> pending_pump_throttled_tasks_runtime_;
160 bool allow_throttling_; 189 bool allow_throttling_;
161 190
162 std::unordered_map<BudgetPool*, std::unique_ptr<BudgetPool>> 191 std::unordered_map<BudgetPool*, std::unique_ptr<BudgetPool>> budget_pools_;
163 time_budget_pools_;
164 192
165 base::WeakPtrFactory<TaskQueueThrottler> weak_factory_; 193 base::WeakPtrFactory<TaskQueueThrottler> weak_factory_;
166 194
167 DISALLOW_COPY_AND_ASSIGN(TaskQueueThrottler); 195 DISALLOW_COPY_AND_ASSIGN(TaskQueueThrottler);
168 }; 196 };
169 197
170 } // namespace scheduler 198 } // namespace scheduler
171 } // namespace blink 199 } // namespace blink
172 200
173 #endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_RENDERER_TASK_QUEUE_THRO TTLER_H_ 201 #endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_RENDERER_TASK_QUEUE_THRO TTLER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698