1 // Copyright 2021 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_TASK_SEQUENCE_MANAGER_TASK_ORDER_H_ 6 #define BASE_TASK_SEQUENCE_MANAGER_TASK_ORDER_H_ 7 8 #include "base/base_export.h" 9 #include "base/task/sequence_manager/enqueue_order.h" 10 #include "base/time/time.h" 11 12 namespace base { 13 namespace sequence_manager { 14 15 struct Task; 16 17 namespace internal { 18 class Fence; 19 } // namespace internal 20 21 // `TaskOrder` represents the order of a `Task` relative to other `Task`s. The < 22 // operator on the set of all `TaskOrder`s is a strict total ordering [1]. 23 // `TaskOrder` consists of the following: 24 // - `enqueue_order_`: The order the task was enqueued. It is assigned at 25 // posting time for immediate tasks and enqueue time for delayed tasks, which 26 // is the time at which a pending delayed task is moved to its `WorkQueue` 27 // (after its delay has expired, during a wake-up). This is the primary 28 // ordering for tasks. Delayed tasks that are enqueued during the same 29 // wake-up have the same `enqueue_order_` and their order is decided by 30 // `delayed_run_time_` and `sequence_num_`. 31 // 32 // - `delayed_run_time_`: The latest time at which a delayed task should run; 33 // only non-zero for delayed tasks. Before they become ripe, delayed tasks 34 // are maintained in a heap ordered by `latest_delayed_run_time`. 35 // 36 // - `sequence_num_`: a strictly increasing number assigned at posting time for 37 // all tasks. This is used to order delayed tasks if their `enqueue_order_` 38 // and `delayed_run_time_`s match. 39 // 40 // While `TaskOrder` can be used to order a set `Task`s, it is not necessarily 41 // the order that the associated tasks will run: tasks are executed in order of 42 // highest to lowest priority, tasks from disabled queues and queues blocked by 43 // fences are prevented from running, and sequence manager may choose immediate 44 // over delayed tasks to prevent starvation. 45 // 46 // [1] sequence_num is an int rollovers are possible, however it is extremely 47 // unlikely that two delayed tasks would have the same posting order and delayed 48 // run time. 49 class BASE_EXPORT TaskOrder { 50 public: 51 TaskOrder(const TaskOrder& other); 52 TaskOrder& operator=(const TaskOrder& other); 53 ~TaskOrder(); 54 enqueue_order()55 EnqueueOrder enqueue_order() const { return enqueue_order_; } 56 sequence_num()57 int sequence_num() const { return sequence_num_; } 58 59 // TODO(1153139): Rename to latest_delayed_run_time() for clarity. delayed_run_time()60 TimeTicks delayed_run_time() const { return delayed_run_time_; } 61 62 static TaskOrder CreateForTesting(EnqueueOrder enqueue_order, 63 TimeTicks delayed_run_time, 64 int sequence_num); 65 static TaskOrder CreateForTesting(EnqueueOrder enqueue_order); 66 67 bool operator>(const TaskOrder& other) const; 68 bool operator<(const TaskOrder& other) const; 69 bool operator<=(const TaskOrder& other) const; 70 bool operator>=(const TaskOrder& other) const; 71 bool operator==(const TaskOrder& other) const; 72 bool operator!=(const TaskOrder& other) const; 73 74 protected: 75 TaskOrder(EnqueueOrder enqueue_order, 76 TimeTicks delayed_run_time, 77 int sequence_num); 78 79 private: 80 friend class internal::Fence; 81 friend struct Task; 82 83 EnqueueOrder enqueue_order_; 84 TimeTicks delayed_run_time_; 85 int sequence_num_; 86 }; 87 88 } // namespace sequence_manager 89 } // namespace base 90 91 #endif // BASE_TASK_SEQUENCE_MANAGER_TASK_ORDER_H_ 92