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

Side by Side Diff: components/scheduler/base/task_queue_manager.h

Issue 1432263002: (reland) Adds TimeDomains to the TaskQueueManager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix thread_hop_task DCHECK Created 5 years, 1 month 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 #ifndef CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_ 5 #ifndef CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_
6 #define CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_ 6 #define CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_
7 7
8 #include <map> 8 #include <map>
9 9
10 #include "base/atomic_sequence_num.h" 10 #include "base/atomic_sequence_num.h"
(...skipping 12 matching lines...) Expand all
23 class TickClock; 23 class TickClock;
24 24
25 namespace trace_event { 25 namespace trace_event {
26 class ConvertableToTraceFormat; 26 class ConvertableToTraceFormat;
27 class TracedValue; 27 class TracedValue;
28 } // namespace trace_event 28 } // namespace trace_event
29 } // namespace base 29 } // namespace base
30 30
31 namespace scheduler { 31 namespace scheduler {
32 namespace internal { 32 namespace internal {
33 class LazyNow;
34 class TaskQueueImpl; 33 class TaskQueueImpl;
35 } // namespace internal 34 } // namespace internal
36 35
36 class LazyNow;
37 class RealTimeDomain;
38 class TimeDomain;
37 class TaskQueueManagerDelegate; 39 class TaskQueueManagerDelegate;
38 40
39 // The task queue manager provides N task queues and a selector interface for 41 // The task queue manager provides N task queues and a selector interface for
40 // choosing which task queue to service next. Each task queue consists of two 42 // choosing which task queue to service next. Each task queue consists of two
41 // sub queues: 43 // sub queues:
42 // 44 //
43 // 1. Incoming task queue. Tasks that are posted get immediately appended here. 45 // 1. Incoming task queue. Tasks that are posted get immediately appended here.
44 // When a task is appended into an empty incoming queue, the task manager 46 // When a task is appended into an empty incoming queue, the task manager
45 // work function (DoWork) is scheduled to run on the main task runner. 47 // work function (DoWork) is scheduled to run on the main task runner.
46 // 48 //
47 // 2. Work queue. If a work queue is empty when DoWork() is entered, tasks from 49 // 2. Work queue. If a work queue is empty when DoWork() is entered, tasks from
48 // the incoming task queue (if any) are moved here. The work queues are 50 // the incoming task queue (if any) are moved here. The work queues are
49 // registered with the selector as input to the scheduling decision. 51 // registered with the selector as input to the scheduling decision.
50 // 52 //
51 class SCHEDULER_EXPORT TaskQueueManager 53 class SCHEDULER_EXPORT TaskQueueManager
52 : public internal::TaskQueueSelector::Observer { 54 : public internal::TaskQueueSelector::Observer {
53 public: 55 public:
54 // Create a task queue manager where |delegate| identifies the thread 56 // Create a task queue manager where |delegate| identifies the thread
55 // on which where the tasks are eventually run. Category strings must have 57 // on which where the tasks are eventually run. Category strings must have
56 // application lifetime (statics or literals). They may not include " chars. 58 // application lifetime (statics or literals). They may not include " chars.
57 TaskQueueManager(scoped_refptr<TaskQueueManagerDelegate> delegate, 59 TaskQueueManager(scoped_refptr<TaskQueueManagerDelegate> delegate,
58 const char* tracing_category, 60 const char* tracing_category,
59 const char* disabled_by_default_tracing_category, 61 const char* disabled_by_default_tracing_category,
60 const char* disabled_by_default_verbose_tracing_category); 62 const char* disabled_by_default_verbose_tracing_category);
61 ~TaskQueueManager() override; 63 ~TaskQueueManager() override;
62 64
63 // Returns the time of the next pending delayed task in any queue. Ignores
64 // any delayed tasks whose delay has expired. Returns a null TimeTicks object
65 // if no tasks are pending. NOTE this is somewhat expensive since every queue
66 // will get locked.
67 base::TimeTicks NextPendingDelayedTaskRunTime();
68
69 // Set the number of tasks executed in a single invocation of the task queue 65 // Set the number of tasks executed in a single invocation of the task queue
70 // manager. Increasing the batch size can reduce the overhead of yielding 66 // manager. Increasing the batch size can reduce the overhead of yielding
71 // back to the main message loop -- at the cost of potentially delaying other 67 // back to the main message loop -- at the cost of potentially delaying other
72 // tasks posted to the main loop. The batch size is 1 by default. 68 // tasks posted to the main loop. The batch size is 1 by default.
73 void SetWorkBatchSize(int work_batch_size); 69 void SetWorkBatchSize(int work_batch_size);
74 70
75 // These functions can only be called on the same thread that the task queue 71 // These functions can only be called on the same thread that the task queue
76 // manager executes its tasks on. 72 // manager executes its tasks on.
77 void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer); 73 void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer);
78 void RemoveTaskObserver(base::MessageLoop::TaskObserver* task_observer); 74 void RemoveTaskObserver(base::MessageLoop::TaskObserver* task_observer);
(...skipping 17 matching lines...) Expand all
96 }; 92 };
97 93
98 // Called once to set the Observer. This function is called on the main 94 // Called once to set the Observer. This function is called on the main
99 // thread. If |observer| is null, then no callbacks will occur. 95 // thread. If |observer| is null, then no callbacks will occur.
100 // Note |observer| is expected to outlive the SchedulerHelper. 96 // Note |observer| is expected to outlive the SchedulerHelper.
101 void SetObserver(Observer* observer); 97 void SetObserver(Observer* observer);
102 98
103 // Returns the delegate used by the TaskQueueManager. 99 // Returns the delegate used by the TaskQueueManager.
104 const scoped_refptr<TaskQueueManagerDelegate>& delegate() const; 100 const scoped_refptr<TaskQueueManagerDelegate>& delegate() const;
105 101
102 // Time domains must be registered for the task queues to get updated.
103 void RegisterTimeDomain(const scoped_refptr<TimeDomain>& time_domain);
104 void UnregisterTimeDomain(const scoped_refptr<TimeDomain>& time_domain);
105
106 const scoped_refptr<RealTimeDomain>& real_time_domain() const {
107 return real_time_domain_;
108 }
109
106 private: 110 private:
107 friend class internal::LazyNow; 111 friend class LazyNow;
108 friend class internal::TaskQueueImpl; 112 friend class internal::TaskQueueImpl;
109 friend class TaskQueueManagerTest; 113 friend class TaskQueueManagerTest;
110 114
111 class DeletionSentinel : public base::RefCounted<DeletionSentinel> { 115 class DeletionSentinel : public base::RefCounted<DeletionSentinel> {
112 private: 116 private:
113 friend class base::RefCounted<DeletionSentinel>; 117 friend class base::RefCounted<DeletionSentinel>;
114 ~DeletionSentinel() {} 118 ~DeletionSentinel() {}
115 }; 119 };
116 120
117 // Unregisters a TaskQueue previously created by |NewTaskQueue()|. 121 // Unregisters a TaskQueue previously created by |NewTaskQueue()|.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 internal::TaskQueueImpl* queue, 163 internal::TaskQueueImpl* queue,
160 internal::TaskQueueImpl::Task* out_previous_task); 164 internal::TaskQueueImpl::Task* out_previous_task);
161 165
162 bool RunsTasksOnCurrentThread() const; 166 bool RunsTasksOnCurrentThread() const;
163 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, 167 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
164 const base::Closure& task, 168 const base::Closure& task,
165 base::TimeDelta delay); 169 base::TimeDelta delay);
166 170
167 int GetNextSequenceNumber(); 171 int GetNextSequenceNumber();
168 172
173 bool TryAdvanceTimeDomains();
174
169 scoped_refptr<base::trace_event::ConvertableToTraceFormat> 175 scoped_refptr<base::trace_event::ConvertableToTraceFormat>
170 AsValueWithSelectorResult(bool should_run, 176 AsValueWithSelectorResult(bool should_run,
171 internal::TaskQueueImpl* selected_queue) const; 177 internal::TaskQueueImpl* selected_queue) const;
172 178
173 // Causes DoWork to start calling UpdateWorkQueue for |queue|. Can be called 179 std::set<scoped_refptr<TimeDomain>> time_domains_;
174 // from any thread. 180 scoped_refptr<RealTimeDomain> real_time_domain_;
175 void RegisterAsUpdatableTaskQueue(internal::TaskQueueImpl* queue);
176
177 // Prevents DoWork from calling UpdateWorkQueue for |queue|. Must be called
178 // from the thread the TaskQueueManager was created on.
179 void UnregisterAsUpdatableTaskQueue(internal::TaskQueueImpl* queue);
180
181 // Schedule a call to DoWork at |delayed_run_time| which indirectly calls
182 // TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue for |queue|.
183 // Can be called from any thread.
184 void ScheduleDelayedWork(internal::TaskQueueImpl* queue,
185 base::TimeTicks delayed_run_time,
186 internal::LazyNow* lazy_now);
187
188 // Function calling ScheduleDelayedWork that's suitable for use in base::Bind.
189 void ScheduleDelayedWorkTask(scoped_refptr<internal::TaskQueueImpl> queue,
190 base::TimeTicks delayed_run_time);
191
192 // Call TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue for each
193 // registered queue for which the delay has elapsed.
194 void WakeupReadyDelayedQueues(internal::LazyNow* lazy_now);
195
196 void MoveNewlyUpdatableQueuesIntoUpdatableQueueSet();
197 181
198 std::set<scoped_refptr<internal::TaskQueueImpl>> queues_; 182 std::set<scoped_refptr<internal::TaskQueueImpl>> queues_;
199 183
200 // We have to be careful when deleting a queue because some of the code uses 184 // We have to be careful when deleting a queue because some of the code uses
201 // raw pointers and doesn't expect the rug to be pulled out from underneath. 185 // raw pointers and doesn't expect the rug to be pulled out from underneath.
202 std::set<scoped_refptr<internal::TaskQueueImpl>> queues_to_delete_; 186 std::set<scoped_refptr<internal::TaskQueueImpl>> queues_to_delete_;
203 187
204 // This lock guards only |newly_updatable_|. It's not expected to be heavily
205 // contended.
206 base::Lock newly_updatable_lock_;
207 std::vector<internal::TaskQueueImpl*> newly_updatable_;
208
209 // Set of task queues with avaliable work on the incoming queue. This should
210 // only be accessed from the main thread.
211 std::set<internal::TaskQueueImpl*> updatable_queue_set_;
212
213 typedef std::multimap<base::TimeTicks, internal::TaskQueueImpl*>
214 DelayedWakeupMultimap;
215
216 DelayedWakeupMultimap delayed_wakeup_multimap_;
217 188
218 base::AtomicSequenceNumber task_sequence_num_; 189 base::AtomicSequenceNumber task_sequence_num_;
219 base::debug::TaskAnnotator task_annotator_; 190 base::debug::TaskAnnotator task_annotator_;
220 191
221 base::ThreadChecker main_thread_checker_; 192 base::ThreadChecker main_thread_checker_;
222 scoped_refptr<TaskQueueManagerDelegate> delegate_; 193 scoped_refptr<TaskQueueManagerDelegate> delegate_;
223 internal::TaskQueueSelector selector_; 194 internal::TaskQueueSelector selector_;
224 195
225 base::Closure decrement_pending_and_do_work_closure_; 196 base::Closure decrement_pending_and_do_work_closure_;
226 base::Closure do_work_closure_; 197 base::Closure do_work_closure_;
227 198
228 bool task_was_run_on_quiescence_monitored_queue_; 199 bool task_was_run_on_quiescence_monitored_queue_;
229 200
230 // The pending_dowork_count_ is only tracked on the main thread since that's 201 // The pending_dowork_count_ is only tracked on the main thread since that's
231 // where re-entrant problems happen. 202 // where re-entrant problems happen.
232 int pending_dowork_count_; 203 int pending_dowork_count_;
233 204
234 int work_batch_size_; 205 int work_batch_size_;
235 206
236 base::ObserverList<base::MessageLoop::TaskObserver> task_observers_; 207 base::ObserverList<base::MessageLoop::TaskObserver> task_observers_;
237 208
238 const char* tracing_category_; 209 const char* tracing_category_;
239 const char* disabled_by_default_tracing_category_; 210 const char* disabled_by_default_tracing_category_;
240 const char* disabled_by_default_verbose_tracing_category_; 211 const char* disabled_by_default_verbose_tracing_category_;
241 212
242 Observer* observer_; // NOT OWNED 213 Observer* observer_; // NOT OWNED
243 scoped_refptr<DeletionSentinel> deletion_sentinel_; 214 scoped_refptr<DeletionSentinel> deletion_sentinel_;
215 scoped_refptr<TimeDomain> time_domain_;
244 base::WeakPtrFactory<TaskQueueManager> weak_factory_; 216 base::WeakPtrFactory<TaskQueueManager> weak_factory_;
245 217
246 DISALLOW_COPY_AND_ASSIGN(TaskQueueManager); 218 DISALLOW_COPY_AND_ASSIGN(TaskQueueManager);
247 }; 219 };
248 220
249 } // namespace scheduler 221 } // namespace scheduler
250 222
251 #endif // CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_ 223 #endif // CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_
OLDNEW
« no previous file with comments | « components/scheduler/base/task_queue_impl.cc ('k') | components/scheduler/base/task_queue_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698