xref: /aosp_15_r20/external/libchrome/base/task_scheduler/sequence.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright 2016 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_TASK_SCHEDULER_SEQUENCE_H_
6*635a8641SAndroid Build Coastguard Worker #define BASE_TASK_SCHEDULER_SEQUENCE_H_
7*635a8641SAndroid Build Coastguard Worker 
8*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
9*635a8641SAndroid Build Coastguard Worker 
10*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h"
11*635a8641SAndroid Build Coastguard Worker #include "base/containers/queue.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/optional.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/sequence_token.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/task_scheduler/scheduler_lock.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/task_scheduler/sequence_sort_key.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/task_scheduler/task.h"
19*635a8641SAndroid Build Coastguard Worker #include "base/threading/sequence_local_storage_map.h"
20*635a8641SAndroid Build Coastguard Worker 
21*635a8641SAndroid Build Coastguard Worker namespace base {
22*635a8641SAndroid Build Coastguard Worker namespace internal {
23*635a8641SAndroid Build Coastguard Worker 
24*635a8641SAndroid Build Coastguard Worker // A Sequence holds slots each containing up to a single Task that must be
25*635a8641SAndroid Build Coastguard Worker // executed in posting order.
26*635a8641SAndroid Build Coastguard Worker //
27*635a8641SAndroid Build Coastguard Worker // In comments below, an "empty Sequence" is a Sequence with no slot.
28*635a8641SAndroid Build Coastguard Worker //
29*635a8641SAndroid Build Coastguard Worker // Note: there is a known refcounted-ownership cycle in the Scheduler
30*635a8641SAndroid Build Coastguard Worker // architecture: Sequence -> Task -> TaskRunner -> Sequence -> ...
31*635a8641SAndroid Build Coastguard Worker // This is okay so long as the other owners of Sequence (PriorityQueue and
32*635a8641SAndroid Build Coastguard Worker // SchedulerWorker in alternation and
33*635a8641SAndroid Build Coastguard Worker // SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl::GetWork()
34*635a8641SAndroid Build Coastguard Worker // temporarily) keep running it (and taking Tasks from it as a result). A
35*635a8641SAndroid Build Coastguard Worker // dangling reference cycle would only occur should they release their reference
36*635a8641SAndroid Build Coastguard Worker // to it while it's not empty. In other words, it is only correct for them to
37*635a8641SAndroid Build Coastguard Worker // release it after PopTask() returns false to indicate it was made empty by
38*635a8641SAndroid Build Coastguard Worker // that call (in which case the next PushTask() will return true to indicate to
39*635a8641SAndroid Build Coastguard Worker // the caller that the Sequence should be re-enqueued for execution).
40*635a8641SAndroid Build Coastguard Worker //
41*635a8641SAndroid Build Coastguard Worker // This class is thread-safe.
42*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT Sequence : public RefCountedThreadSafe<Sequence> {
43*635a8641SAndroid Build Coastguard Worker  public:
44*635a8641SAndroid Build Coastguard Worker   Sequence();
45*635a8641SAndroid Build Coastguard Worker 
46*635a8641SAndroid Build Coastguard Worker   // Adds |task| in a new slot at the end of the Sequence. Returns true if the
47*635a8641SAndroid Build Coastguard Worker   // Sequence was empty before this operation.
48*635a8641SAndroid Build Coastguard Worker   bool PushTask(Task task);
49*635a8641SAndroid Build Coastguard Worker 
50*635a8641SAndroid Build Coastguard Worker   // Transfers ownership of the Task in the front slot of the Sequence to the
51*635a8641SAndroid Build Coastguard Worker   // caller. The front slot of the Sequence will be nullptr and remain until
52*635a8641SAndroid Build Coastguard Worker   // Pop(). Cannot be called on an empty Sequence or a Sequence whose front slot
53*635a8641SAndroid Build Coastguard Worker   // is already nullptr.
54*635a8641SAndroid Build Coastguard Worker   //
55*635a8641SAndroid Build Coastguard Worker   // Because this method cannot be called on an empty Sequence, the returned
56*635a8641SAndroid Build Coastguard Worker   // Optional<Task> is never nullptr. An Optional is used in preparation for the
57*635a8641SAndroid Build Coastguard Worker   // merge between TaskScheduler and TaskQueueManager (in Blink).
58*635a8641SAndroid Build Coastguard Worker   // https://crbug.com/783309
59*635a8641SAndroid Build Coastguard Worker   Optional<Task> TakeTask();
60*635a8641SAndroid Build Coastguard Worker 
61*635a8641SAndroid Build Coastguard Worker   // Removes the front slot of the Sequence. The front slot must have been
62*635a8641SAndroid Build Coastguard Worker   // emptied by TakeTask() before this is called. Cannot be called on an empty
63*635a8641SAndroid Build Coastguard Worker   // Sequence. Returns true if the Sequence is empty after this operation.
64*635a8641SAndroid Build Coastguard Worker   bool Pop();
65*635a8641SAndroid Build Coastguard Worker 
66*635a8641SAndroid Build Coastguard Worker   // Returns a SequenceSortKey representing the priority of the Sequence. Cannot
67*635a8641SAndroid Build Coastguard Worker   // be called on an empty Sequence.
68*635a8641SAndroid Build Coastguard Worker   SequenceSortKey GetSortKey() const;
69*635a8641SAndroid Build Coastguard Worker 
70*635a8641SAndroid Build Coastguard Worker   // Returns a token that uniquely identifies this Sequence.
token()71*635a8641SAndroid Build Coastguard Worker   const SequenceToken& token() const { return token_; }
72*635a8641SAndroid Build Coastguard Worker 
sequence_local_storage()73*635a8641SAndroid Build Coastguard Worker   SequenceLocalStorageMap* sequence_local_storage() {
74*635a8641SAndroid Build Coastguard Worker     return &sequence_local_storage_;
75*635a8641SAndroid Build Coastguard Worker   }
76*635a8641SAndroid Build Coastguard Worker 
77*635a8641SAndroid Build Coastguard Worker  private:
78*635a8641SAndroid Build Coastguard Worker   friend class RefCountedThreadSafe<Sequence>;
79*635a8641SAndroid Build Coastguard Worker   ~Sequence();
80*635a8641SAndroid Build Coastguard Worker 
81*635a8641SAndroid Build Coastguard Worker   const SequenceToken token_ = SequenceToken::Create();
82*635a8641SAndroid Build Coastguard Worker 
83*635a8641SAndroid Build Coastguard Worker   // Synchronizes access to all members.
84*635a8641SAndroid Build Coastguard Worker   mutable SchedulerLock lock_;
85*635a8641SAndroid Build Coastguard Worker 
86*635a8641SAndroid Build Coastguard Worker   // Queue of tasks to execute.
87*635a8641SAndroid Build Coastguard Worker   base::queue<Task> queue_;
88*635a8641SAndroid Build Coastguard Worker 
89*635a8641SAndroid Build Coastguard Worker   // Number of tasks contained in the Sequence for each priority.
90*635a8641SAndroid Build Coastguard Worker   size_t num_tasks_per_priority_[static_cast<int>(TaskPriority::HIGHEST) + 1] =
91*635a8641SAndroid Build Coastguard Worker       {};
92*635a8641SAndroid Build Coastguard Worker 
93*635a8641SAndroid Build Coastguard Worker   // Holds data stored through the SequenceLocalStorageSlot API.
94*635a8641SAndroid Build Coastguard Worker   SequenceLocalStorageMap sequence_local_storage_;
95*635a8641SAndroid Build Coastguard Worker 
96*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(Sequence);
97*635a8641SAndroid Build Coastguard Worker };
98*635a8641SAndroid Build Coastguard Worker 
99*635a8641SAndroid Build Coastguard Worker }  // namespace internal
100*635a8641SAndroid Build Coastguard Worker }  // namespace base
101*635a8641SAndroid Build Coastguard Worker 
102*635a8641SAndroid Build Coastguard Worker #endif  // BASE_TASK_SCHEDULER_SEQUENCE_H_
103