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

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

Issue 2778123003: [scheduler] Add WakeupBudgetPool. (Closed)
Patch Set: Addressed comments Created 3 years, 7 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 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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_BUDGET_POOL_H_ 5 #ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_RENDERER_BUDGET_POOL_H_
6 #define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_RENDERER_BUDGET_POOL_H_ 6 #define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_RENDERER_BUDGET_POOL_H_
7 7
8 #include <unordered_set> 8 #include <unordered_set>
9 9
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/gtest_prod_util.h"
12 #include "base/macros.h" 11 #include "base/macros.h"
13 #include "base/optional.h" 12 #include "base/optional.h"
14 #include "base/time/time.h" 13 #include "base/time/time.h"
15 #include "platform/scheduler/base/lazy_now.h" 14 #include "platform/scheduler/base/lazy_now.h"
16 15
17 namespace base { 16 namespace base {
18 namespace trace_event { 17 namespace trace_event {
19 class TracedValue; 18 class TracedValue;
20 } 19 }
21 } 20 }
22 21
23 namespace blink { 22 namespace blink {
24 namespace scheduler { 23 namespace scheduler {
25 24
26 class TaskQueue; 25 class TaskQueue;
27 class BudgetPoolController; 26 class BudgetPoolController;
27 enum class QueueBlockType;
28 28
29 // BudgetPool represents a group of task queues which share a limit 29 // BudgetPool represents a group of task queues which share a limit
30 // on a resource. This limit applies when task queues are already throttled 30 // on a resource. This limit applies when task queues are already throttled
31 // by TaskQueueThrottler. 31 // by TaskQueueThrottler.
32 class PLATFORM_EXPORT BudgetPool { 32 class PLATFORM_EXPORT BudgetPool {
33 public: 33 public:
34 virtual ~BudgetPool(); 34 virtual ~BudgetPool();
35 35
36 const char* Name() const; 36 const char* Name() const;
37 37
38 // Report task run time to the budget pool. 38 // Report task run time to the budget pool.
39 virtual void RecordTaskRunTime(base::TimeTicks start_time, 39 virtual void RecordTaskRunTime(TaskQueue* queue,
40 base::TimeTicks start_time,
40 base::TimeTicks end_time) = 0; 41 base::TimeTicks end_time) = 0;
41 42
42 // Retuns earliest time (can be in the past) when the next task can run. 43 // Returns the earliest time when the next pump can be scheduled to run
43 virtual base::TimeTicks GetNextAllowedRunTime() = 0; 44 // new tasks.
45 virtual base::TimeTicks GetNextAllowedRunTime(
46 base::TimeTicks desired_run_time) const = 0;
44 47
45 // Returns true at a task can be run immediately at the given time. 48 // Returns true if a task can run at the given time.
46 virtual bool HasEnoughBudgetToRun(base::TimeTicks now) = 0; 49 virtual bool CanRunTasksAt(base::TimeTicks moment, bool is_wake_up) const = 0;
50
51 // Notifies budget pool that queue has work with desired run time.
52 virtual void OnQueueNextWakeUpChanged(TaskQueue* queue,
53 base::TimeTicks now,
54 base::TimeTicks desired_run_time) = 0;
55
56 // Notifies budget pool that wakeup has happened.
57 virtual void OnWakeUp(base::TimeTicks now) = 0;
58
59 // Specify how this budget pool should block affected queues.
60 virtual QueueBlockType GetBlockType() const = 0;
47 61
48 // Returns state for tracing. 62 // Returns state for tracing.
49 virtual void AsValueInto(base::trace_event::TracedValue* state, 63 virtual void AsValueInto(base::trace_event::TracedValue* state,
50 base::TimeTicks now) const = 0; 64 base::TimeTicks now) const = 0;
51 65
52 // Adds |queue| to given pool. If the pool restriction does not allow 66 // Adds |queue| to given pool. If the pool restriction does not allow
53 // a task to be run immediately and |queue| is throttled, |queue| becomes 67 // a task to be run immediately and |queue| is throttled, |queue| becomes
54 // disabled. 68 // disabled.
55 void AddQueue(base::TimeTicks now, TaskQueue* queue); 69 void AddQueue(base::TimeTicks now, TaskQueue* queue);
56 70
57 // Removes |queue| from given pool. If it is throttled, it does not 71 // Removes |queue| from given pool. If it is throttled, it does not
58 // become enabled immediately, but a call to |PumpThrottledTasks| 72 // become enabled immediately, but a wake-up is scheduled if needed.
59 // is scheduled.
60 void RemoveQueue(base::TimeTicks now, TaskQueue* queue); 73 void RemoveQueue(base::TimeTicks now, TaskQueue* queue);
61 74
75 // Unlike RemoveQueue, does not schedule a new wake-up for the queue.
76 void UnregisterQueue(TaskQueue* queue);
77
62 // Enables this time budget pool. Queues from this pool will be 78 // Enables this time budget pool. Queues from this pool will be
63 // throttled based on their run time. 79 // throttled based on their run time.
64 void EnableThrottling(LazyNow* now); 80 void EnableThrottling(LazyNow* now);
65 81
66 // Disables with time budget pool. Queues from this pool will not be 82 // Disables with time budget pool. Queues from this pool will not be
67 // throttled based on their run time. A call to |PumpThrottledTasks| 83 // throttled based on their run time. A call to |PumpThrottledTasks|
68 // will be scheduled to enable this queues back again and respect 84 // will be scheduled to enable this queues back again and respect
69 // timer alignment. Internal budget level will not regenerate with time. 85 // timer alignment. Internal budget level will not regenerate with time.
70 void DisableThrottling(LazyNow* now); 86 void DisableThrottling(LazyNow* now);
71 87
72 bool IsThrottlingEnabled() const; 88 bool IsThrottlingEnabled() const;
73 89
74 // All queues should be removed before calling Close(). 90 // All queues should be removed before calling Close().
75 void Close(); 91 void Close();
76 92
77 // Block all associated queues and schedule them to run when appropriate. 93 // Block all associated queues and schedule them to run when appropriate.
78 void BlockThrottledQueues(base::TimeTicks now); 94 void BlockThrottledQueues(base::TimeTicks now);
79 95
80 protected: 96 protected:
81 BudgetPool(const char* name, BudgetPoolController* budget_pool_controller); 97 BudgetPool(const char* name, BudgetPoolController* budget_pool_controller);
82 98
83 const char* name_; // NOT OWNED 99 const char* name_; // NOT OWNED
84 100
85 BudgetPoolController* budget_pool_controller_; 101 BudgetPoolController* budget_pool_controller_;
86 102
87 std::unordered_set<TaskQueue*> associated_task_queues_; 103 std::unordered_set<TaskQueue*> associated_task_queues_;
88 bool is_enabled_; 104 bool is_enabled_;
89 };
90
91 // CPUTimeBudgetPool represents a collection of task queues which share a limit
92 // on total cpu time.
93 class PLATFORM_EXPORT CPUTimeBudgetPool : public BudgetPool {
94 public:
95 CPUTimeBudgetPool(const char* name,
96 BudgetPoolController* budget_pool_controller,
97 base::TimeTicks now);
98
99 ~CPUTimeBudgetPool();
100
101 // Set max budget level, base::nullopt represent absence of max level.
102 // Max budget level prevents accumulating arbitrary large budgets when
103 // page is inactive for a very long time.
104 void SetMaxBudgetLevel(base::TimeTicks now,
105 base::Optional<base::TimeDelta> max_budget_level);
106
107 // Set max throttling duration, base::nullopt represents absense of it.
108 // Max throttling duration prevents page from being throttled for
109 // a very long period after a single long task.
110 void SetMaxThrottlingDelay(
111 base::TimeTicks now,
112 base::Optional<base::TimeDelta> max_throttling_delay);
113
114 // Set minimal budget level required to run a task. If budget pool was
115 // exhausted, it needs to accumulate at least |min_budget_to_run| time units
116 // to unblock and run tasks again. When unblocked, it still can run tasks
117 // when budget is positive but less than this level until being blocked
118 // until being blocked when budget reaches zero.
119 // This is needed for integration with WakeUpBudgetPool to prevent a situation
120 // when wake-up happened but time budget pool allows only one task to run at
121 // the moment.
122 // It is recommended to use the same value for this and WakeUpBudgetPool's
123 // wake-up window length.
124 // NOTE: This does not have an immediate effect and does not call
125 // BudgetPoolController::UnblockQueue.
126 void SetMinBudgetLevelToRun(base::TimeTicks now,
127 base::TimeDelta min_budget_level_to_run);
128
129 // Throttle task queues from this time budget pool if tasks are running
130 // for more than |cpu_percentage| per cent of wall time.
131 // This function does not affect internal time budget level.
132 void SetTimeBudgetRecoveryRate(base::TimeTicks now, double cpu_percentage);
133
134 // Increase budget level by given value. This function DOES NOT unblock
135 // queues even if they are allowed to run with increased budget level.
136 void GrantAdditionalBudget(base::TimeTicks now, base::TimeDelta budget_level);
137
138 // Set callback which will be called every time when this budget pool
139 // is throttled. Throttling duration (time until the queue is allowed
140 // to run again) is passed as a parameter to callback.
141 void SetReportingCallback(
142 base::Callback<void(base::TimeDelta)> reporting_callback);
143
144 // BudgetPool implementation:
145 void RecordTaskRunTime(base::TimeTicks start_time,
146 base::TimeTicks end_time) final;
147 bool HasEnoughBudgetToRun(base::TimeTicks now) final;
148 base::TimeTicks GetNextAllowedRunTime() final;
149 void AsValueInto(base::trace_event::TracedValue* state,
150 base::TimeTicks now) const final;
151 105
152 private: 106 private:
153 FRIEND_TEST_ALL_PREFIXES(TaskQueueThrottlerTest, CPUTimeBudgetPool); 107 void DissociateQueue(TaskQueue* queue);
154
155 // Advances |last_checkpoint_| to |now| if needed and recalculates
156 // budget level.
157 void Advance(base::TimeTicks now);
158
159 // Increase |current_budget_level_| to satisfy max throttling duration
160 // condition if necessary.
161 // Decrease |current_budget_level_| to satisfy max budget level
162 // condition if necessary.
163 void EnforceBudgetLevelRestrictions();
164
165 // Max budget level which we can accrue.
166 // Tasks will be allowed to run for this time before being throttled
167 // after a very long period of inactivity.
168 base::Optional<base::TimeDelta> max_budget_level_;
169 // Max throttling delay places a lower limit on time budget level,
170 // ensuring that one long task does not cause extremely long throttling.
171 // Note that this is not a guarantee that every task will run
172 // after desired run time + max throttling duration, but a guarantee
173 // that at least one task will be run every max_throttling_delay.
174 base::Optional<base::TimeDelta> max_throttling_delay_;
175 // See CPUTimeBudgetPool::SetMinBudgetLevelToRun.
176 base::TimeDelta min_budget_level_to_run_;
177
178 base::TimeDelta current_budget_level_;
179 base::TimeTicks last_checkpoint_;
180 double cpu_percentage_;
181
182 base::Callback<void(base::TimeDelta)> reporting_callback_;
183
184 DISALLOW_COPY_AND_ASSIGN(CPUTimeBudgetPool);
185 }; 108 };
186 109
187 } // namespace scheduler 110 } // namespace scheduler
188 } // namespace blink 111 } // namespace blink
189 112
190 #endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_RENDERER_BUDGET_POOL_H_ 113 #endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_RENDERER_BUDGET_POOL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698