summaryrefslogtreecommitdiffstats
path: root/chromium/base/task/thread_pool/sequence.h
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2023-02-13 16:03:23 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2023-05-26 11:26:35 +0000
commit813d9ae984a99e739b99cf694a9d5b24d0a6b7a7 (patch)
tree60c14d40d77a3c702c8a72887662d97c0b8f3e99 /chromium/base/task/thread_pool/sequence.h
parenteb596ba9fe579987eb93f6b4021ca156885b48c2 (diff)
BASELINE: Update Chromium to 110.0.5481.111
Change-Id: I2b5f5ed66fee2a6f8da61c9b17fd1b25bb5b3a4e Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/464348 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/base/task/thread_pool/sequence.h')
-rw-r--r--chromium/base/task/thread_pool/sequence.h107
1 files changed, 52 insertions, 55 deletions
diff --git a/chromium/base/task/thread_pool/sequence.h b/chromium/base/task/thread_pool/sequence.h
index 7f0f3032649..decdbdfb1d2 100644
--- a/chromium/base/task/thread_pool/sequence.h
+++ b/chromium/base/task/thread_pool/sequence.h
@@ -16,6 +16,7 @@
#include "base/task/thread_pool/task.h"
#include "base/task/thread_pool/task_source.h"
#include "base/task/thread_pool/task_source_sort_key.h"
+#include "base/thread_annotations.h"
#include "base/threading/sequence_local_storage_map.h"
namespace base {
@@ -24,8 +25,6 @@ namespace internal {
// A Sequence is intended to hold delayed tasks and immediate tasks.
// Delayed tasks are held in a prority_queue until they are ripe and
// immediate tasks in a simple fifo queue.
-// Sequence::PushTask is responsible for putting a task into the right
-// queue depending on its nature.
// When Sequence::TakeTask is called, we select the next appropriate task
// from both queues and return it.
// Each queue holds slots each containing up to a single Task that must be
@@ -58,26 +57,19 @@ class BASE_EXPORT Sequence : public TaskSource {
Transaction& operator=(const Transaction&) = delete;
~Transaction();
- // Returns true if the sequence would need to be queued in the
- // immediate/delayed queue after receiving a new immediate/delayed Task.
- // Thread-safe but the returned value may immediately be obsolete when
- // pushing a delayed task since a sequence can become ready at any time;
- // therefore it must be externally synchronized to prevent races against
- // OnBecomeReady().
- [[nodiscard]] bool ShouldBeQueued() const;
+ // Returns true if the sequence must be added to the immediate queue after
+ // receiving a new immediate Task in order to be scheduled. If the caller
+ // doesn't want the sequence to be scheduled, it may not add the sequence to
+ // the immediate queue even if this returns true.
+ bool WillPushImmediateTask();
- // Returns true if the task to be posted will change the sequence
- // delayed_queue top.
- bool TopDelayedTaskWillChange(Task& delayed_task) const;
-
- // Adds immediate |task| to the end of this sequence. This must only
- // be called after invoking ShouldBeQueued().
+ // Adds immediate |task| to the end of this sequence.
void PushImmediateTask(Task task);
- // Adds a delayed |task| in this sequence to be prioritized based on it's
- // delayed run time. This must only be called after invoking
- // TopDelayedTaskWillChange()/ShouldBeQueued().
- void PushDelayedTask(Task task);
+ // Adds a delayed |task| in this sequence, and returns true if the sequence
+ // needs to be re-enqueued in the delayed queue as a result of this
+ // sequence's delayed sort key changing.
+ bool PushDelayedTask(Task task);
Sequence* sequence() const { return static_cast<Sequence*>(task_source()); }
@@ -87,19 +79,6 @@ class BASE_EXPORT Sequence : public TaskSource {
explicit Transaction(Sequence* sequence);
};
- // This indicates where a sequence is stored, used by Sequence to keep track
- // of its status.
- enum class SequenceLocation {
- // Sequence is not present in any queue.
- kNone,
- // Sequence is present in queue of immediate sequences.
- kImmediateQueue,
- // Sequence is present in queue of delayed sequences.
- kDelayedQueue,
- // Sequence is being run by a worker.
- kInWorker,
- };
-
// |traits| is metadata that applies to all Tasks in the Sequence.
// |task_runner| is a reference to the TaskRunner feeding this TaskSource.
// |task_runner| can be nullptr only for tasks with no TaskRunner, in which
@@ -128,9 +107,13 @@ class BASE_EXPORT Sequence : public TaskSource {
return &sequence_local_storage_;
}
- SequenceLocation GetCurrentLocationForTesting();
+ bool OnBecomeReady() override;
- void OnBecomeReady() override;
+ bool has_worker_for_testing() const NO_THREAD_SAFETY_ANALYSIS {
+ return has_worker_;
+ }
+ bool is_immediate_for_testing() const { return is_immediate_; }
+ bool IsEmptyForTesting() const NO_THREAD_SAFETY_ANALYSIS { return IsEmpty(); }
private:
~Sequence() override;
@@ -147,30 +130,29 @@ class BASE_EXPORT Sequence : public TaskSource {
bool WillReEnqueue(TimeTicks now,
TaskSource::Transaction* transaction) override;
+ // Returns true if the delayed task to be posted will cause the delayed sort
+ // key to change.
+ bool DelayedSortKeyWillChange(const Task& delayed_task) const;
+
// Selects the earliest task to run, either from immediate or
// delayed queue and return it.
// Expects this sequence to have at least one task that can run
// immediately.
- Task TakeEarliestTask();
+ Task TakeEarliestTask() EXCLUSIVE_LOCKS_REQUIRED(lock_);
// Get and return next task from immediate queue
- Task TakeNextImmediateTask();
+ Task TakeNextImmediateTask() EXCLUSIVE_LOCKS_REQUIRED(lock_);
- // Determine next ready time and set ready time to it
- TimeTicks GetNextReadyTime();
+ // Update the next earliest/latest ready time.
+ void UpdateReadyTimes() EXCLUSIVE_LOCKS_REQUIRED(lock_);
// Returns true if there are immediate tasks
- bool HasImmediateTasks() const;
-
- // Returns true if there are tasks ripe for execution in the delayed queue
- bool HasRipeDelayedTasks(TimeTicks now) const;
+ bool HasImmediateTasks() const EXCLUSIVE_LOCKS_REQUIRED(lock_);
// Returns true if tasks ready to be executed
- bool HasReadyTasks(TimeTicks now) const;
-
- bool IsEmpty() const;
+ bool HasReadyTasks(TimeTicks now) const override;
- TimeTicks GetReadyTime() const;
+ bool IsEmpty() const EXCLUSIVE_LOCKS_REQUIRED(lock_);
// Releases reference to TaskRunner.
void ReleaseTaskRunner();
@@ -178,18 +160,33 @@ class BASE_EXPORT Sequence : public TaskSource {
const SequenceToken token_ = SequenceToken::Create();
// Queues of tasks to execute.
- base::queue<Task> queue_;
- base::IntrusiveHeap<Task, DelayedTaskGreater> delayed_queue_;
-
- std::atomic<TimeTicks> ready_time_{TimeTicks()};
+ base::queue<Task> queue_ GUARDED_BY(lock_);
+ base::IntrusiveHeap<Task, DelayedTaskGreater> delayed_queue_
+ GUARDED_BY(lock_);
+
+ // Caches the latest/earliest ready time for atomic access. Writes are
+ // protected by |lock_|, but allows atomic reads outside of |lock_|. If this
+ // sequence is empty, these are in an unknown state and shouldn't be read.
+
+ // Minimum of latest_delayed_run_time() of next delayed task if any, and
+ // |queue_time| of next immediate task if any.
+ std::atomic<TimeTicks> latest_ready_time_ GUARDED_BY(lock_){TimeTicks()};
+ // is_null() if there is an immediate task, or earliest_delayed_run_time() of
+ // next delayed task otherwise.
+ std::atomic<TimeTicks> earliest_ready_time_ GUARDED_BY(lock_){TimeTicks()};
+
+ // True if a worker is currently associated with a Task from this Sequence.
+ bool has_worker_ = false;
+
+ // True if the sequence has ready tasks and requested to be queued as such
+ // through WillPushImmediateTask() or OnBecomeReady(). Reset to false once all
+ // ready tasks are done being processed and either DidProcessTask() or
+ // WillReEnqueue() returned false. Normally, |is_immediate_| is protected by
+ // |lock_|, except in OnBecomeReady() hence the use of atomics.
+ std::atomic_bool is_immediate_{false};
// Holds data stored through the SequenceLocalStorageSlot API.
SequenceLocalStorageMap sequence_local_storage_;
-
- // This member will hold the current location of the sequence at any time.
- // At instantiation, the sequence is not put in any queue yet so the
- // sequence location is set to |kNone|.
- std::atomic<SequenceLocation> current_location_{SequenceLocation::kNone};
};
} // namespace internal