1 // Copyright 2018 The Chromium Authors. All rights reserved. 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_SEQUENCE_MANAGER_H_ 6 #define BASE_TASK_SEQUENCE_MANAGER_SEQUENCE_MANAGER_H_ 7 8 #include <memory> 9 #include <utility> 10 11 #include "base/message_loop/message_loop.h" 12 #include "base/single_thread_task_runner.h" 13 #include "base/task/sequence_manager/task_queue_impl.h" 14 #include "base/task/sequence_manager/task_time_observer.h" 15 16 namespace base { 17 namespace sequence_manager { 18 19 class TimeDomain; 20 21 // SequenceManager manages TaskQueues which have different properties 22 // (e.g. priority, common task type) multiplexing all posted tasks into 23 // a single backing sequence (currently bound to a single thread, which is 24 // refererred as *main thread* in the comments below). SequenceManager 25 // implementation can be used in a various ways to apply scheduling logic. 26 class SequenceManager { 27 public: 28 class Observer { 29 public: 30 virtual ~Observer() = default; 31 // Called back on the main thread. 32 virtual void OnBeginNestedRunLoop() = 0; 33 virtual void OnExitNestedRunLoop() = 0; 34 }; 35 36 struct MetricRecordingSettings { 37 MetricRecordingSettings(); 38 // Note: These parameters are desired and MetricRecordingSetting's will 39 // update them for consistency (e.g. setting values to false when 40 // ThreadTicks are not supported). 41 MetricRecordingSettings(bool records_cpu_time_for_each_task, 42 double task_sampling_rate_for_recording_cpu_time); 43 44 // True if cpu time is measured for each task, so the integral 45 // metrics (as opposed to per-task metrics) can be recorded. 46 bool records_cpu_time_for_each_task = false; 47 // The proportion of the tasks for which the cpu time will be 48 // sampled or 0 if this is not enabled. 49 // This value is always 1 if the |records_cpu_time_for_each_task| is true. 50 double task_sampling_rate_for_recording_cpu_time = 0; 51 }; 52 53 virtual ~SequenceManager() = default; 54 55 // TODO(kraynov): Bring back CreateOnCurrentThread static method here 56 // when the move is done. It's not here yet to reduce PLATFORM_EXPORT 57 // macros hacking during the move. 58 59 // Must be called on the main thread. 60 // Can be called only once, before creating TaskQueues. 61 // Observer must outlive the SequenceManager. 62 virtual void SetObserver(Observer* observer) = 0; 63 64 // Must be called on the main thread. 65 virtual void AddTaskObserver(MessageLoop::TaskObserver* task_observer) = 0; 66 virtual void RemoveTaskObserver(MessageLoop::TaskObserver* task_observer) = 0; 67 virtual void AddTaskTimeObserver(TaskTimeObserver* task_time_observer) = 0; 68 virtual void RemoveTaskTimeObserver(TaskTimeObserver* task_time_observer) = 0; 69 70 // Registers a TimeDomain with SequenceManager. 71 // TaskQueues must only be created with a registered TimeDomain. 72 // Conversely, any TimeDomain must remain registered until no 73 // TaskQueues (using that TimeDomain) remain. 74 virtual void RegisterTimeDomain(TimeDomain* time_domain) = 0; 75 virtual void UnregisterTimeDomain(TimeDomain* time_domain) = 0; 76 77 virtual TimeDomain* GetRealTimeDomain() const = 0; 78 virtual const TickClock* GetTickClock() const = 0; 79 virtual TimeTicks NowTicks() const = 0; 80 81 // Sets the SingleThreadTaskRunner that will be returned by 82 // ThreadTaskRunnerHandle::Get on the main thread. 83 virtual void SetDefaultTaskRunner( 84 scoped_refptr<SingleThreadTaskRunner> task_runner) = 0; 85 86 // Removes all canceled delayed tasks. 87 virtual void SweepCanceledDelayedTasks() = 0; 88 89 // Returns true if no tasks were executed in TaskQueues that monitor 90 // quiescence since the last call to this method. 91 virtual bool GetAndClearSystemIsQuiescentBit() = 0; 92 93 // Set the number of tasks executed in a single SequenceManager invocation. 94 // Increasing this number reduces the overhead of the tasks dispatching 95 // logic at the cost of a potentially worse latency. 1 by default. 96 virtual void SetWorkBatchSize(int work_batch_size) = 0; 97 98 // Enables crash keys that can be set in the scope of a task which help 99 // to identify the culprit if upcoming work results in a crash. 100 // Key names must be thread-specific to avoid races and corrupted crash dumps. 101 virtual void EnableCrashKeys(const char* file_name_crash_key, 102 const char* function_name_crash_key) = 0; 103 104 // Returns the metric recording configuration for the current SequenceManager. 105 virtual const MetricRecordingSettings& GetMetricRecordingSettings() const = 0; 106 107 // Creates a task queue with the given type, |spec| and args. 108 // Must be called on the main thread. 109 // TODO(scheduler-dev): SequenceManager should not create TaskQueues. 110 template <typename TaskQueueType, typename... Args> CreateTaskQueue(const TaskQueue::Spec & spec,Args &&...args)111 scoped_refptr<TaskQueueType> CreateTaskQueue(const TaskQueue::Spec& spec, 112 Args&&... args) { 113 return WrapRefCounted(new TaskQueueType(CreateTaskQueueImpl(spec), spec, 114 std::forward<Args>(args)...)); 115 } 116 117 protected: 118 virtual std::unique_ptr<internal::TaskQueueImpl> CreateTaskQueueImpl( 119 const TaskQueue::Spec& spec) = 0; 120 }; 121 122 // Create SequenceManager using MessageLoop on the current thread. 123 // Implementation is located in sequence_manager_impl.cc. 124 // TODO(scheduler-dev): Rename to TakeOverCurrentThread when we'll stop using 125 // MessageLoop and will actually take over a thread. 126 BASE_EXPORT std::unique_ptr<SequenceManager> 127 CreateSequenceManagerOnCurrentThread(); 128 129 } // namespace sequence_manager 130 } // namespace base 131 132 #endif // BASE_TASK_SEQUENCE_MANAGER_SEQUENCE_MANAGER_H_ 133