task_traits.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  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_TASK_TRAITS_H_
  5. #define BASE_TASK_TASK_TRAITS_H_
  6. #include <stdint.h>
  7. #include <iosfwd>
  8. #include <tuple>
  9. #include <type_traits>
  10. #include <utility>
  11. #include "base/base_export.h"
  12. #include "base/check_op.h"
  13. #include "base/task/task_traits_extension.h"
  14. #include "base/traits_bag.h"
  15. #include "build/build_config.h"
  16. // TODO(gab): This is backwards, thread_pool.h should include task_traits.h
  17. // but it this is necessary to have it in this direction during the migration
  18. // from old code that used base::ThreadPool as a trait.
  19. #include "base/task/thread_pool.h"
  20. namespace base {
  21. class PostTaskAndroid;
  22. // Valid priorities supported by the task scheduling infrastructure.
  23. //
  24. // Note: internal algorithms depend on priorities being expressed as a
  25. // continuous zero-based list from lowest to highest priority. Users of this API
  26. // shouldn't otherwise care about nor use the underlying values.
  27. //
  28. // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.base.task
  29. enum class TaskPriority : uint8_t {
  30. // This will always be equal to the lowest priority available.
  31. LOWEST = 0,
  32. // Best effort tasks will only start running when machine resources are
  33. // available. The application may preempt best effort tasks if it expects that
  34. // resources will soon be needed by work of higher priority. Dependending on
  35. // the ThreadPolicy, best effort tasks may run on a thread that is likely to
  36. // be descheduled when higher priority work arrives (in this process or
  37. // another).
  38. //
  39. // Examples:
  40. // - Reporting metrics.
  41. // - Persisting data to disk.
  42. // - Loading data that is required for a potential future user interaction
  43. // (Note: Use CreateUpdateableSequencedTaskRunner() to increase the priority
  44. // when that user interactions happens).
  45. BEST_EFFORT = LOWEST,
  46. // The result of user visible tasks is visible to the user (in the UI or as a
  47. // side-effect on the system) but it is not an immediate response to a user
  48. // interaction.
  49. //
  50. // Examples:
  51. // - Updating the UI to reflect progress on a long task.
  52. // - Downloading a file requested by the user.
  53. // - Loading an image that is displayed in the UI but is non-critical.
  54. USER_VISIBLE,
  55. // User blocking tasks affects UI immediately after a user interaction.
  56. //
  57. // Example:
  58. // - Loading and rendering a web page after the user clicks a link.
  59. // - Sorting suggestions after the user types a character in the omnibox.
  60. //
  61. // This is the default TaskPriority in order for tasks to run in order by
  62. // default and avoid unintended consequences. The only way to get a task to
  63. // run at a higher priority than USER_BLOCKING is to coordinate with a
  64. // higher-level scheduler (contact scheduler-dev@chromium.org for such use
  65. // cases).
  66. USER_BLOCKING,
  67. // This will always be equal to the highest priority available.
  68. HIGHEST = USER_BLOCKING
  69. };
  70. // Valid shutdown behaviors supported by the thread pool.
  71. enum class TaskShutdownBehavior : uint8_t {
  72. // Tasks posted with this mode which have not started executing before
  73. // shutdown is initiated will never run. Tasks with this mode running at
  74. // shutdown will be ignored (the worker will not be joined).
  75. //
  76. // This option provides a nice way to post stuff you don't want blocking
  77. // shutdown. For example, you might be doing a slow DNS lookup and if it's
  78. // blocked on the OS, you may not want to stop shutdown, since the result
  79. // doesn't really matter at that point.
  80. //
  81. // However, you need to be very careful what you do in your callback when you
  82. // use this option. Since the thread will continue to run until the OS
  83. // terminates the process, the app can be in the process of tearing down when
  84. // you're running. This means any singletons or global objects you use may
  85. // suddenly become invalid out from under you. For this reason, it's best to
  86. // use this only for slow but simple operations like the DNS example.
  87. CONTINUE_ON_SHUTDOWN,
  88. // Tasks posted with this mode that have not started executing at
  89. // shutdown will never run. However, any task that has already begun
  90. // executing when shutdown is invoked will be allowed to continue and
  91. // will block shutdown until completion.
  92. //
  93. // Note: Because ThreadPoolInstance::Shutdown() may block while these tasks
  94. // are executing, care must be taken to ensure that they do not block on the
  95. // thread that called ThreadPoolInstance::Shutdown(), as this may lead to
  96. // deadlock.
  97. SKIP_ON_SHUTDOWN,
  98. // Tasks posted with this mode before shutdown is complete will block shutdown
  99. // until they're executed. Generally, this should be used only to save
  100. // critical user data.
  101. //
  102. // Note: Background threads will be promoted to normal threads at shutdown
  103. // (i.e. TaskPriority::BEST_EFFORT + TaskShutdownBehavior::BLOCK_SHUTDOWN will
  104. // resolve without a priority inversion).
  105. BLOCK_SHUTDOWN,
  106. };
  107. // Determines at which thread priority a task may run.
  108. //
  109. // ThreadPolicy and priority updates
  110. // ---------------------------------
  111. //
  112. // If the TaskPriority of an UpdateableSequencedTaskRunner is increased while
  113. // one of its tasks is running at background thread priority, the task's
  114. // execution will have to complete at background thread priority (may take a
  115. // long time) before the next task can be scheduled with the new TaskPriority.
  116. // If it is important that priority increases take effect quickly,
  117. // MUST_USE_FOREGROUND should be used to prevent the tasks from running at
  118. // background thread priority. If it is important to minimize impact on the
  119. // rest on the system when the TaskPriority is BEST_EFFORT, PREFER_BACKGROUND
  120. // should be used.
  121. //
  122. // ThreadPolicy and priority inversions
  123. // ------------------------------------
  124. //
  125. // A priority inversion occurs when a task running at background thread
  126. // priority is descheduled while holding a resource needed by a thread of
  127. // higher priority. MUST_USE_FOREGROUND can be combined with BEST_EFFORT to
  128. // indicate that a task has a low priority, but shouldn't run at background
  129. // thread priority in order to avoid priority inversions. Please consult with
  130. // //base/task/OWNERS if you suspect a priority inversion.
  131. enum class ThreadPolicy : uint8_t {
  132. // The task runs on a background priority thread if:
  133. // - The TaskPriority is BEST_EFFORT.
  134. // - Background thread priority is supported by the platform (see
  135. // environment_config_unittest.cc).
  136. // - No extension trait (e.g. BrowserThread) is used.
  137. // - ThreadPoolInstance::Shutdown() hadn't been called when the task started running.
  138. // (Remaining TaskShutdownBehavior::BLOCK_SHUTDOWN tasks use foreground
  139. // threads during shutdown regardless of TaskPriority)
  140. // Otherwise, it runs on a normal priority thread.
  141. // This is the default.
  142. PREFER_BACKGROUND,
  143. // The task runs at normal thread priority, irrespective of its TaskPriority.
  144. MUST_USE_FOREGROUND
  145. };
  146. // Tasks with this trait may block. This includes but is not limited to tasks
  147. // that wait on synchronous file I/O operations: read or write a file from disk,
  148. // interact with a pipe or a socket, rename or delete a file, enumerate files in
  149. // a directory, etc. This trait isn't required for the mere use of locks. For
  150. // tasks that block on base/ synchronization primitives, see the
  151. // WithBaseSyncPrimitives trait.
  152. struct MayBlock {};
  153. // DEPRECATED. Use base::ScopedAllowBaseSyncPrimitives(ForTesting) instead.
  154. //
  155. // Tasks with this trait will pass base::AssertBaseSyncPrimitivesAllowed(), i.e.
  156. // will be allowed on the following methods :
  157. // - base::WaitableEvent::Wait
  158. // - base::ConditionVariable::Wait
  159. // - base::PlatformThread::Join
  160. // - base::PlatformThread::Sleep
  161. // - base::Process::WaitForExit
  162. // - base::Process::WaitForExitWithTimeout
  163. //
  164. // Tasks should generally not use these methods.
  165. //
  166. // Instead of waiting on a WaitableEvent or a ConditionVariable, put the work
  167. // that should happen after the wait in a callback and post that callback from
  168. // where the WaitableEvent or ConditionVariable would have been signaled. If
  169. // something needs to be scheduled after many tasks have executed, use
  170. // base::BarrierClosure.
  171. //
  172. // On Windows, join processes asynchronously using base::win::ObjectWatcher.
  173. //
  174. // MayBlock() must be specified in conjunction with this trait if and only if
  175. // removing usage of methods listed above in the labeled tasks would still
  176. // result in tasks that may block (per MayBlock()'s definition).
  177. //
  178. // In doubt, consult with //base/task/OWNERS.
  179. struct WithBaseSyncPrimitives {};
  180. // Describes metadata for a single task or a group of tasks.
  181. class BASE_EXPORT TaskTraits {
  182. public:
  183. // ValidTrait ensures TaskTraits' constructor only accepts appropriate types.
  184. struct ValidTrait {
  185. ValidTrait(TaskPriority);
  186. ValidTrait(TaskShutdownBehavior);
  187. ValidTrait(ThreadPolicy);
  188. ValidTrait(MayBlock);
  189. ValidTrait(WithBaseSyncPrimitives);
  190. ValidTrait(ThreadPool);
  191. };
  192. // Invoking this constructor without arguments produces default TaskTraits
  193. // that are appropriate for tasks that
  194. // (1) don't block (ref. MayBlock() and WithBaseSyncPrimitives()),
  195. // (2) pertain to user-blocking activity,
  196. // (explicitly or implicitly by having an ordering dependency with a
  197. // component that does)
  198. // (3) can either block shutdown or be skipped on shutdown
  199. // (the task recipient is free to choose a fitting default).
  200. //
  201. // To get TaskTraits for tasks that have more precise traits: provide any
  202. // combination of ValidTrait's as arguments to this constructor.
  203. //
  204. // Note: When posting to well-known threads (e.g. UI/IO), default traits are
  205. // almost always what you want unless you know for sure the task being posted
  206. // has no explicit/implicit ordering dependency with anything else running at
  207. // default (USER_BLOCKING) priority.
  208. //
  209. // E.g.
  210. // constexpr base::TaskTraits default_traits = {};
  211. // constexpr base::TaskTraits user_visible_traits = {
  212. // base::TaskPriority::USER_VISIBLE};
  213. // constexpr base::TaskTraits user_visible_may_block_traits = {
  214. // base::TaskPriority::USER_VISIBLE, base::MayBlock()
  215. // };
  216. // constexpr base::TaskTraits other_user_visible_may_block_traits = {
  217. // base::MayBlock(), base::TaskPriority::USER_VISIBLE
  218. // };
  219. template <class... ArgTypes,
  220. class CheckArgumentsAreValid = std::enable_if_t<
  221. trait_helpers::AreValidTraits<ValidTrait, ArgTypes...>::value ||
  222. trait_helpers::AreValidTraitsForExtension<ArgTypes...>::value>>
  223. constexpr TaskTraits(ArgTypes... args)
  224. : extension_(trait_helpers::GetTaskTraitsExtension(
  225. trait_helpers::AreValidTraits<ValidTrait, ArgTypes...>{},
  226. args...)),
  227. priority_(
  228. trait_helpers::GetEnum<TaskPriority, TaskPriority::USER_BLOCKING>(
  229. args...)),
  230. shutdown_behavior_(
  231. static_cast<uint8_t>(
  232. trait_helpers::GetEnum<TaskShutdownBehavior,
  233. TaskShutdownBehavior::SKIP_ON_SHUTDOWN>(
  234. args...)) |
  235. (trait_helpers::HasTrait<TaskShutdownBehavior, ArgTypes...>()
  236. ? kIsExplicitFlag
  237. : 0)),
  238. thread_policy_(
  239. static_cast<uint8_t>(
  240. trait_helpers::GetEnum<ThreadPolicy,
  241. ThreadPolicy::PREFER_BACKGROUND>(
  242. args...)) |
  243. (trait_helpers::HasTrait<ThreadPolicy, ArgTypes...>()
  244. ? kIsExplicitFlag
  245. : 0)),
  246. may_block_(trait_helpers::HasTrait<MayBlock, ArgTypes...>()),
  247. with_base_sync_primitives_(
  248. trait_helpers::HasTrait<WithBaseSyncPrimitives, ArgTypes...>()),
  249. use_thread_pool_(trait_helpers::HasTrait<ThreadPool, ArgTypes...>()) {}
  250. constexpr TaskTraits(const TaskTraits& other) = default;
  251. TaskTraits& operator=(const TaskTraits& other) = default;
  252. // TODO(eseckler): Default the comparison operator once C++20 arrives.
  253. bool operator==(const TaskTraits& other) const {
  254. static_assert(sizeof(TaskTraits) == 15,
  255. "Update comparison operator when TaskTraits change");
  256. return extension_ == other.extension_ && priority_ == other.priority_ &&
  257. shutdown_behavior_ == other.shutdown_behavior_ &&
  258. thread_policy_ == other.thread_policy_ &&
  259. may_block_ == other.may_block_ &&
  260. with_base_sync_primitives_ == other.with_base_sync_primitives_ &&
  261. use_thread_pool_ == other.use_thread_pool_;
  262. }
  263. // Sets the priority of tasks with these traits to |priority|.
  264. void UpdatePriority(TaskPriority priority) { priority_ = priority; }
  265. // Returns the priority of tasks with these traits.
  266. constexpr TaskPriority priority() const { return priority_; }
  267. // Returns true if the shutdown behavior was set explicitly.
  268. constexpr bool shutdown_behavior_set_explicitly() const {
  269. return shutdown_behavior_ & kIsExplicitFlag;
  270. }
  271. // Returns the shutdown behavior of tasks with these traits.
  272. constexpr TaskShutdownBehavior shutdown_behavior() const {
  273. return static_cast<TaskShutdownBehavior>(shutdown_behavior_ &
  274. ~kIsExplicitFlag);
  275. }
  276. // Returns true if the thread policy was set explicitly.
  277. constexpr bool thread_policy_set_explicitly() const {
  278. return thread_policy_ & kIsExplicitFlag;
  279. }
  280. // Returns the thread policy of tasks with these traits.
  281. constexpr ThreadPolicy thread_policy() const {
  282. return static_cast<ThreadPolicy>(thread_policy_ & ~kIsExplicitFlag);
  283. }
  284. // Returns true if tasks with these traits may block.
  285. constexpr bool may_block() const { return may_block_; }
  286. // Returns true if tasks with these traits may use base/ sync primitives.
  287. constexpr bool with_base_sync_primitives() const {
  288. return with_base_sync_primitives_;
  289. }
  290. // Returns true if tasks with these traits execute on the thread pool.
  291. constexpr bool use_thread_pool() const { return use_thread_pool_; }
  292. uint8_t extension_id() const { return extension_.extension_id; }
  293. // Access the extension data by parsing it into the provided extension type.
  294. // See task_traits_extension.h for requirements on the extension type.
  295. template <class TaskTraitsExtension>
  296. const TaskTraitsExtension GetExtension() const {
  297. DCHECK_EQ(TaskTraitsExtension::kExtensionId, extension_.extension_id);
  298. return TaskTraitsExtension::Parse(extension_);
  299. }
  300. private:
  301. friend PostTaskAndroid;
  302. // For use by PostTaskAndroid.
  303. TaskTraits(TaskPriority priority,
  304. bool may_block,
  305. bool use_thread_pool,
  306. TaskTraitsExtensionStorage extension)
  307. : extension_(extension),
  308. priority_(priority),
  309. shutdown_behavior_(
  310. static_cast<uint8_t>(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)),
  311. thread_policy_(static_cast<uint8_t>(ThreadPolicy::PREFER_BACKGROUND)),
  312. may_block_(may_block),
  313. with_base_sync_primitives_(false),
  314. use_thread_pool_(use_thread_pool) {
  315. static_assert(sizeof(TaskTraits) == 15, "Keep this constructor up to date");
  316. // Java is expected to provide an explicit destination. See TODO in
  317. // TaskTraits.java to move towards API-as-a-destination there as well.
  318. const bool has_extension =
  319. (extension_.extension_id !=
  320. TaskTraitsExtensionStorage::kInvalidExtensionId);
  321. DCHECK(use_thread_pool_ ^ has_extension)
  322. << "Traits must explicitly specify a destination (e.g. ThreadPool or a "
  323. "named thread like BrowserThread)";
  324. }
  325. // This bit is set in |priority_|, |shutdown_behavior_| and |thread_policy_|
  326. // when the value was set explicitly.
  327. static constexpr uint8_t kIsExplicitFlag = 0x80;
  328. // Ordered for packing.
  329. TaskTraitsExtensionStorage extension_;
  330. TaskPriority priority_;
  331. uint8_t shutdown_behavior_;
  332. uint8_t thread_policy_;
  333. bool may_block_;
  334. bool with_base_sync_primitives_;
  335. bool use_thread_pool_;
  336. };
  337. // Returns string literals for the enums defined in this file. These methods
  338. // should only be used for tracing and debugging.
  339. BASE_EXPORT const char* TaskPriorityToString(TaskPriority task_priority);
  340. BASE_EXPORT const char* TaskShutdownBehaviorToString(
  341. TaskShutdownBehavior task_priority);
  342. // Stream operators so that the enums defined in this file can be used in
  343. // DCHECK and EXPECT statements.
  344. BASE_EXPORT std::ostream& operator<<(std::ostream& os,
  345. const TaskPriority& shutdown_behavior);
  346. BASE_EXPORT std::ostream& operator<<(
  347. std::ostream& os,
  348. const TaskShutdownBehavior& shutdown_behavior);
  349. } // namespace base
  350. #endif // BASE_TASK_TASK_TRAITS_H_