#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "base/task/sequence_manager/sequence_manager_impl.h"
#include <array>
#include <atomic>
#include <optional>
#include <queue>
#include <string_view>
#include <vector>
#include "base/callback_list.h"
#include "base/compiler_specific.h"
#include "base/debug/crash_logging.h"
#include "base/debug/stack_trace.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/notreached.h"
#include "base/observer_list.h"
#include "base/rand_util.h"
#include "base/ranges/algorithm.h"
#include "base/task/sequence_manager/enqueue_order.h"
#include "base/task/sequence_manager/task_queue_impl.h"
#include "base/task/sequence_manager/task_time_observer.h"
#include "base/task/sequence_manager/thread_controller_impl.h"
#include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
#include "base/task/sequence_manager/time_domain.h"
#include "base/task/sequence_manager/wake_up_queue.h"
#include "base/task/sequence_manager/work_queue.h"
#include "base/task/sequence_manager/work_queue_sets.h"
#include "base/task/task_features.h"
#include "base/threading/thread_id_name_manager.h"
#include "base/time/default_tick_clock.h"
#include "base/time/tick_clock.h"
#include "base/trace_event/base_tracing.h"
#include "build/build_config.h"
#include "third_party/abseil-cpp/absl/base/attributes.h"
namespace base {
namespace sequence_manager {
namespace {
BASE_FEATURE(…);
ABSL_CONST_INIT thread_local internal::SequenceManagerImpl*
thread_local_sequence_manager = …;
class TracedBaseValue : public trace_event::ConvertableToTraceFormat { … };
}
std::unique_ptr<SequenceManager> CreateSequenceManagerOnCurrentThread(
SequenceManager::Settings settings) { … }
std::unique_ptr<SequenceManager> CreateSequenceManagerOnCurrentThreadWithPump(
std::unique_ptr<MessagePump> message_pump,
SequenceManager::Settings settings) { … }
std::unique_ptr<SequenceManager> CreateUnboundSequenceManager(
SequenceManager::Settings settings) { … }
namespace internal {
std::unique_ptr<SequenceManagerImpl> CreateUnboundSequenceManagerImpl(
PassKey<base::internal::SequenceManagerThreadDelegate>,
SequenceManager::Settings settings) { … }
TimeRecordingPolicy;
namespace {
constexpr TimeDelta kLongTaskTraceEventThreshold = …;
const double kTaskSamplingRateForRecordingCPUTime = …;
const double kThreadSamplingRateForRecordingCPUTime = …;
void ReclaimMemoryFromQueue(internal::TaskQueueImpl* queue, LazyNow* lazy_now) { … }
SequenceManager::MetricRecordingSettings InitializeMetricRecordingSettings(
bool randomised_sampling_enabled) { … }
#if !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_ANDROID)
char* PrependHexAddress(char* output, const void* address) { … }
#endif
std::atomic_bool g_record_crash_keys = …;
#if BUILDFLAG(IS_WIN)
bool g_explicit_high_resolution_timer_win = true;
#endif
}
SequenceManagerImpl* SequenceManagerImpl::GetCurrent() { … }
SequenceManagerImpl::SequenceManagerImpl(
std::unique_ptr<internal::ThreadController> controller,
SequenceManager::Settings settings)
: … { … }
SequenceManagerImpl::~SequenceManagerImpl() { … }
SequenceManagerImpl::MainThreadOnly::MainThreadOnly(
SequenceManagerImpl* sequence_manager,
const scoped_refptr<AssociatedThreadId>& associated_thread,
const SequenceManager::Settings& settings,
const base::TickClock* clock)
: … { … }
SequenceManagerImpl::MainThreadOnly::~MainThreadOnly() = default;
std::unique_ptr<ThreadControllerImpl>
SequenceManagerImpl::CreateThreadControllerImplForCurrentThread(
const TickClock* clock) { … }
std::unique_ptr<SequenceManagerImpl> SequenceManagerImpl::CreateOnCurrentThread(
SequenceManager::Settings settings) { … }
std::unique_ptr<SequenceManagerImpl> SequenceManagerImpl::CreateUnbound(
SequenceManager::Settings settings) { … }
void SequenceManagerImpl::InitializeFeatures() { … }
void SequenceManagerImpl::BindToMessagePump(std::unique_ptr<MessagePump> pump) { … }
void SequenceManagerImpl::BindToCurrentThread() { … }
scoped_refptr<SequencedTaskRunner>
SequenceManagerImpl::GetTaskRunnerForCurrentTask() { … }
void SequenceManagerImpl::CompleteInitializationOnBoundThread() { … }
void SequenceManagerImpl::SetTimeDomain(TimeDomain* time_domain) { … }
void SequenceManagerImpl::ResetTimeDomain() { … }
std::unique_ptr<internal::TaskQueueImpl>
SequenceManagerImpl::CreateTaskQueueImpl(const TaskQueue::Spec& spec) { … }
void SequenceManagerImpl::SetAddQueueTimeToTasks(bool enable) { … }
bool SequenceManagerImpl::GetAddQueueTimeToTasks() { … }
void SequenceManagerImpl::SetObserver(Observer* observer) { … }
void SequenceManagerImpl::UnregisterTaskQueueImpl(
std::unique_ptr<internal::TaskQueueImpl> task_queue) { … }
AtomicFlagSet::AtomicFlag
SequenceManagerImpl::GetFlagToRequestReloadForEmptyQueue(
TaskQueueImpl* task_queue) { … }
void SequenceManagerImpl::ReloadEmptyWorkQueues() { … }
void SequenceManagerImpl::MoveReadyDelayedTasksToWorkQueues(LazyNow* lazy_now) { … }
void SequenceManagerImpl::OnBeginNestedRunLoop() { … }
void SequenceManagerImpl::OnExitNestedRunLoop() { … }
void SequenceManagerImpl::ScheduleWork() { … }
void SequenceManagerImpl::SetNextWakeUp(LazyNow* lazy_now,
std::optional<WakeUp> wake_up) { … }
void SequenceManagerImpl::MaybeEmitTaskDetails(
perfetto::EventContext& ctx,
const SequencedTaskSource::SelectedTask& selected_task) const { … }
void SequenceManagerImpl::SetRunTaskSynchronouslyAllowed(
bool can_run_tasks_synchronously) { … }
std::optional<SequenceManagerImpl::SelectedTask>
SequenceManagerImpl::SelectNextTask(LazyNow& lazy_now,
SelectTaskOption option) { … }
#if DCHECK_IS_ON() && !BUILDFLAG(IS_NACL)
void SequenceManagerImpl::LogTaskDebugInfo(
const WorkQueue* selected_work_queue) const { … }
#endif
std::optional<SequenceManagerImpl::SelectedTask>
SequenceManagerImpl::SelectNextTaskImpl(LazyNow& lazy_now,
SelectTaskOption option) { … }
void SequenceManagerImpl::DidRunTask(LazyNow& lazy_now) { … }
void SequenceManagerImpl::RemoveAllCanceledDelayedTasksFromFront(
LazyNow* lazy_now) { … }
std::optional<WakeUp> SequenceManagerImpl::GetPendingWakeUp(
LazyNow* lazy_now,
SelectTaskOption option) { … }
std::optional<WakeUp> SequenceManagerImpl::GetNextDelayedWakeUp() const { … }
std::optional<WakeUp> SequenceManagerImpl::GetNextDelayedWakeUpWithOption(
SelectTaskOption option) const { … }
std::optional<WakeUp> SequenceManagerImpl::AdjustWakeUp(
std::optional<WakeUp> wake_up,
LazyNow* lazy_now) const { … }
void SequenceManagerImpl::MaybeAddLeewayToTask(Task& task) const { … }
bool SequenceManagerImpl::HasPendingHighResolutionTasks() { … }
void SequenceManagerImpl::OnBeginWork() { … }
bool SequenceManagerImpl::OnIdle() { … }
void SequenceManagerImpl::WillRequestReloadImmediateWorkQueue() { … }
SyncWorkAuthorization SequenceManagerImpl::TryAcquireSyncWorkAuthorization() { … }
void SequenceManagerImpl::WillQueueTask(Task* pending_task) { … }
TaskQueue::TaskTiming SequenceManagerImpl::InitializeTaskTiming(
internal::TaskQueueImpl* task_queue) { … }
TimeRecordingPolicy SequenceManagerImpl::ShouldRecordTaskTiming(
const internal::TaskQueueImpl* task_queue) { … }
void SequenceManagerImpl::NotifyWillProcessTask(ExecutingTask* executing_task,
LazyNow* time_before_task) { … }
void SequenceManagerImpl::NotifyDidProcessTask(ExecutingTask* executing_task,
LazyNow* time_after_task) { … }
void SequenceManagerImpl::SetWorkBatchSize(int work_batch_size) { … }
void SequenceManagerImpl::AddTaskObserver(TaskObserver* task_observer) { … }
void SequenceManagerImpl::RemoveTaskObserver(TaskObserver* task_observer) { … }
void SequenceManagerImpl::AddTaskTimeObserver(
TaskTimeObserver* task_time_observer) { … }
void SequenceManagerImpl::RemoveTaskTimeObserver(
TaskTimeObserver* task_time_observer) { … }
bool SequenceManagerImpl::GetAndClearSystemIsQuiescentBit() { … }
EnqueueOrder SequenceManagerImpl::GetNextSequenceNumber() { … }
std::unique_ptr<trace_event::ConvertableToTraceFormat>
SequenceManagerImpl::AsValueWithSelectorResultForTracing(
internal::WorkQueue* selected_work_queue,
bool force_verbose) const { … }
Value::Dict SequenceManagerImpl::AsValueWithSelectorResult(
internal::WorkQueue* selected_work_queue,
bool force_verbose) const { … }
void SequenceManagerImpl::OnTaskQueueEnabled(internal::TaskQueueImpl* queue) { … }
void SequenceManagerImpl::OnWorkAvailable() { … }
void SequenceManagerImpl::MaybeReclaimMemory() { … }
void SequenceManagerImpl::ReclaimMemory() { … }
void SequenceManagerImpl::CleanUpQueues() { … }
WeakPtr<SequenceManagerImpl> SequenceManagerImpl::GetWeakPtr() { … }
void SequenceManagerImpl::SetDefaultTaskRunner(
scoped_refptr<SingleThreadTaskRunner> task_runner) { … }
const TickClock* SequenceManagerImpl::GetTickClock() const { … }
TimeTicks SequenceManagerImpl::NowTicks() const { … }
bool SequenceManagerImpl::ShouldRecordCPUTimeForTask() { … }
const SequenceManager::MetricRecordingSettings&
SequenceManagerImpl::GetMetricRecordingSettings() const { … }
void SequenceManagerImpl::SetTaskExecutionAllowedInNativeNestedLoop(
bool allowed) { … }
bool SequenceManagerImpl::IsTaskExecutionAllowedInNativeNestedLoop() const { … }
#if BUILDFLAG(IS_IOS)
void SequenceManagerImpl::AttachToMessagePump() {
return controller_->AttachToMessagePump();
}
#endif
bool SequenceManagerImpl::IsIdleForTesting() { … }
void SequenceManagerImpl::EnableMessagePumpTimeKeeperMetrics(
const char* thread_name,
bool wall_time_based_metrics_enabled_for_testing) { … }
size_t SequenceManagerImpl::GetPendingTaskCountForTesting() const { … }
TaskQueue::Handle SequenceManagerImpl::CreateTaskQueue(
const TaskQueue::Spec& spec) { … }
std::string SequenceManagerImpl::DescribeAllPendingTasks() const { … }
void SequenceManagerImpl::PrioritizeYieldingToNative(
base::TimeTicks prioritize_until) { … }
void SequenceManagerImpl::AddDestructionObserver(
CurrentThread::DestructionObserver* destruction_observer) { … }
void SequenceManagerImpl::RemoveDestructionObserver(
CurrentThread::DestructionObserver* destruction_observer) { … }
CallbackListSubscription SequenceManagerImpl::RegisterOnNextIdleCallback(
OnceClosure on_next_idle_callback) { … }
void SequenceManagerImpl::SetTaskRunner(
scoped_refptr<SingleThreadTaskRunner> task_runner) { … }
scoped_refptr<SingleThreadTaskRunner> SequenceManagerImpl::GetTaskRunner() { … }
bool SequenceManagerImpl::IsBoundToCurrentThread() const { … }
MessagePump* SequenceManagerImpl::GetMessagePump() const { … }
bool SequenceManagerImpl::IsType(MessagePumpType type) const { … }
void SequenceManagerImpl::EnableCrashKeys(const char* async_stack_crash_key) { … }
void SequenceManagerImpl::RecordCrashKeys(const PendingTask& pending_task) { … }
internal::TaskQueueImpl* SequenceManagerImpl::currently_executing_task_queue()
const { … }
TaskQueue::QueuePriority SequenceManagerImpl::GetPriorityCount() const { … }
constexpr TimeDelta SequenceManagerImpl::kReclaimMemoryInterval;
}
}
}