thread_pool_instance.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  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
  3. // found in the LICENSE file.
  4. #ifndef BASE_TASK_THREAD_POOL_THREAD_POOL_INSTANCE_H_
  5. #define BASE_TASK_THREAD_POOL_THREAD_POOL_INSTANCE_H_
  6. #include <memory>
  7. #include <vector>
  8. #include "base/base_export.h"
  9. #include "base/callback.h"
  10. #include "base/gtest_prod_util.h"
  11. #include "base/memory/ref_counted.h"
  12. #include "base/sequenced_task_runner.h"
  13. #include "base/single_thread_task_runner.h"
  14. #include "base/strings/string_piece.h"
  15. #include "base/task/single_thread_task_runner_thread_mode.h"
  16. #include "base/task/task_traits.h"
  17. #include "base/task_runner.h"
  18. #include "base/time/time.h"
  19. #include "build/build_config.h"
  20. namespace gin {
  21. class V8Platform;
  22. }
  23. namespace content {
  24. // Can't use the FRIEND_TEST_ALL_PREFIXES macro because the test is in a
  25. // different namespace.
  26. class BrowserMainLoopTest_CreateThreadsInSingleProcess_Test;
  27. } // namespace content
  28. namespace base {
  29. class WorkerThreadObserver;
  30. class ThreadPoolTestHelpers;
  31. // Interface for a thread pool and static methods to manage the instance used
  32. // by the post_task.h API.
  33. //
  34. // The thread pool doesn't create threads until Start() is called. Tasks can
  35. // be posted at any time but will not run until after Start() is called.
  36. //
  37. // The instance methods of this class are thread-safe.
  38. //
  39. // Note: All thread pool users should go through base/task/post_task.h instead
  40. // of this interface except for the one callsite per process which manages the
  41. // process's instance.
  42. class BASE_EXPORT ThreadPoolInstance {
  43. public:
  44. struct BASE_EXPORT InitParams {
  45. enum class CommonThreadPoolEnvironment {
  46. // Use the default environment (no environment).
  47. DEFAULT,
  48. #if defined(OS_WIN)
  49. // Place the pool's workers in a COM MTA.
  50. COM_MTA,
  51. // Place the pool's *foreground* workers in a COM STA. This exists to
  52. // mimic the behavior of SequencedWorkerPool and BrowserThreadImpl that
  53. // ThreadPool has replaced. Tasks that need a COM STA should use
  54. // CreateCOMSTATaskRunner() instead of Create(Sequenced)TaskRunner() +
  55. // this init param.
  56. DEPRECATED_COM_STA_IN_FOREGROUND_GROUP,
  57. #endif // defined(OS_WIN)
  58. };
  59. InitParams(int max_num_foreground_threads_in);
  60. ~InitParams();
  61. // Maximum number of unblocked tasks that can run concurrently in the
  62. // foreground thread group.
  63. int max_num_foreground_threads;
  64. // Whether COM is initialized when running sequenced and parallel tasks.
  65. CommonThreadPoolEnvironment common_thread_pool_environment =
  66. CommonThreadPoolEnvironment::DEFAULT;
  67. // An experiment conducted in July 2019 revealed that on Android, changing
  68. // the reclaim time from 30 seconds to 5 minutes:
  69. // - Reduces jank by 5% at 99th percentile
  70. // - Reduces first input delay by 5% at 99th percentile
  71. // - Reduces input delay by 3% at 50th percentile
  72. // - Reduces navigation to first contentful paint by 2-3% at 25-95th
  73. // percentiles
  74. // On Windows and Mac, we instead see no impact or small regressions.
  75. //
  76. // TODO(scheduler-dev): Conduct experiments to find the optimal value for
  77. // each process type on each platform. In particular, due to regressions at
  78. // high percentiles for *HeartbeatLatencyMicroseconds.Renderer* histograms,
  79. // it was suggested that we might want a different reclaim time in
  80. // renderers. Note that the regression is not present in
  81. // *TaskLatencyMicroseconds.Renderer* histograms.
  82. TimeDelta suggested_reclaim_time =
  83. #if defined(OS_ANDROID)
  84. TimeDelta::FromMinutes(5);
  85. #else
  86. TimeDelta::FromSeconds(30);
  87. #endif
  88. };
  89. // A Scoped(BestEffort)ExecutionFence prevents new tasks of any/BEST_EFFORT
  90. // priority from being scheduled in ThreadPoolInstance within its scope.
  91. // Multiple fences can exist at the same time. Upon destruction of all
  92. // Scoped(BestEffort)ExecutionFences, tasks that were preeempted are released.
  93. // Note: the constructor of Scoped(BestEffort)ExecutionFence will not wait for
  94. // currently running tasks (as they were posted before entering this scope and
  95. // do not violate the contract; some of them could be CONTINUE_ON_SHUTDOWN and
  96. // waiting for them to complete is ill-advised).
  97. class BASE_EXPORT ScopedExecutionFence {
  98. public:
  99. ScopedExecutionFence();
  100. ~ScopedExecutionFence();
  101. private:
  102. DISALLOW_COPY_AND_ASSIGN(ScopedExecutionFence);
  103. };
  104. class BASE_EXPORT ScopedBestEffortExecutionFence {
  105. public:
  106. ScopedBestEffortExecutionFence();
  107. ~ScopedBestEffortExecutionFence();
  108. private:
  109. DISALLOW_COPY_AND_ASSIGN(ScopedBestEffortExecutionFence);
  110. };
  111. // Destroying a ThreadPoolInstance is not allowed in production; it is always
  112. // leaked. In tests, it should only be destroyed after JoinForTesting() has
  113. // returned.
  114. virtual ~ThreadPoolInstance() = default;
  115. // Allows the thread pool to create threads and run tasks following the
  116. // |init_params| specification.
  117. //
  118. // If specified, |worker_thread_observer| will be notified when a worker
  119. // enters and exits its main function. It must not be destroyed before
  120. // JoinForTesting() has returned (must never be destroyed in production).
  121. //
  122. // CHECKs on failure.
  123. virtual void Start(
  124. const InitParams& init_params,
  125. WorkerThreadObserver* worker_thread_observer = nullptr) = 0;
  126. // Synchronously shuts down the thread pool. Once this is called, only tasks
  127. // posted with the BLOCK_SHUTDOWN behavior will be run. When this returns:
  128. // - All SKIP_ON_SHUTDOWN tasks that were already running have completed their
  129. // execution.
  130. // - All posted BLOCK_SHUTDOWN tasks have completed their execution.
  131. // - CONTINUE_ON_SHUTDOWN tasks might still be running.
  132. // Note that an implementation can keep threads and other resources alive to
  133. // support running CONTINUE_ON_SHUTDOWN after this returns. This can only be
  134. // called once.
  135. virtual void Shutdown() = 0;
  136. // Waits until there are no pending undelayed tasks. May be called in tests
  137. // to validate that a condition is met after all undelayed tasks have run.
  138. //
  139. // Does not wait for delayed tasks. Waits for undelayed tasks posted from
  140. // other threads during the call. Returns immediately when shutdown completes.
  141. virtual void FlushForTesting() = 0;
  142. // Returns and calls |flush_callback| when there are no incomplete undelayed
  143. // tasks. |flush_callback| may be called back on any thread and should not
  144. // perform a lot of work. May be used when additional work on the current
  145. // thread needs to be performed during a flush. Only one
  146. // FlushAsyncForTesting() may be pending at any given time.
  147. virtual void FlushAsyncForTesting(OnceClosure flush_callback) = 0;
  148. // Joins all threads. Tasks that are already running are allowed to complete
  149. // their execution. This can only be called once. Using this thread pool
  150. // instance to create task runners or post tasks is not permitted during or
  151. // after this call.
  152. virtual void JoinForTesting() = 0;
  153. // CreateAndStartWithDefaultParams(), Create(), and SetInstance() register a
  154. // ThreadPoolInstance to handle tasks posted through the post_task.h API for
  155. // this process.
  156. //
  157. // Processes that need to initialize ThreadPoolInstance with custom params or
  158. // that need to allow tasks to be posted before the ThreadPoolInstance creates
  159. // its threads should use Create() followed by Start(). Other processes can
  160. // use CreateAndStartWithDefaultParams().
  161. //
  162. // A registered ThreadPoolInstance is only deleted when a new
  163. // ThreadPoolInstance is registered. The last registered ThreadPoolInstance is
  164. // leaked on shutdown. The methods below must not be called when TaskRunners
  165. // created by a previous ThreadPoolInstance are still alive. The methods are
  166. // not thread-safe; proper synchronization is required to use the post_task.h
  167. // API after registering a new ThreadPoolInstance.
  168. #if !defined(OS_NACL)
  169. // Creates and starts a thread pool using default params. |name| is used to
  170. // label histograms, it must not be empty. It should identify the component
  171. // that calls this. Start() is called by this method; it is invalid to call it
  172. // again afterwards. CHECKs on failure. For tests, prefer
  173. // base::test::TaskEnvironment (ensures isolation).
  174. static void CreateAndStartWithDefaultParams(StringPiece name);
  175. // Same as CreateAndStartWithDefaultParams() but allows callers to split the
  176. // Create() and StartWithDefaultParams() calls.
  177. void StartWithDefaultParams();
  178. #endif // !defined(OS_NACL)
  179. // Creates a ready to start thread pool. |name| is used to label histograms,
  180. // it must not be empty. It should identify the component that creates the
  181. // ThreadPoolInstance. The thread pool doesn't create threads until Start() is
  182. // called. Tasks can be posted at any time but will not run until after
  183. // Start() is called. For tests, prefer base::test::TaskEnvironment
  184. // (ensures isolation).
  185. static void Create(StringPiece name);
  186. // Registers |thread_pool| to handle tasks posted through the post_task.h
  187. // API for this process. For tests, prefer base::test::TaskEnvironment
  188. // (ensures isolation).
  189. static void Set(std::unique_ptr<ThreadPoolInstance> thread_pool);
  190. // Retrieve the ThreadPoolInstance set via SetInstance() or Create(). This
  191. // should be used very rarely; most users of the thread pool should use the
  192. // post_task.h API. In particular, refrain from doing
  193. // if (!ThreadPoolInstance::Get()) {
  194. // ThreadPoolInstance::Set(...);
  195. // base::PostTask(...);
  196. // }
  197. // instead make sure to SetInstance() early in one determinstic place in the
  198. // process' initialization phase.
  199. // In doubt, consult with //base/task/thread_pool/OWNERS.
  200. static ThreadPoolInstance* Get();
  201. private:
  202. friend class ThreadPoolTestHelpers;
  203. friend class gin::V8Platform;
  204. friend class content::BrowserMainLoopTest_CreateThreadsInSingleProcess_Test;
  205. // Returns the maximum number of non-single-threaded non-blocked tasks posted
  206. // with |traits| that can run concurrently in this thread pool. |traits|
  207. // can't contain TaskPriority::BEST_EFFORT.
  208. //
  209. // Do not use this method. To process n items, post n tasks that each process
  210. // 1 item rather than GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated()
  211. // tasks that each process
  212. // n/GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated() items.
  213. //
  214. // TODO(fdoray): Remove this method. https://crbug.com/687264
  215. virtual int GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated(
  216. const TaskTraits& traits) const = 0;
  217. // Starts/stops a fence that prevents execution of tasks of any / BEST_EFFORT
  218. // priority.
  219. virtual void BeginFence() = 0;
  220. virtual void EndFence() = 0;
  221. virtual void BeginBestEffortFence() = 0;
  222. virtual void EndBestEffortFence() = 0;
  223. };
  224. } // namespace base
  225. #endif // BASE_TASK_THREAD_POOL_THREAD_POOL_INSTANCE_H_