92 lines
3.4 KiB
C++
92 lines
3.4 KiB
C++
// Copyright 2021 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef BASE_TASK_SEQUENCE_MANAGER_TASK_ORDER_H_
|
|
#define BASE_TASK_SEQUENCE_MANAGER_TASK_ORDER_H_
|
|
|
|
#include "base/base_export.h"
|
|
#include "base/task/sequence_manager/enqueue_order.h"
|
|
#include "base/time/time.h"
|
|
|
|
namespace base {
|
|
namespace sequence_manager {
|
|
|
|
struct Task;
|
|
|
|
namespace internal {
|
|
class Fence;
|
|
} // namespace internal
|
|
|
|
// `TaskOrder` represents the order of a `Task` relative to other `Task`s. The <
|
|
// operator on the set of all `TaskOrder`s is a strict total ordering [1].
|
|
// `TaskOrder` consists of the following:
|
|
// - `enqueue_order_`: The order the task was enqueued. It is assigned at
|
|
// posting time for immediate tasks and enqueue time for delayed tasks, which
|
|
// is the time at which a pending delayed task is moved to its `WorkQueue`
|
|
// (after its delay has expired, during a wake-up). This is the primary
|
|
// ordering for tasks. Delayed tasks that are enqueued during the same
|
|
// wake-up have the same `enqueue_order_` and their order is decided by
|
|
// `delayed_run_time_` and `sequence_num_`.
|
|
//
|
|
// - `delayed_run_time_`: The latest time at which a delayed task should run;
|
|
// only non-zero for delayed tasks. Before they become ripe, delayed tasks
|
|
// are maintained in a heap ordered by `latest_delayed_run_time`.
|
|
//
|
|
// - `sequence_num_`: a strictly increasing number assigned at posting time for
|
|
// all tasks. This is used to order delayed tasks if their `enqueue_order_`
|
|
// and `delayed_run_time_`s match.
|
|
//
|
|
// While `TaskOrder` can be used to order a set `Task`s, it is not necessarily
|
|
// the order that the associated tasks will run: tasks are executed in order of
|
|
// highest to lowest priority, tasks from disabled queues and queues blocked by
|
|
// fences are prevented from running, and sequence manager may choose immediate
|
|
// over delayed tasks to prevent starvation.
|
|
//
|
|
// [1] sequence_num is an int rollovers are possible, however it is extremely
|
|
// unlikely that two delayed tasks would have the same posting order and delayed
|
|
// run time.
|
|
class BASE_EXPORT TaskOrder {
|
|
public:
|
|
TaskOrder(const TaskOrder& other);
|
|
TaskOrder& operator=(const TaskOrder& other);
|
|
~TaskOrder();
|
|
|
|
EnqueueOrder enqueue_order() const { return enqueue_order_; }
|
|
|
|
int sequence_num() const { return sequence_num_; }
|
|
|
|
// TODO(1153139): Rename to latest_delayed_run_time() for clarity.
|
|
TimeTicks delayed_run_time() const { return delayed_run_time_; }
|
|
|
|
static TaskOrder CreateForTesting(EnqueueOrder enqueue_order,
|
|
TimeTicks delayed_run_time,
|
|
int sequence_num);
|
|
static TaskOrder CreateForTesting(EnqueueOrder enqueue_order);
|
|
|
|
bool operator>(const TaskOrder& other) const;
|
|
bool operator<(const TaskOrder& other) const;
|
|
bool operator<=(const TaskOrder& other) const;
|
|
bool operator>=(const TaskOrder& other) const;
|
|
bool operator==(const TaskOrder& other) const;
|
|
bool operator!=(const TaskOrder& other) const;
|
|
|
|
protected:
|
|
TaskOrder(EnqueueOrder enqueue_order,
|
|
TimeTicks delayed_run_time,
|
|
int sequence_num);
|
|
|
|
private:
|
|
friend class internal::Fence;
|
|
friend struct Task;
|
|
|
|
EnqueueOrder enqueue_order_;
|
|
TimeTicks delayed_run_time_;
|
|
int sequence_num_;
|
|
};
|
|
|
|
} // namespace sequence_manager
|
|
} // namespace base
|
|
|
|
#endif // BASE_TASK_SEQUENCE_MANAGER_TASK_ORDER_H_
|