chromium/base/task/sequence_manager/sequence_manager_impl.cc

// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
#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 {

// Whether SequenceManagerImpl records crash keys. Enable via Finch when needed
// for an investigation. Disabled by default to avoid unnecessary overhead.
BASE_FEATURE();

ABSL_CONST_INIT thread_local internal::SequenceManagerImpl*
    thread_local_sequence_manager =;

class TracedBaseValue : public trace_event::ConvertableToTraceFormat {};

}  // namespace

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 =;
// Proportion of tasks which will record thread time for metrics.
const double kTaskSamplingRateForRecordingCPUTime =;
// Proprortion of SequenceManagers which will record thread time for each task,
// enabling advanced metrics.
const double kThreadSamplingRateForRecordingCPUTime =;

void ReclaimMemoryFromQueue(internal::TaskQueueImpl* queue, LazyNow* lazy_now) {}

SequenceManager::MetricRecordingSettings InitializeMetricRecordingSettings(
    bool randomised_sampling_enabled) {}

// Writes |address| in hexadecimal ("0x11223344") form starting from |output|
// and moving backwards in memory. Returns a pointer to the first digit of the
// result. Does *not* NUL-terminate the number.
#if !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_ANDROID)
char* PrependHexAddress(char* output, const void* address) {}
#endif  // !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_ANDROID)

// Atomic to avoid TSAN flags when a test  tries to access the value before the
// feature list is available.
std::atomic_bool g_record_crash_keys =;

#if BUILDFLAG(IS_WIN)
bool g_explicit_high_resolution_timer_win = true;
#endif  // BUILDFLAG(IS_WIN)

}  // namespace

// static
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;

// static
std::unique_ptr<ThreadControllerImpl>
SequenceManagerImpl::CreateThreadControllerImplForCurrentThread(
    const TickClock* clock) {}

// static
std::unique_ptr<SequenceManagerImpl> SequenceManagerImpl::CreateOnCurrentThread(
    SequenceManager::Settings settings) {}

// static
std::unique_ptr<SequenceManagerImpl> SequenceManagerImpl::CreateUnbound(
    SequenceManager::Settings settings) {}

// static
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  // DCHECK_IS_ON() && !BUILDFLAG(IS_NACL)

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 {}

// TODO(crbug.com/40204558): Rename once ExplicitHighResolutionTimerWin
// experiment is shipped.
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;

}  // namespace internal
}  // namespace sequence_manager
}  // namespace base