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

Side by Side Diff: base/task_scheduler/scheduler_worker_pool_impl.h

Issue 2801673002: Separate the create and start phases in SchedulerWorkerPoolImpl. (Closed)
Patch Set: CR-robliao-9 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 BASE_TASK_SCHEDULER_SCHEDULER_WORKER_POOL_IMPL_H_ 5 #ifndef BASE_TASK_SCHEDULER_SCHEDULER_WORKER_POOL_IMPL_H_
6 #define BASE_TASK_SCHEDULER_SCHEDULER_WORKER_POOL_IMPL_H_ 6 #define BASE_TASK_SCHEDULER_SCHEDULER_WORKER_POOL_IMPL_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <memory> 10 #include <memory>
(...skipping 27 matching lines...) Expand all
38 class DelayedTaskManager; 38 class DelayedTaskManager;
39 class TaskTracker; 39 class TaskTracker;
40 40
41 // A pool of workers that run Tasks. This class is thread-safe. 41 // A pool of workers that run Tasks. This class is thread-safe.
42 class BASE_EXPORT SchedulerWorkerPoolImpl : public SchedulerWorkerPool { 42 class BASE_EXPORT SchedulerWorkerPoolImpl : public SchedulerWorkerPool {
43 public: 43 public:
44 // Callback invoked when a Sequence isn't empty after a worker pops a Task 44 // Callback invoked when a Sequence isn't empty after a worker pops a Task
45 // from it. 45 // from it.
46 using ReEnqueueSequenceCallback = Callback<void(scoped_refptr<Sequence>)>; 46 using ReEnqueueSequenceCallback = Callback<void(scoped_refptr<Sequence>)>;
47 47
48 // Constructs a pool without workers. Tasks can be posted to the pool, but
49 // they won't run until workers are created. To create workers and start
50 // running tasks, call Start().
51 //
52 // |name| is used to label the pool's threads ("TaskScheduler" + |name| +
53 // index) and histograms ("TaskScheduler." + histogram name + "." + |name| +
54 // extra suffixes). |priority_hint| is the preferred thread priority; the
55 // actual thread priority depends on shutdown state and platform capabilities.
56 // |re_enqueue_sequence_callback| is invoked when a Sequence isn't empty after
57 // a worker pops a Task from it. |task_tracker| keeps track of tasks.
58 // |delayed_task_manager| handles tasks posted with a delay.
59 SchedulerWorkerPoolImpl(
60 const std::string& name,
61 ThreadPriority priority_hint,
62 ReEnqueueSequenceCallback re_enqueue_sequence_callback,
63 TaskTracker* task_tracker,
64 DelayedTaskManager* delayed_task_manager);
65
66 // Creates workers following the |params| specification, allowing existing and
67 // future tasks to run. Can only be called once. CHECKs on failure.
68 void Start(const SchedulerWorkerPoolParams& params);
69
48 // Destroying a SchedulerWorkerPoolImpl returned by Create() is not allowed in 70 // Destroying a SchedulerWorkerPoolImpl returned by Create() is not allowed in
49 // production; it is always leaked. In tests, it can only be destroyed after 71 // production; it is always leaked. In tests, it can only be destroyed after
50 // JoinForTesting() has returned. 72 // JoinForTesting() has returned.
51 ~SchedulerWorkerPoolImpl() override; 73 ~SchedulerWorkerPoolImpl() override;
52 74
53 // Creates a SchedulerWorkerPoolImpl following the |worker_pool_params|
54 // specification. |re_enqueue_sequence_callback| will be invoked after a
55 // worker of this worker pool tries to run a Task. |task_tracker| is used to
56 // handle shutdown behavior of Tasks. |delayed_task_manager| handles Tasks
57 // posted with a delay. Returns nullptr on failure to create a worker pool
58 // with at least one thread.
59 static std::unique_ptr<SchedulerWorkerPoolImpl> Create(
60 const SchedulerWorkerPoolParams& params,
61 const ReEnqueueSequenceCallback& re_enqueue_sequence_callback,
62 TaskTracker* task_tracker,
63 DelayedTaskManager* delayed_task_manager);
64
65 // SchedulerWorkerPool: 75 // SchedulerWorkerPool:
66 scoped_refptr<TaskRunner> CreateTaskRunnerWithTraits( 76 scoped_refptr<TaskRunner> CreateTaskRunnerWithTraits(
67 const TaskTraits& traits) override; 77 const TaskTraits& traits) override;
68 scoped_refptr<SequencedTaskRunner> CreateSequencedTaskRunnerWithTraits( 78 scoped_refptr<SequencedTaskRunner> CreateSequencedTaskRunnerWithTraits(
69 const TaskTraits& traits) override; 79 const TaskTraits& traits) override;
70 void ReEnqueueSequence(scoped_refptr<Sequence> sequence, 80 void ReEnqueueSequence(scoped_refptr<Sequence> sequence,
71 const SequenceSortKey& sequence_sort_key) override; 81 const SequenceSortKey& sequence_sort_key) override;
72 bool PostTaskWithSequence(std::unique_ptr<Task> task, 82 bool PostTaskWithSequence(std::unique_ptr<Task> task,
73 scoped_refptr<Sequence> sequence) override; 83 scoped_refptr<Sequence> sequence) override;
74 void PostTaskWithSequenceNow(std::unique_ptr<Task> task, 84 void PostTaskWithSequenceNow(std::unique_ptr<Task> task,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 // change if workers are woken up or detached during this call. 116 // change if workers are woken up or detached during this call.
107 size_t NumberOfAliveWorkersForTesting(); 117 size_t NumberOfAliveWorkersForTesting();
108 118
109 private: 119 private:
110 class SchedulerWorkerDelegateImpl; 120 class SchedulerWorkerDelegateImpl;
111 121
112 SchedulerWorkerPoolImpl(const SchedulerWorkerPoolParams& params, 122 SchedulerWorkerPoolImpl(const SchedulerWorkerPoolParams& params,
113 TaskTracker* task_tracker, 123 TaskTracker* task_tracker,
114 DelayedTaskManager* delayed_task_manager); 124 DelayedTaskManager* delayed_task_manager);
115 125
116 bool Initialize(
117 const SchedulerWorkerPoolParams& params,
118 const ReEnqueueSequenceCallback& re_enqueue_sequence_callback);
119
120 // Wakes up the last worker from this worker pool to go idle, if any. 126 // Wakes up the last worker from this worker pool to go idle, if any.
121 void WakeUpOneWorker(); 127 void WakeUpOneWorker();
122 128
123 // Adds |worker| to |idle_workers_stack_|. 129 // Adds |worker| to |idle_workers_stack_|.
124 void AddToIdleWorkersStack(SchedulerWorker* worker); 130 void AddToIdleWorkersStack(SchedulerWorker* worker);
125 131
126 // Peeks from |idle_workers_stack_|. 132 // Peeks from |idle_workers_stack_|.
127 const SchedulerWorker* PeekAtIdleWorkersStack() const; 133 const SchedulerWorker* PeekAtIdleWorkersStack() const;
128 134
129 // Removes |worker| from |idle_workers_stack_|. 135 // Removes |worker| from |idle_workers_stack_|.
130 void RemoveFromIdleWorkersStack(SchedulerWorker* worker); 136 void RemoveFromIdleWorkersStack(SchedulerWorker* worker);
131 137
132 // Returns true if worker thread detachment is permitted. 138 // Returns true if worker thread detachment is permitted.
133 bool CanWorkerDetachForTesting(); 139 bool CanWorkerDetachForTesting();
134 140
135 // The name of this worker pool, used to label its worker threads.
136 const std::string name_; 141 const std::string name_;
137 142 const ThreadPriority priority_hint_;
138 // All worker owned by this worker pool. Only modified during initialization 143 const ReEnqueueSequenceCallback re_enqueue_sequence_callback_;
139 // of the worker pool.
140 std::vector<scoped_refptr<SchedulerWorker>> workers_;
141 144
142 // PriorityQueue from which all threads of this worker pool get work. 145 // PriorityQueue from which all threads of this worker pool get work.
143 PriorityQueue shared_priority_queue_; 146 PriorityQueue shared_priority_queue_;
144 147
145 // Suggested reclaim time for workers. 148 // All workers owned by this worker pool. Initialized by Start() within the
146 const TimeDelta suggested_reclaim_time_; 149 // scope of |idle_workers_stack_lock_|. Never modified afterwards (i.e. can be
150 // read without synchronization once |workers_created_.IsSignaled()|).
151 std::vector<scoped_refptr<SchedulerWorker>> workers_;
147 152
148 // Synchronizes access to |idle_workers_stack_| and 153 // Suggested reclaim time for workers. Initialized by Start(). Never modified
149 // |idle_workers_stack_cv_for_testing_|. Has |shared_priority_queue_|'s 154 // afterwards (i.e. can be read without synchronization once
150 // lock as its predecessor so that a worker can be pushed to 155 // |workers_created_.IsSignaled()|).
151 // |idle_workers_stack_| within the scope of a Transaction (more 156 TimeDelta suggested_reclaim_time_;
157
158 // Synchronizes access to |idle_workers_stack_|,
159 // |idle_workers_stack_cv_for_testing_| and |num_wake_ups_before_start_|. Has
160 // |shared_priority_queue_|'s lock as its predecessor so that a worker can be
161 // pushed to |idle_workers_stack_| within the scope of a Transaction (more
152 // details in GetWork()). 162 // details in GetWork()).
153 mutable SchedulerLock idle_workers_stack_lock_; 163 mutable SchedulerLock idle_workers_stack_lock_;
154 164
155 // Stack of idle workers. Initially, all workers are on this stack. A worker 165 // Stack of idle workers. Initially, all workers are on this stack. A worker
156 // is removed from the stack before its WakeUp() function is called and when 166 // is removed from the stack before its WakeUp() function is called and when
157 // it receives work from GetWork() (a worker calls GetWork() when its sleep 167 // it receives work from GetWork() (a worker calls GetWork() when its sleep
158 // timeout expires, even if its WakeUp() method hasn't been called). A worker 168 // timeout expires, even if its WakeUp() method hasn't been called). A worker
159 // is pushed on this stack when it receives nullptr from GetWork(). 169 // is pushed on this stack when it receives nullptr from GetWork().
160 SchedulerWorkerStack idle_workers_stack_; 170 SchedulerWorkerStack idle_workers_stack_;
161 171
162 // Signaled when all workers become idle. 172 // Signaled when all workers become idle.
163 std::unique_ptr<ConditionVariable> idle_workers_stack_cv_for_testing_; 173 std::unique_ptr<ConditionVariable> idle_workers_stack_cv_for_testing_;
164 174
175 // Number of wake ups that occurred before Start().
176 int num_wake_ups_before_start_ = 0;
177
165 // Signaled once JoinForTesting() has returned. 178 // Signaled once JoinForTesting() has returned.
166 WaitableEvent join_for_testing_returned_; 179 WaitableEvent join_for_testing_returned_;
167 180
168 // Indicates to the delegates that workers are not permitted to detach their 181 // Indicates to the delegates that workers are not permitted to detach their
169 // threads. 182 // threads.
170 AtomicFlag worker_detachment_disallowed_; 183 AtomicFlag worker_detachment_disallowed_;
171 184
172 #if DCHECK_IS_ON() 185 #if DCHECK_IS_ON()
173 // Signaled when all workers have been created. 186 // Signaled when all workers have been created.
174 WaitableEvent workers_created_; 187 mutable WaitableEvent workers_created_;
175 #endif 188 #endif
176 189
177 // TaskScheduler.DetachDuration.[worker pool name] histogram. Intentionally 190 // TaskScheduler.DetachDuration.[worker pool name] histogram. Intentionally
178 // leaked. 191 // leaked.
179 HistogramBase* const detach_duration_histogram_; 192 HistogramBase* const detach_duration_histogram_;
180 193
181 // TaskScheduler.NumTasksBeforeDetach.[worker pool name] histogram. 194 // TaskScheduler.NumTasksBeforeDetach.[worker pool name] histogram.
182 // Intentionally leaked. 195 // Intentionally leaked.
183 HistogramBase* const num_tasks_before_detach_histogram_; 196 HistogramBase* const num_tasks_before_detach_histogram_;
184 197
185 // TaskScheduler.NumTasksBetweenWaits.[worker pool name] histogram. 198 // TaskScheduler.NumTasksBetweenWaits.[worker pool name] histogram.
186 // Intentionally leaked. 199 // Intentionally leaked.
187 HistogramBase* const num_tasks_between_waits_histogram_; 200 HistogramBase* const num_tasks_between_waits_histogram_;
188 201
189 TaskTracker* const task_tracker_; 202 TaskTracker* const task_tracker_;
190 DelayedTaskManager* const delayed_task_manager_; 203 DelayedTaskManager* const delayed_task_manager_;
191 204
192 DISALLOW_COPY_AND_ASSIGN(SchedulerWorkerPoolImpl); 205 DISALLOW_COPY_AND_ASSIGN(SchedulerWorkerPoolImpl);
193 }; 206 };
194 207
195 } // namespace internal 208 } // namespace internal
196 } // namespace base 209 } // namespace base
197 210
198 #endif // BASE_TASK_SCHEDULER_SCHEDULER_WORKER_POOL_IMPL_H_ 211 #endif // BASE_TASK_SCHEDULER_SCHEDULER_WORKER_POOL_IMPL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698