blob: b4cfc49ac55fb462199162dc7cea249df78b3bb2 [file] [log] [blame]
fdoray4151cea2016-05-06 15:39:141// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Gabriel Charette52fa3ae2019-04-15 21:44:375#ifndef BASE_TASK_THREAD_POOL_THREAD_POOL_IMPL_H_
6#define BASE_TASK_THREAD_POOL_THREAD_POOL_IMPL_H_
fdoray4151cea2016-05-06 15:39:147
8#include <memory>
fdoray51da6a832016-06-28 22:51:089#include <vector>
fdoray4151cea2016-05-06 15:39:1410
11#include "base/base_export.h"
fdoray51da6a832016-06-28 22:51:0812#include "base/callback.h"
fdoray4151cea2016-05-06 15:39:1413#include "base/logging.h"
14#include "base/macros.h"
fdorayb199f1be2017-05-29 23:00:0315#include "base/memory/ptr_util.h"
fdoray4151cea2016-05-06 15:39:1416#include "base/memory/ref_counted.h"
Gabriel Charette1b3b02a2019-07-11 02:58:1617#include "base/optional.h"
Etienne Pierre-dorayefad3ec2019-04-17 17:07:0518#include "base/sequence_checker.h"
fdoray5d16e802017-04-19 14:45:1619#include "base/strings/string_piece.h"
fdorayef191122016-07-25 14:43:1720#include "base/synchronization/atomic_flag.h"
Gabriel Charette04b138f2018-08-06 00:03:2221#include "base/task/single_thread_task_runner_thread_mode.h"
Gabriel Charette43fd3702019-05-29 16:36:5122#include "base/task/task_executor.h"
Gabriel Charette04b138f2018-08-06 00:03:2223#include "base/task/task_traits.h"
Gabriel Charette52fa3ae2019-04-15 21:44:3724#include "base/task/thread_pool/delayed_task_manager.h"
25#include "base/task/thread_pool/environment_config.h"
Gabriel Charette3e2898f2019-05-01 14:55:0126#include "base/task/thread_pool/pooled_single_thread_task_runner_manager.h"
27#include "base/task/thread_pool/pooled_task_runner_delegate.h"
Etienne Pierre-dorayabfecf72019-05-09 20:41:4828#include "base/task/thread_pool/task_source.h"
Gabriel Charette52fa3ae2019-04-15 21:44:3729#include "base/task/thread_pool/task_tracker.h"
Gabriel Charette3e2898f2019-05-01 14:55:0130#include "base/task/thread_pool/thread_group.h"
31#include "base/task/thread_pool/thread_group_impl.h"
Gabriel Charetteeadf58862019-08-29 05:20:2732#include "base/task/thread_pool/thread_pool_instance.h"
Jesse McKenna00074542018-11-30 02:08:0933#include "base/updateable_sequenced_task_runner.h"
robliao75dd50b2017-03-29 17:11:1734#include "build/build_config.h"
fdoray4151cea2016-05-06 15:39:1435
fdoray2cc05d12017-04-19 14:06:5436#if defined(OS_POSIX) && !defined(OS_NACL_SFI)
Gabriel Charette52fa3ae2019-04-15 21:44:3737#include "base/task/thread_pool/task_tracker_posix.h"
fdoray2cc05d12017-04-19 14:06:5438#endif
39
Robert Liaodd04109f2017-06-27 22:05:3740#if defined(OS_WIN)
41#include "base/win/com_init_check_hook.h"
42#endif
43
fdoray4151cea2016-05-06 15:39:1444namespace base {
robliao5a363692016-08-01 22:29:0545
Gabriel Charette6084a132018-05-04 19:05:5946class Thread;
robliao5a363692016-08-01 22:29:0547
fdoray4151cea2016-05-06 15:39:1448namespace internal {
49
Gabriel Charette43fd3702019-05-29 16:36:5150// Default ThreadPoolInstance implementation. This class is thread-safe.
51class BASE_EXPORT ThreadPoolImpl : public ThreadPoolInstance,
52 public TaskExecutor,
Gabriel Charette3e2898f2019-05-01 14:55:0153 public ThreadGroup::Delegate,
54 public PooledTaskRunnerDelegate {
fdoray4151cea2016-05-06 15:39:1455 public:
fdorayb199f1be2017-05-29 23:00:0356 using TaskTrackerImpl =
57#if defined(OS_POSIX) && !defined(OS_NACL_SFI)
58 TaskTrackerPosix;
59#else
60 TaskTracker;
61#endif
62
Francois Doray098076d2019-10-25 21:04:5763 // Creates a ThreadPoolImpl with a production TaskTracker. |histogram_label|
64 // is used to label histograms. No histograms are recorded if it is empty.
Gabriel Charette52fa3ae2019-04-15 21:44:3765 explicit ThreadPoolImpl(StringPiece histogram_label);
Gabriel Charette19621cd2018-01-18 16:48:5966
Gabriel Charette996000b2019-08-14 23:41:1967 // For testing only. Creates a ThreadPoolImpl with a custom TaskTracker.
Gabriel Charette52fa3ae2019-04-15 21:44:3768 ThreadPoolImpl(StringPiece histogram_label,
Gabriel Charette996000b2019-08-14 23:41:1969 std::unique_ptr<TaskTrackerImpl> task_tracker);
Gabriel Charette19621cd2018-01-18 16:48:5970
Gabriel Charette52fa3ae2019-04-15 21:44:3771 ~ThreadPoolImpl() override;
fdoray4151cea2016-05-06 15:39:1472
Gabriel Charette43fd3702019-05-29 16:36:5173 // ThreadPoolInstance:
74 void Start(const ThreadPoolInstance::InitParams& init_params,
Gabriel Charette3e2898f2019-05-01 14:55:0175 WorkerThreadObserver* worker_thread_observer) override;
Eric Secklercdd866d2018-08-21 10:49:5476 int GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated(
77 const TaskTraits& traits) const override;
78 void Shutdown() override;
79 void FlushForTesting() override;
80 void FlushAsyncForTesting(OnceClosure flush_callback) override;
81 void JoinForTesting() override;
Francois Dorayc92dedd22019-11-01 13:48:5482 void BeginFence() override;
83 void EndFence() override;
84 void BeginBestEffortFence() override;
85 void EndBestEffortFence() override;
Eric Secklercdd866d2018-08-21 10:49:5486
87 // TaskExecutor:
Sami Kyostila675d7dc92019-06-05 10:33:0888 bool PostDelayedTask(const Location& from_here,
89 const TaskTraits& traits,
90 OnceClosure task,
91 TimeDelta delay) override;
92 scoped_refptr<TaskRunner> CreateTaskRunner(const TaskTraits& traits) override;
93 scoped_refptr<SequencedTaskRunner> CreateSequencedTaskRunner(
fdoraye72adfa12016-11-02 14:35:2694 const TaskTraits& traits) override;
Sami Kyostila675d7dc92019-06-05 10:33:0895 scoped_refptr<SingleThreadTaskRunner> CreateSingleThreadTaskRunner(
robliao94520d72017-05-12 12:43:3596 const TaskTraits& traits,
97 SingleThreadTaskRunnerThreadMode thread_mode) override;
robliao75dd50b2017-03-29 17:11:1798#if defined(OS_WIN)
Sami Kyostila675d7dc92019-06-05 10:33:0899 scoped_refptr<SingleThreadTaskRunner> CreateCOMSTATaskRunner(
robliao94520d72017-05-12 12:43:35100 const TaskTraits& traits,
101 SingleThreadTaskRunnerThreadMode thread_mode) override;
robliao75dd50b2017-03-29 17:11:17102#endif // defined(OS_WIN)
Alex Clarke0dd499562019-10-18 19:45:09103 const scoped_refptr<SequencedTaskRunner>& GetContinuationTaskRunner()
104 override;
Jesse McKenna00074542018-11-30 02:08:09105 scoped_refptr<UpdateableSequencedTaskRunner>
Sami Kyostila675d7dc92019-06-05 10:33:08106 CreateUpdateableSequencedTaskRunner(const TaskTraits& traits);
fdoray4151cea2016-05-06 15:39:14107
Etienne Pierre-doray38cb18ba2019-08-08 19:50:37108 // PooledTaskRunnerDelegate:
109 bool EnqueueJobTaskSource(scoped_refptr<JobTaskSource> task_source) override;
Etienne Pierre-doraye62a1382019-10-03 17:08:52110 void RemoveJobTaskSource(scoped_refptr<JobTaskSource> task_source) override;
Etienne Pierre-dorayac3680742019-08-29 17:43:17111 void UpdatePriority(scoped_refptr<TaskSource> task_source,
112 TaskPriority priority) override;
Etienne Pierre-doray38cb18ba2019-08-08 19:50:37113
Gabriel Charette1b3b02a2019-07-11 02:58:16114 // Returns the TimeTicks of the next task scheduled on ThreadPool (Now() if
115 // immediate, nullopt if none). This is thread-safe, i.e., it's safe if tasks
116 // are being posted in parallel with this call but such a situation obviously
117 // results in a race as to whether this call will see the new tasks in time.
118 Optional<TimeTicks> NextScheduledRunTimeForTesting() const;
119
120 // Forces ripe delayed tasks to be posted (e.g. when time is mocked and
121 // advances faster than the real-time delay on ServiceThread).
122 void ProcessRipeDelayedTasksForTesting();
123
fdoray4151cea2016-05-06 15:39:14124 private:
Francois Dorayc92dedd22019-11-01 13:48:54125 // Invoked after |num_fences_| or |num_best_effort_fences_| is updated. Sets
126 // the CanRunPolicy in TaskTracker and wakes up workers as appropriate.
Etienne Pierre-dorayefad3ec2019-04-17 17:07:05127 void UpdateCanRunPolicy();
128
Francois Dorayd9f7e1a2017-08-22 20:20:40129 // Returns |traits|, with priority set to TaskPriority::USER_BLOCKING if
130 // |all_tasks_user_blocking_| is set.
Francois Doray0ca4f565d2019-04-04 12:45:42131 TaskTraits SetUserBlockingPriorityIfNeeded(TaskTraits traits) const;
Francois Dorayd9f7e1a2017-08-22 20:20:40132
Etienne Pierre-doray730a9392018-08-13 22:39:31133 void ReportHeartbeatMetrics() const;
134
Gabriel Charette3e2898f2019-05-01 14:55:01135 const ThreadGroup* GetThreadGroupForTraits(const TaskTraits& traits) const;
Aditya Keerthic174d337e2019-03-05 18:14:16136
Gabriel Charette3e2898f2019-05-01 14:55:01137 // ThreadGroup::Delegate:
138 ThreadGroup* GetThreadGroupForTraits(const TaskTraits& traits) override;
Jesse McKennabcab5d92018-10-22 16:54:21139
Etienne Pierre-dorayabfecf72019-05-09 20:41:48140 // Posts |task| to be executed by the appropriate thread group as part of
141 // |sequence|. This must only be called after |task| has gone through
142 // TaskTracker::WillPostTask() and after |task|'s delayed run time.
143 bool PostTaskWithSequenceNow(Task task, scoped_refptr<Sequence> sequence);
144
Gabriel Charette3e2898f2019-05-01 14:55:01145 // PooledTaskRunnerDelegate:
Jesse McKennacf418062018-10-26 18:05:59146 bool PostTaskWithSequence(Task task,
147 scoped_refptr<Sequence> sequence) override;
Etienne Pierre-dorayd4d2481e2019-08-29 21:07:04148 bool ShouldYield(const TaskSource* task_source) const override;
Jesse McKennacf418062018-10-26 18:05:59149
fdorayb199f1be2017-05-29 23:00:03150 const std::unique_ptr<TaskTrackerImpl> task_tracker_;
Gabriel Charette3fb9e4f2018-05-18 21:34:43151 std::unique_ptr<Thread> service_thread_;
fdoray840441c2017-04-20 13:13:11152 DelayedTaskManager delayed_task_manager_;
Gabriel Charette3e2898f2019-05-01 14:55:01153 PooledSingleThreadTaskRunnerManager single_thread_task_runner_manager_;
fdoraye7e84772017-04-19 13:42:24154
Francois Dorayd9f7e1a2017-08-22 20:20:40155 // Indicates that all tasks are handled as if they had been posted with
156 // TaskPriority::USER_BLOCKING. Since this is set in Start(), it doesn't apply
157 // to tasks posted before Start() or to tasks posted to TaskRunners created
158 // before Start().
Francois Dorayfbfcc6b2017-08-25 19:44:58159 //
160 // TODO(fdoray): Remove after experiment. https://crbug.com/757022
Francois Dorayd9f7e1a2017-08-22 20:20:40161 AtomicFlag all_tasks_user_blocking_;
162
Gabriel Charette60496c72019-05-02 15:54:41163 std::unique_ptr<ThreadGroup> foreground_thread_group_;
164 std::unique_ptr<ThreadGroupImpl> background_thread_group_;
robliao3d93b692016-05-12 18:27:15165
Etienne Pierre-dorayefad3ec2019-04-17 17:07:05166 // Whether this TaskScheduler was started. Access controlled by
167 // |sequence_checker_|.
168 bool started_ = false;
169
François Doray906d5f32019-05-29 21:00:46170 // Whether the --disable-best-effort-tasks switch is preventing execution of
171 // BEST_EFFORT tasks until shutdown.
172 const bool has_disable_best_effort_switch_;
173
Francois Dorayc92dedd22019-11-01 13:48:54174 // Number of fences preventing execution of tasks of any/BEST_EFFORT priority.
175 // Access controlled by |sequence_checker_|.
176 int num_fences_ = 0;
177 int num_best_effort_fences_ = 0;
Etienne Pierre-dorayefad3ec2019-04-17 17:07:05178
fdoray4151cea2016-05-06 15:39:14179#if DCHECK_IS_ON()
fdorayef191122016-07-25 14:43:17180 // Set once JoinForTesting() has returned.
181 AtomicFlag join_for_testing_returned_;
fdoray4151cea2016-05-06 15:39:14182#endif
183
Robert Liaodd04109f2017-06-27 22:05:37184#if defined(OS_WIN) && defined(COM_INIT_CHECK_HOOK_ENABLED)
185 // Provides COM initialization verification for supported builds.
186 base::win::ComInitCheckHook com_init_check_hook_;
187#endif
188
Etienne Pierre-dorayefad3ec2019-04-17 17:07:05189 // Asserts that operations occur in sequence with Start().
190 SEQUENCE_CHECKER(sequence_checker_);
191
Gabriel Charette3e2898f2019-05-01 14:55:01192 TrackedRefFactory<ThreadGroup::Delegate> tracked_ref_factory_;
Jesse McKennabcab5d92018-10-22 16:54:21193
Gabriel Charette52fa3ae2019-04-15 21:44:37194 DISALLOW_COPY_AND_ASSIGN(ThreadPoolImpl);
fdoray4151cea2016-05-06 15:39:14195};
196
197} // namespace internal
198} // namespace base
199
Gabriel Charette52fa3ae2019-04-15 21:44:37200#endif // BASE_TASK_THREAD_POOL_THREAD_POOL_IMPL_H_