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_TASK_TRACKER_H_ 6*635a8641SAndroid Build Coastguard Worker #define BASE_TASK_SCHEDULER_TASK_TRACKER_H_ 7*635a8641SAndroid Build Coastguard Worker 8*635a8641SAndroid Build Coastguard Worker #include <functional> 9*635a8641SAndroid Build Coastguard Worker #include <memory> 10*635a8641SAndroid Build Coastguard Worker #include <queue> 11*635a8641SAndroid Build Coastguard Worker 12*635a8641SAndroid Build Coastguard Worker #include "base/atomicops.h" 13*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h" 14*635a8641SAndroid Build Coastguard Worker #include "base/callback_forward.h" 15*635a8641SAndroid Build Coastguard Worker #include "base/debug/task_annotator.h" 16*635a8641SAndroid Build Coastguard Worker #include "base/logging.h" 17*635a8641SAndroid Build Coastguard Worker #include "base/macros.h" 18*635a8641SAndroid Build Coastguard Worker #include "base/metrics/histogram_base.h" 19*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_piece.h" 20*635a8641SAndroid Build Coastguard Worker #include "base/synchronization/waitable_event.h" 21*635a8641SAndroid Build Coastguard Worker #include "base/task_scheduler/can_schedule_sequence_observer.h" 22*635a8641SAndroid Build Coastguard Worker #include "base/task_scheduler/scheduler_lock.h" 23*635a8641SAndroid Build Coastguard Worker #include "base/task_scheduler/sequence.h" 24*635a8641SAndroid Build Coastguard Worker #include "base/task_scheduler/task.h" 25*635a8641SAndroid Build Coastguard Worker #include "base/task_scheduler/task_traits.h" 26*635a8641SAndroid Build Coastguard Worker #include "base/task_scheduler/tracked_ref.h" 27*635a8641SAndroid Build Coastguard Worker 28*635a8641SAndroid Build Coastguard Worker namespace base { 29*635a8641SAndroid Build Coastguard Worker 30*635a8641SAndroid Build Coastguard Worker class ConditionVariable; 31*635a8641SAndroid Build Coastguard Worker class HistogramBase; 32*635a8641SAndroid Build Coastguard Worker 33*635a8641SAndroid Build Coastguard Worker namespace internal { 34*635a8641SAndroid Build Coastguard Worker 35*635a8641SAndroid Build Coastguard Worker // TaskTracker enforces policies that determines whether: 36*635a8641SAndroid Build Coastguard Worker // - A task can be added to a sequence (WillPostTask). 37*635a8641SAndroid Build Coastguard Worker // - A sequence can be scheduled (WillScheduleSequence). 38*635a8641SAndroid Build Coastguard Worker // - The next task in a scheduled sequence can run (RunAndPopNextTask). 39*635a8641SAndroid Build Coastguard Worker // TaskTracker also sets up the environment to run a task (RunAndPopNextTask) 40*635a8641SAndroid Build Coastguard Worker // and records metrics and trace events. This class is thread-safe. 41*635a8641SAndroid Build Coastguard Worker // 42*635a8641SAndroid Build Coastguard Worker // Life of a sequence: 43*635a8641SAndroid Build Coastguard Worker // (possible states: IDLE, PREEMPTED, SCHEDULED, RUNNING) 44*635a8641SAndroid Build Coastguard Worker // 45*635a8641SAndroid Build Coastguard Worker // Create a sequence 46*635a8641SAndroid Build Coastguard Worker // | 47*635a8641SAndroid Build Coastguard Worker // ------------------------> Sequence is IDLE 48*635a8641SAndroid Build Coastguard Worker // | | 49*635a8641SAndroid Build Coastguard Worker // | Add a task to the sequence 50*635a8641SAndroid Build Coastguard Worker // | (allowed by TaskTracker::WillPostTask) 51*635a8641SAndroid Build Coastguard Worker // | | 52*635a8641SAndroid Build Coastguard Worker // | TaskTracker:WillScheduleSequence 53*635a8641SAndroid Build Coastguard Worker // | _____________________|_____________________ 54*635a8641SAndroid Build Coastguard Worker // | | | 55*635a8641SAndroid Build Coastguard Worker // | Returns true Returns false 56*635a8641SAndroid Build Coastguard Worker // | | | 57*635a8641SAndroid Build Coastguard Worker // | | Sequence is PREEMPTED <---- 58*635a8641SAndroid Build Coastguard Worker // | | | | 59*635a8641SAndroid Build Coastguard Worker // | | Eventually, | 60*635a8641SAndroid Build Coastguard Worker // | | CanScheduleSequenceObserver | 61*635a8641SAndroid Build Coastguard Worker // | | is notified that the | 62*635a8641SAndroid Build Coastguard Worker // | | sequence can be scheduled. | 63*635a8641SAndroid Build Coastguard Worker // | |__________________________________________| | 64*635a8641SAndroid Build Coastguard Worker // | | | 65*635a8641SAndroid Build Coastguard Worker // | (*) Sequence is SCHEDULED | 66*635a8641SAndroid Build Coastguard Worker // | | | 67*635a8641SAndroid Build Coastguard Worker // | A thread is ready to run the next | 68*635a8641SAndroid Build Coastguard Worker // | task in the sequence | 69*635a8641SAndroid Build Coastguard Worker // | | | 70*635a8641SAndroid Build Coastguard Worker // | TaskTracker::RunAndPopNextTask | 71*635a8641SAndroid Build Coastguard Worker // | A task from the sequence is run | 72*635a8641SAndroid Build Coastguard Worker // | Sequence is RUNNING | 73*635a8641SAndroid Build Coastguard Worker // | | | 74*635a8641SAndroid Build Coastguard Worker // | ______________________|____ | 75*635a8641SAndroid Build Coastguard Worker // | | | | 76*635a8641SAndroid Build Coastguard Worker // | Sequence is empty Sequence has more tasks | 77*635a8641SAndroid Build Coastguard Worker // |_________| _____________|_______________ | 78*635a8641SAndroid Build Coastguard Worker // | | | 79*635a8641SAndroid Build Coastguard Worker // Sequence can be Sequence cannot be | 80*635a8641SAndroid Build Coastguard Worker // scheduled scheduled at this | 81*635a8641SAndroid Build Coastguard Worker // | moment | 82*635a8641SAndroid Build Coastguard Worker // Go back to (*) |_________________| 83*635a8641SAndroid Build Coastguard Worker // 84*635a8641SAndroid Build Coastguard Worker // 85*635a8641SAndroid Build Coastguard Worker // Note: A background task is a task posted with TaskPriority::BACKGROUND. A 86*635a8641SAndroid Build Coastguard Worker // foreground task is a task posted with TaskPriority::USER_VISIBLE or 87*635a8641SAndroid Build Coastguard Worker // TaskPriority::USER_BLOCKING. 88*635a8641SAndroid Build Coastguard Worker // 89*635a8641SAndroid Build Coastguard Worker // TODO(fdoray): We want to allow disabling TaskPriority::BACKGROUND tasks in a 90*635a8641SAndroid Build Coastguard Worker // scope (e.g. during startup or page load), but we don't need a dynamic maximum 91*635a8641SAndroid Build Coastguard Worker // number of background tasks. The code could probably be simplified if it 92*635a8641SAndroid Build Coastguard Worker // didn't support that. https://crbug.com/831835 93*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT TaskTracker { 94*635a8641SAndroid Build Coastguard Worker public: 95*635a8641SAndroid Build Coastguard Worker // |histogram_label| is used as a suffix for histograms, it must not be empty. 96*635a8641SAndroid Build Coastguard Worker // The first constructor sets the maximum number of TaskPriority::BACKGROUND 97*635a8641SAndroid Build Coastguard Worker // sequences that can be scheduled concurrently to 0 if the 98*635a8641SAndroid Build Coastguard Worker // --disable-background-tasks flag is specified, max() otherwise. The second 99*635a8641SAndroid Build Coastguard Worker // constructor sets it to |max_num_scheduled_background_sequences|. 100*635a8641SAndroid Build Coastguard Worker TaskTracker(StringPiece histogram_label); 101*635a8641SAndroid Build Coastguard Worker TaskTracker(StringPiece histogram_label, 102*635a8641SAndroid Build Coastguard Worker int max_num_scheduled_background_sequences); 103*635a8641SAndroid Build Coastguard Worker 104*635a8641SAndroid Build Coastguard Worker virtual ~TaskTracker(); 105*635a8641SAndroid Build Coastguard Worker 106*635a8641SAndroid Build Coastguard Worker // Synchronously shuts down the scheduler. Once this is called, only tasks 107*635a8641SAndroid Build Coastguard Worker // posted with the BLOCK_SHUTDOWN behavior will be run. Returns when: 108*635a8641SAndroid Build Coastguard Worker // - All SKIP_ON_SHUTDOWN tasks that were already running have completed their 109*635a8641SAndroid Build Coastguard Worker // execution. 110*635a8641SAndroid Build Coastguard Worker // - All posted BLOCK_SHUTDOWN tasks have completed their execution. 111*635a8641SAndroid Build Coastguard Worker // CONTINUE_ON_SHUTDOWN tasks still may be running after Shutdown returns. 112*635a8641SAndroid Build Coastguard Worker // This can only be called once. 113*635a8641SAndroid Build Coastguard Worker void Shutdown(); 114*635a8641SAndroid Build Coastguard Worker 115*635a8641SAndroid Build Coastguard Worker // Waits until there are no incomplete undelayed tasks. May be called in tests 116*635a8641SAndroid Build Coastguard Worker // to validate that a condition is met after all undelayed tasks have run. 117*635a8641SAndroid Build Coastguard Worker // 118*635a8641SAndroid Build Coastguard Worker // Does not wait for delayed tasks. Waits for undelayed tasks posted from 119*635a8641SAndroid Build Coastguard Worker // other threads during the call. Returns immediately when shutdown completes. 120*635a8641SAndroid Build Coastguard Worker void FlushForTesting(); 121*635a8641SAndroid Build Coastguard Worker 122*635a8641SAndroid Build Coastguard Worker // Returns and calls |flush_callback| when there are no incomplete undelayed 123*635a8641SAndroid Build Coastguard Worker // tasks. |flush_callback| may be called back on any thread and should not 124*635a8641SAndroid Build Coastguard Worker // perform a lot of work. May be used when additional work on the current 125*635a8641SAndroid Build Coastguard Worker // thread needs to be performed during a flush. Only one 126*635a8641SAndroid Build Coastguard Worker // FlushAsyncForTesting() may be pending at any given time. 127*635a8641SAndroid Build Coastguard Worker void FlushAsyncForTesting(OnceClosure flush_callback); 128*635a8641SAndroid Build Coastguard Worker 129*635a8641SAndroid Build Coastguard Worker // Informs this TaskTracker that |task| is about to be posted. Returns true if 130*635a8641SAndroid Build Coastguard Worker // this operation is allowed (|task| should be posted if-and-only-if it is). 131*635a8641SAndroid Build Coastguard Worker // This method may also modify metadata on |task| if desired. 132*635a8641SAndroid Build Coastguard Worker bool WillPostTask(Task* task); 133*635a8641SAndroid Build Coastguard Worker 134*635a8641SAndroid Build Coastguard Worker // Informs this TaskTracker that |sequence| is about to be scheduled. If this 135*635a8641SAndroid Build Coastguard Worker // returns |sequence|, it is expected that RunAndPopNextTask() will soon be 136*635a8641SAndroid Build Coastguard Worker // called with |sequence| as argument. Otherwise, RunAndPopNextTask() must not 137*635a8641SAndroid Build Coastguard Worker // be called with |sequence| as argument until |observer| is notified that 138*635a8641SAndroid Build Coastguard Worker // |sequence| can be scheduled (the caller doesn't need to keep a pointer to 139*635a8641SAndroid Build Coastguard Worker // |sequence|; it will be included in the notification to |observer|). 140*635a8641SAndroid Build Coastguard Worker // WillPostTask() must have allowed the task in front of |sequence| to be 141*635a8641SAndroid Build Coastguard Worker // posted before this is called. |observer| is only required if the priority 142*635a8641SAndroid Build Coastguard Worker // of |sequence| is TaskPriority::BACKGROUND 143*635a8641SAndroid Build Coastguard Worker scoped_refptr<Sequence> WillScheduleSequence( 144*635a8641SAndroid Build Coastguard Worker scoped_refptr<Sequence> sequence, 145*635a8641SAndroid Build Coastguard Worker CanScheduleSequenceObserver* observer); 146*635a8641SAndroid Build Coastguard Worker 147*635a8641SAndroid Build Coastguard Worker // Runs the next task in |sequence| unless the current shutdown state prevents 148*635a8641SAndroid Build Coastguard Worker // that. Then, pops the task from |sequence| (even if it didn't run). Returns 149*635a8641SAndroid Build Coastguard Worker // |sequence| if it can be rescheduled immediately. If |sequence| is non-empty 150*635a8641SAndroid Build Coastguard Worker // after popping a task from it but it can't be rescheduled immediately, it 151*635a8641SAndroid Build Coastguard Worker // will be handed back to |observer| when it can be rescheduled. 152*635a8641SAndroid Build Coastguard Worker // WillPostTask() must have allowed the task in front of |sequence| to be 153*635a8641SAndroid Build Coastguard Worker // posted before this is called. Also, WillScheduleSequence(), 154*635a8641SAndroid Build Coastguard Worker // RunAndPopNextTask() or CanScheduleSequenceObserver::OnCanScheduleSequence() 155*635a8641SAndroid Build Coastguard Worker // must have allowed |sequence| to be (re)scheduled. 156*635a8641SAndroid Build Coastguard Worker scoped_refptr<Sequence> RunAndPopNextTask( 157*635a8641SAndroid Build Coastguard Worker scoped_refptr<Sequence> sequence, 158*635a8641SAndroid Build Coastguard Worker CanScheduleSequenceObserver* observer); 159*635a8641SAndroid Build Coastguard Worker 160*635a8641SAndroid Build Coastguard Worker // Returns true once shutdown has started (Shutdown() has been called but 161*635a8641SAndroid Build Coastguard Worker // might not have returned). Note: sequential consistency with the thread 162*635a8641SAndroid Build Coastguard Worker // calling Shutdown() (or SetHasShutdownStartedForTesting()) isn't guaranteed 163*635a8641SAndroid Build Coastguard Worker // by this call. 164*635a8641SAndroid Build Coastguard Worker bool HasShutdownStarted() const; 165*635a8641SAndroid Build Coastguard Worker 166*635a8641SAndroid Build Coastguard Worker // Returns true if shutdown has completed (Shutdown() has returned). 167*635a8641SAndroid Build Coastguard Worker bool IsShutdownComplete() const; 168*635a8641SAndroid Build Coastguard Worker 169*635a8641SAndroid Build Coastguard Worker enum class LatencyHistogramType { 170*635a8641SAndroid Build Coastguard Worker // Records the latency of each individual task posted through TaskTracker. 171*635a8641SAndroid Build Coastguard Worker TASK_LATENCY, 172*635a8641SAndroid Build Coastguard Worker // Records the latency of heartbeat tasks which are independent of current 173*635a8641SAndroid Build Coastguard Worker // workload. These avoid a bias towards TASK_LATENCY reporting that high- 174*635a8641SAndroid Build Coastguard Worker // priority tasks are "slower" than regular tasks because high-priority 175*635a8641SAndroid Build Coastguard Worker // tasks tend to be correlated with heavy workloads. 176*635a8641SAndroid Build Coastguard Worker HEARTBEAT_LATENCY, 177*635a8641SAndroid Build Coastguard Worker }; 178*635a8641SAndroid Build Coastguard Worker 179*635a8641SAndroid Build Coastguard Worker // Causes HasShutdownStarted() to return true. Unlike when Shutdown() returns, 180*635a8641SAndroid Build Coastguard Worker // IsShutdownComplete() won't return true after this returns. Shutdown() 181*635a8641SAndroid Build Coastguard Worker // cannot be called after this. 182*635a8641SAndroid Build Coastguard Worker void SetHasShutdownStartedForTesting(); 183*635a8641SAndroid Build Coastguard Worker 184*635a8641SAndroid Build Coastguard Worker // Records |Now() - posted_time| to the appropriate |latency_histogram_type| 185*635a8641SAndroid Build Coastguard Worker // based on |task_traits|. 186*635a8641SAndroid Build Coastguard Worker void RecordLatencyHistogram(LatencyHistogramType latency_histogram_type, 187*635a8641SAndroid Build Coastguard Worker TaskTraits task_traits, 188*635a8641SAndroid Build Coastguard Worker TimeTicks posted_time) const; 189*635a8641SAndroid Build Coastguard Worker GetTrackedRef()190*635a8641SAndroid Build Coastguard Worker TrackedRef<TaskTracker> GetTrackedRef() { 191*635a8641SAndroid Build Coastguard Worker return tracked_ref_factory_.GetTrackedRef(); 192*635a8641SAndroid Build Coastguard Worker } 193*635a8641SAndroid Build Coastguard Worker 194*635a8641SAndroid Build Coastguard Worker protected: 195*635a8641SAndroid Build Coastguard Worker // Runs and deletes |task| if |can_run_task| is true. Otherwise, just deletes 196*635a8641SAndroid Build Coastguard Worker // |task|. |task| is always deleted in the environment where it runs or would 197*635a8641SAndroid Build Coastguard Worker // have run. |sequence| is the sequence from which |task| was extracted. An 198*635a8641SAndroid Build Coastguard Worker // override is expected to call its parent's implementation but is free to 199*635a8641SAndroid Build Coastguard Worker // perform extra work before and after doing so. 200*635a8641SAndroid Build Coastguard Worker virtual void RunOrSkipTask(Task task, Sequence* sequence, bool can_run_task); 201*635a8641SAndroid Build Coastguard Worker 202*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 203*635a8641SAndroid Build Coastguard Worker // Returns true if this context should be exempt from blocking shutdown 204*635a8641SAndroid Build Coastguard Worker // DCHECKs. 205*635a8641SAndroid Build Coastguard Worker // TODO(robliao): Remove when http://crbug.com/698140 is fixed. 206*635a8641SAndroid Build Coastguard Worker virtual bool IsPostingBlockShutdownTaskAfterShutdownAllowed(); 207*635a8641SAndroid Build Coastguard Worker #endif 208*635a8641SAndroid Build Coastguard Worker 209*635a8641SAndroid Build Coastguard Worker // Returns true if there are undelayed tasks that haven't completed their 210*635a8641SAndroid Build Coastguard Worker // execution (still queued or in progress). If it returns false: the side- 211*635a8641SAndroid Build Coastguard Worker // effects of all completed tasks are guaranteed to be visible to the caller. 212*635a8641SAndroid Build Coastguard Worker bool HasIncompleteUndelayedTasksForTesting() const; 213*635a8641SAndroid Build Coastguard Worker 214*635a8641SAndroid Build Coastguard Worker private: 215*635a8641SAndroid Build Coastguard Worker class State; 216*635a8641SAndroid Build Coastguard Worker struct PreemptedBackgroundSequence; 217*635a8641SAndroid Build Coastguard Worker 218*635a8641SAndroid Build Coastguard Worker void PerformShutdown(); 219*635a8641SAndroid Build Coastguard Worker 220*635a8641SAndroid Build Coastguard Worker // Updates the maximum number of background sequences that can be scheduled 221*635a8641SAndroid Build Coastguard Worker // concurrently to |max_num_scheduled_background_sequences|. Then, schedules 222*635a8641SAndroid Build Coastguard Worker // as many preempted background sequences as allowed by the new value. 223*635a8641SAndroid Build Coastguard Worker void SetMaxNumScheduledBackgroundSequences( 224*635a8641SAndroid Build Coastguard Worker int max_num_scheduled_background_sequences); 225*635a8641SAndroid Build Coastguard Worker 226*635a8641SAndroid Build Coastguard Worker // Pops the next sequence in |preempted_background_sequences_| and increments 227*635a8641SAndroid Build Coastguard Worker // |num_scheduled_background_sequences_|. Must only be called in the scope of 228*635a8641SAndroid Build Coastguard Worker // |background_lock_|, with |preempted_background_sequences_| non-empty. The 229*635a8641SAndroid Build Coastguard Worker // caller must forward the returned sequence to the associated 230*635a8641SAndroid Build Coastguard Worker // CanScheduleSequenceObserver as soon as |background_lock_| is released. 231*635a8641SAndroid Build Coastguard Worker PreemptedBackgroundSequence 232*635a8641SAndroid Build Coastguard Worker GetPreemptedBackgroundSequenceToScheduleLockRequired(); 233*635a8641SAndroid Build Coastguard Worker 234*635a8641SAndroid Build Coastguard Worker // Schedules |sequence_to_schedule.sequence| using 235*635a8641SAndroid Build Coastguard Worker // |sequence_to_schedule.observer|. Does not verify that the sequence is 236*635a8641SAndroid Build Coastguard Worker // allowed to be scheduled. 237*635a8641SAndroid Build Coastguard Worker void SchedulePreemptedBackgroundSequence( 238*635a8641SAndroid Build Coastguard Worker PreemptedBackgroundSequence sequence_to_schedule); 239*635a8641SAndroid Build Coastguard Worker 240*635a8641SAndroid Build Coastguard Worker // Called before WillPostTask() informs the tracing system that a task has 241*635a8641SAndroid Build Coastguard Worker // been posted. Updates |num_tasks_blocking_shutdown_| if necessary and 242*635a8641SAndroid Build Coastguard Worker // returns true if the current shutdown state allows the task to be posted. 243*635a8641SAndroid Build Coastguard Worker bool BeforePostTask(TaskShutdownBehavior shutdown_behavior); 244*635a8641SAndroid Build Coastguard Worker 245*635a8641SAndroid Build Coastguard Worker // Called before a task with |shutdown_behavior| is run by RunTask(). Updates 246*635a8641SAndroid Build Coastguard Worker // |num_tasks_blocking_shutdown_| if necessary and returns true if the current 247*635a8641SAndroid Build Coastguard Worker // shutdown state allows the task to be run. 248*635a8641SAndroid Build Coastguard Worker bool BeforeRunTask(TaskShutdownBehavior shutdown_behavior); 249*635a8641SAndroid Build Coastguard Worker 250*635a8641SAndroid Build Coastguard Worker // Called after a task with |shutdown_behavior| has been run by RunTask(). 251*635a8641SAndroid Build Coastguard Worker // Updates |num_tasks_blocking_shutdown_| and signals |shutdown_cv_| if 252*635a8641SAndroid Build Coastguard Worker // necessary. 253*635a8641SAndroid Build Coastguard Worker void AfterRunTask(TaskShutdownBehavior shutdown_behavior); 254*635a8641SAndroid Build Coastguard Worker 255*635a8641SAndroid Build Coastguard Worker // Called when the number of tasks blocking shutdown becomes zero after 256*635a8641SAndroid Build Coastguard Worker // shutdown has started. 257*635a8641SAndroid Build Coastguard Worker void OnBlockingShutdownTasksComplete(); 258*635a8641SAndroid Build Coastguard Worker 259*635a8641SAndroid Build Coastguard Worker // Decrements the number of incomplete undelayed tasks and signals |flush_cv_| 260*635a8641SAndroid Build Coastguard Worker // if it reaches zero. 261*635a8641SAndroid Build Coastguard Worker void DecrementNumIncompleteUndelayedTasks(); 262*635a8641SAndroid Build Coastguard Worker 263*635a8641SAndroid Build Coastguard Worker // To be called after running a background task from |just_ran_sequence|. 264*635a8641SAndroid Build Coastguard Worker // Performs the following actions: 265*635a8641SAndroid Build Coastguard Worker // - If |just_ran_sequence| is non-null: 266*635a8641SAndroid Build Coastguard Worker // - returns it if it should be rescheduled by the caller of 267*635a8641SAndroid Build Coastguard Worker // RunAndPopNextTask(), i.e. its next task is set to run earlier than the 268*635a8641SAndroid Build Coastguard Worker // earliest currently preempted sequence. 269*635a8641SAndroid Build Coastguard Worker // - Otherwise |just_ran_sequence| is preempted and the next preempted 270*635a8641SAndroid Build Coastguard Worker // sequence is scheduled (|observer| will be notified when 271*635a8641SAndroid Build Coastguard Worker // |just_ran_sequence| should be scheduled again). 272*635a8641SAndroid Build Coastguard Worker // - If |just_ran_sequence| is null (RunAndPopNextTask() just popped the last 273*635a8641SAndroid Build Coastguard Worker // task from it): 274*635a8641SAndroid Build Coastguard Worker // - the next preempeted sequence (if any) is scheduled. 275*635a8641SAndroid Build Coastguard Worker // - In all cases: adjusts the number of scheduled background sequences 276*635a8641SAndroid Build Coastguard Worker // accordingly. 277*635a8641SAndroid Build Coastguard Worker scoped_refptr<Sequence> ManageBackgroundSequencesAfterRunningTask( 278*635a8641SAndroid Build Coastguard Worker scoped_refptr<Sequence> just_ran_sequence, 279*635a8641SAndroid Build Coastguard Worker CanScheduleSequenceObserver* observer); 280*635a8641SAndroid Build Coastguard Worker 281*635a8641SAndroid Build Coastguard Worker // Calls |flush_callback_for_testing_| if one is available in a lock-safe 282*635a8641SAndroid Build Coastguard Worker // manner. 283*635a8641SAndroid Build Coastguard Worker void CallFlushCallbackForTesting(); 284*635a8641SAndroid Build Coastguard Worker 285*635a8641SAndroid Build Coastguard Worker debug::TaskAnnotator task_annotator_; 286*635a8641SAndroid Build Coastguard Worker 287*635a8641SAndroid Build Coastguard Worker // Number of tasks blocking shutdown and boolean indicating whether shutdown 288*635a8641SAndroid Build Coastguard Worker // has started. 289*635a8641SAndroid Build Coastguard Worker const std::unique_ptr<State> state_; 290*635a8641SAndroid Build Coastguard Worker 291*635a8641SAndroid Build Coastguard Worker // Number of undelayed tasks that haven't completed their execution. Is 292*635a8641SAndroid Build Coastguard Worker // decremented with a memory barrier after a task runs. Is accessed with an 293*635a8641SAndroid Build Coastguard Worker // acquire memory barrier in FlushForTesting(). The memory barriers ensure 294*635a8641SAndroid Build Coastguard Worker // that the memory written by flushed tasks is visible when FlushForTesting() 295*635a8641SAndroid Build Coastguard Worker // returns. 296*635a8641SAndroid Build Coastguard Worker subtle::Atomic32 num_incomplete_undelayed_tasks_ = 0; 297*635a8641SAndroid Build Coastguard Worker 298*635a8641SAndroid Build Coastguard Worker // Lock associated with |flush_cv_|. Partially synchronizes access to 299*635a8641SAndroid Build Coastguard Worker // |num_incomplete_undelayed_tasks_|. Full synchronization isn't needed 300*635a8641SAndroid Build Coastguard Worker // because it's atomic, but synchronization is needed to coordinate waking and 301*635a8641SAndroid Build Coastguard Worker // sleeping at the right time. Fully synchronizes access to 302*635a8641SAndroid Build Coastguard Worker // |flush_callback_for_testing_|. 303*635a8641SAndroid Build Coastguard Worker mutable SchedulerLock flush_lock_; 304*635a8641SAndroid Build Coastguard Worker 305*635a8641SAndroid Build Coastguard Worker // Signaled when |num_incomplete_undelayed_tasks_| is or reaches zero or when 306*635a8641SAndroid Build Coastguard Worker // shutdown completes. 307*635a8641SAndroid Build Coastguard Worker const std::unique_ptr<ConditionVariable> flush_cv_; 308*635a8641SAndroid Build Coastguard Worker 309*635a8641SAndroid Build Coastguard Worker // Invoked if non-null when |num_incomplete_undelayed_tasks_| is zero or when 310*635a8641SAndroid Build Coastguard Worker // shutdown completes. 311*635a8641SAndroid Build Coastguard Worker OnceClosure flush_callback_for_testing_; 312*635a8641SAndroid Build Coastguard Worker 313*635a8641SAndroid Build Coastguard Worker // Synchronizes access to shutdown related members below. 314*635a8641SAndroid Build Coastguard Worker mutable SchedulerLock shutdown_lock_; 315*635a8641SAndroid Build Coastguard Worker 316*635a8641SAndroid Build Coastguard Worker // Event instantiated when shutdown starts and signaled when shutdown 317*635a8641SAndroid Build Coastguard Worker // completes. 318*635a8641SAndroid Build Coastguard Worker std::unique_ptr<WaitableEvent> shutdown_event_; 319*635a8641SAndroid Build Coastguard Worker 320*635a8641SAndroid Build Coastguard Worker // Synchronizes accesses to |preempted_background_sequences_|, 321*635a8641SAndroid Build Coastguard Worker // |max_num_scheduled_background_sequences_| and 322*635a8641SAndroid Build Coastguard Worker // |num_scheduled_background_sequences_|. 323*635a8641SAndroid Build Coastguard Worker SchedulerLock background_lock_; 324*635a8641SAndroid Build Coastguard Worker 325*635a8641SAndroid Build Coastguard Worker // A priority queue of sequences that are waiting to be scheduled. Use 326*635a8641SAndroid Build Coastguard Worker // std::greater so that the sequence which contains the task that has been 327*635a8641SAndroid Build Coastguard Worker // posted the earliest is on top of the priority queue. 328*635a8641SAndroid Build Coastguard Worker std::priority_queue<PreemptedBackgroundSequence, 329*635a8641SAndroid Build Coastguard Worker std::vector<PreemptedBackgroundSequence>, 330*635a8641SAndroid Build Coastguard Worker std::greater<PreemptedBackgroundSequence>> 331*635a8641SAndroid Build Coastguard Worker preempted_background_sequences_; 332*635a8641SAndroid Build Coastguard Worker 333*635a8641SAndroid Build Coastguard Worker // Maximum number of background sequences that can that be scheduled 334*635a8641SAndroid Build Coastguard Worker // concurrently. 335*635a8641SAndroid Build Coastguard Worker int max_num_scheduled_background_sequences_; 336*635a8641SAndroid Build Coastguard Worker 337*635a8641SAndroid Build Coastguard Worker // Number of currently scheduled background sequences. 338*635a8641SAndroid Build Coastguard Worker int num_scheduled_background_sequences_ = 0; 339*635a8641SAndroid Build Coastguard Worker 340*635a8641SAndroid Build Coastguard Worker // TaskScheduler.TaskLatencyMicroseconds.* and 341*635a8641SAndroid Build Coastguard Worker // TaskScheduler.HeartbeatLatencyMicroseconds.* histograms. The first index is 342*635a8641SAndroid Build Coastguard Worker // a TaskPriority. The second index is 0 for non-blocking tasks, 1 for 343*635a8641SAndroid Build Coastguard Worker // blocking tasks. Intentionally leaked. 344*635a8641SAndroid Build Coastguard Worker // TODO(scheduler-dev): Consider using STATIC_HISTOGRAM_POINTER_GROUP for 345*635a8641SAndroid Build Coastguard Worker // these. 346*635a8641SAndroid Build Coastguard Worker static constexpr int kNumTaskPriorities = 347*635a8641SAndroid Build Coastguard Worker static_cast<int>(TaskPriority::HIGHEST) + 1; 348*635a8641SAndroid Build Coastguard Worker HistogramBase* const task_latency_histograms_[kNumTaskPriorities][2]; 349*635a8641SAndroid Build Coastguard Worker HistogramBase* const heartbeat_latency_histograms_[kNumTaskPriorities][2]; 350*635a8641SAndroid Build Coastguard Worker 351*635a8641SAndroid Build Coastguard Worker // Number of BLOCK_SHUTDOWN tasks posted during shutdown. 352*635a8641SAndroid Build Coastguard Worker HistogramBase::Sample num_block_shutdown_tasks_posted_during_shutdown_ = 0; 353*635a8641SAndroid Build Coastguard Worker 354*635a8641SAndroid Build Coastguard Worker // Ensures all state (e.g. dangling cleaned up workers) is coalesced before 355*635a8641SAndroid Build Coastguard Worker // destroying the TaskTracker (e.g. in test environments). 356*635a8641SAndroid Build Coastguard Worker // Ref. https://crbug.com/827615. 357*635a8641SAndroid Build Coastguard Worker TrackedRefFactory<TaskTracker> tracked_ref_factory_; 358*635a8641SAndroid Build Coastguard Worker 359*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(TaskTracker); 360*635a8641SAndroid Build Coastguard Worker }; 361*635a8641SAndroid Build Coastguard Worker 362*635a8641SAndroid Build Coastguard Worker } // namespace internal 363*635a8641SAndroid Build Coastguard Worker } // namespace base 364*635a8641SAndroid Build Coastguard Worker 365*635a8641SAndroid Build Coastguard Worker #endif // BASE_TASK_SCHEDULER_TASK_TRACKER_H_ 366