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

#include "base/task/sequence_manager/thread_controller.h"

#include <atomic>
#include <string_view>

#include "base/check.h"
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_base.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/notreached.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/time/tick_clock.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"

namespace base::sequence_manager::internal {

namespace {

// TODO(crbug.com/458682617): Remove this. It is an artifact of a feature which
// had the unintentional side-effect of adding a memory barrier at the end of
// each "ThreadController active". Hiding some TSAN failures which need fixing
// before we can lift this. It is disabled when FeatureList gets initialized (as
// the feature was), but FeatureList isn't initialized in all test suites...
std::atomic<bool> g_fortuitous_memory_barrier_on_sleep{
#if defined(THREAD_SANITIZER)
    true};
#else
    false};
#endif

void PerformFortuitousMemoryBarrierIfNecessary() {
  if (g_fortuitous_memory_barrier_on_sleep.load(std::memory_order_relaxed)) {
    static constinit std::atomic_uint shared_int{0};
    // This is the minimum requirement (side-effect from the previous
    // AutoLock) to reproduce crbug.com/458682617 (and mask TSAN failures).
    // Toggling this to std::memory_order_relaxed exposes the TSAN failures.
    // Note: We use `fetch_add` because a `store` isn't allowed to have
    // `acquire` semantics and we need acquire-release semantics to force any
    // kind of synchronization. We use an atomic variable instead of a full
    // `std::atomic_thread_fence` as this only aligns threads which pass
    // through this code path (as AutoLock would) instead of aligning with
    // other threads and their own unrelated memory barriers.
    shared_int.fetch_add(1, std::memory_order_acq_rel);
  }
}

// ThreadController interval metrics are mostly of interest for intervals that
// are not trivially short. Under a certain threshold it's unlikely that
// intervention from developers would move metrics. Log with suffix for
// intervals under a threshold chosen via tracing data. To validate the
// threshold makes sense and does not filter out too many samples
// ThreadController.ActiveIntervalDuration can be used.
constexpr TimeDelta kNonTrivialActiveIntervalLength = Milliseconds(1);
constexpr TimeDelta kMediumActiveIntervalLength = Milliseconds(100);

std::string MakeSuffix(std::string_view time_suffix,
                       std::string_view thread_name) {
  return base::StrCat({".", time_suffix, ".", thread_name});
}

}  // namespace

ThreadController::ThreadController(const TickClock* time_source)
    : associated_thread_(AssociatedThreadId::CreateUnbound()),
      time_source_(time_source) {}

ThreadController::~ThreadController() = default;

void ThreadController::SetTickClock(const TickClock* clock) {
  DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker);
  time_source_ = clock;
}

ThreadController::RunLevelTracker::RunLevelTracker(
    const ThreadController& outer)
    : outer_(outer) {}

ThreadController::RunLevelTracker::~RunLevelTracker() {
  DCHECK_CALLED_ON_VALID_THREAD(outer_->associated_thread_->thread_checker);

  // There shouldn't be any remaining |run_levels_| by the time this unwinds.
  DCHECK_EQ(run_levels_.size(), 0u);
}

// static
void ThreadController::InitializeFeatures() {
  // Disable fortuitous barriers whenever FeatureList is initialized to minimize
  // the surface where this is applied.
  g_fortuitous_memory_barrier_on_sleep.store(false, std::memory_order_relaxed);
}

std::string_view ThreadController::RunLevelTracker::RunLevel::GetThreadName() {
  std::string_view thread_name = "Other";
  if (!time_keeper_->thread_name().empty()) {
    thread_name = time_keeper_->thread_name();
  }
  return thread_name;
}

std::string
ThreadController::RunLevelTracker::RunLevel::GetSuffixForCatchAllHistogram() {
  return MakeSuffix("Any", GetThreadName());
}

std::string ThreadController::RunLevelTracker::RunLevel::GetSuffixForHistogram(
    TimeDelta duration) {
  std::string_view time_suffix;
  if (duration < kNonTrivialActiveIntervalLength) {
    time_suffix = "Short";
  } else if (duration < kMediumActiveIntervalLength) {
    time_suffix = "Medium";
  }
  return MakeSuffix(time_suffix, GetThreadName());
}

void ThreadController::EnableMessagePumpTimeKeeperMetrics(
    const char* thread_name,
    bool wall_time_based_metrics_enabled_for_testing) {
  // MessagePump runs too fast, a low-res clock would result in noisy metrics.
  if (!base::TimeTicks::IsHighResolution()) {
    return;
  }

  run_level_tracker_.EnableTimeKeeperMetrics(
      thread_name, wall_time_based_metrics_enabled_for_testing);
}

void ThreadController::RunLevelTracker::EnableTimeKeeperMetrics(
    const char* thread_name,
    bool wall_time_based_metrics_enabled_for_testing) {
  time_keeper_.EnableRecording(thread_name,
                               wall_time_based_metrics_enabled_for_testing);
}

void ThreadController::RunLevelTracker::TimeKeeper::EnableRecording(
    const char* thread_name,
    bool wall_time_based_metrics_enabled_for_testing) {
  DCHECK(!histogram_);
  thread_name_ = thread_name;
  wall_time_based_metrics_enabled_for_testing_ =
      wall_time_based_metrics_enabled_for_testing;

  histogram_ = LinearHistogram::FactoryGet(
      JoinString({"Scheduling.MessagePumpTimeKeeper", thread_name}, "."), 1,
      Phase::kLastPhase, Phase::kLastPhase + 1,
      base::HistogramBase::kUmaTargetedHistogramFlag);

  perfetto_track_.emplace("MessagePumpPhases", 0,
                          perfetto::ThreadTrack::Current());
}

void ThreadController::RunLevelTracker::OnRunLoopStarted(State initial_state,
                                                         LazyNow& lazy_now) {
  DCHECK_CALLED_ON_VALID_THREAD(outer_->associated_thread_->thread_checker);

  const bool is_nested = !run_levels_.empty();
  run_levels_.emplace(initial_state, is_nested, time_keeper_, lazy_now);

  // In unit tests, RunLoop::Run() acts as the initial wake-up.
  if (!is_nested && initial_state != kIdle) {
    time_keeper_.RecordWakeUp(lazy_now);
  }
}

void ThreadController::RunLevelTracker::OnRunLoopEnded() {
  DCHECK_CALLED_ON_VALID_THREAD(outer_->associated_thread_->thread_checker);
  // Normally this will occur while kIdle or kInBetweenWorkItems but it can also
  // occur while kRunningWorkItem in rare situations where the owning
  // ThreadController is deleted from within a task. Ref.
  // SequenceManagerWithTaskRunnerTest.DeleteSequenceManagerInsideATask. Thus we
  // can't assert anything about the current state other than that it must be
  // exiting an existing RunLevel.
  DCHECK(!run_levels_.empty());
  LazyNow exit_lazy_now(outer_->time_source_);
  run_levels_.top().set_exit_lazy_now(&exit_lazy_now);
  run_levels_.pop();
}

void ThreadController::RunLevelTracker::OnWorkStarted(LazyNow& lazy_now) {
  DCHECK_CALLED_ON_VALID_THREAD(outer_->associated_thread_->thread_checker);
  // Ignore work outside the main run loop.
  // The only practical case where this would happen is if a native loop is spun
  // outside the main runloop (e.g. system dialog during startup). We cannot
  // support this because we are not guaranteed to be able to observe its exit
  // (like we would inside an application task which is at least guaranteed to
  // itself notify us when it ends). Some ThreadControllerWithMessagePumpTest
  // also drive ThreadController outside a RunLoop and hit this.
  if (run_levels_.empty()) {
    return;
  }

  // Already running a work item? => #work-in-work-implies-nested
  if (run_levels_.top().state() == kRunningWorkItem) {
    run_levels_.emplace(kRunningWorkItem, /*nested=*/true, time_keeper_,
                        lazy_now);
  } else {
    if (run_levels_.top().state() == kIdle) {
      time_keeper_.RecordWakeUp(lazy_now);
    } else {
      time_keeper_.RecordEndOfPhase(kPumpOverhead, lazy_now);
    }

    // Going from kIdle or kInBetweenWorkItems to kRunningWorkItem.
    run_levels_.top().UpdateState(kRunningWorkItem, lazy_now);
  }
}

void ThreadController::RunLevelTracker::OnApplicationTaskSelected(
    TimeTicks queue_time,
    LazyNow& lazy_now) {
  DCHECK_CALLED_ON_VALID_THREAD(outer_->associated_thread_->thread_checker);
  // As-in OnWorkStarted. Early native loops can result in
  // ThreadController::DoWork because the lack of a top-level RunLoop means
  // `task_execution_allowed` wasn't consumed.
  if (run_levels_.empty()) {
    return;
  }

  // OnWorkStarted() is expected to precede OnApplicationTaskSelected().
  DCHECK_EQ(run_levels_.top().state(), kRunningWorkItem);

  time_keeper_.OnApplicationTaskSelected(queue_time, lazy_now);
}

void ThreadController::RunLevelTracker::OnWorkEnded(LazyNow& lazy_now,
                                                    int run_level_depth) {
  DCHECK_CALLED_ON_VALID_THREAD(outer_->associated_thread_->thread_checker);
  if (run_levels_.empty()) {
    return;
  }

  // #done-work-at-lower-runlevel-implies-done-nested
  if (run_level_depth != static_cast<int>(num_run_levels())) {
    DCHECK_EQ(run_level_depth + 1, static_cast<int>(num_run_levels()));
    run_levels_.top().set_exit_lazy_now(&lazy_now);
    run_levels_.pop();
  } else {
    time_keeper_.RecordEndOfPhase(kWorkItem, lazy_now);
  }

  // Whether we exited a nested run-level or not: the current run-level is now
  // transitioning from kRunningWorkItem to kInBetweenWorkItems.
  DCHECK_EQ(run_levels_.top().state(), kRunningWorkItem);
  run_levels_.top().UpdateState(kInBetweenWorkItems, lazy_now);
}

void ThreadController::RunLevelTracker::OnIdle(LazyNow& lazy_now) {
  DCHECK_CALLED_ON_VALID_THREAD(outer_->associated_thread_->thread_checker);
  if (run_levels_.empty()) {
    return;
  }

  DCHECK_NE(run_levels_.top().state(), kRunningWorkItem);
  time_keeper_.RecordEndOfPhase(kIdleWork, lazy_now);
  run_levels_.top().UpdateState(kIdle, lazy_now);
}

void ThreadController::RunLevelTracker::RecordScheduleWork() {
  // Matching TerminatingFlow is found at
  // ThreadController::RunLevelTracker::RunLevel::UpdateState
  if (outer_->associated_thread_->IsBoundToCurrentThread()) {
    TRACE_EVENT_INSTANT("wakeup.flow", "ScheduleWorkToSelf");
  } else {
    TRACE_EVENT_INSTANT("wakeup.flow", "ScheduleWork",
                        perfetto::Flow::FromPointer(this));
  }
}

// static
void ThreadController::RunLevelTracker::SetTraceObserverForTesting(
    TraceObserverForTesting* trace_observer_for_testing) {
  DCHECK_NE(!!trace_observer_for_testing_, !!trace_observer_for_testing);
  trace_observer_for_testing_ = trace_observer_for_testing;
}

// static
ThreadController::RunLevelTracker::TraceObserverForTesting*
    ThreadController::RunLevelTracker::trace_observer_for_testing_ = nullptr;

ThreadController::RunLevelTracker::RunLevel::RunLevel(State initial_state,
                                                      bool is_nested,
                                                      TimeKeeper& time_keeper,
                                                      LazyNow& lazy_now)
    : is_nested_(is_nested), time_keeper_(time_keeper) {
  if (is_nested_) {
    // Stop the current kWorkItem phase now, it will resume after the kNested
    // phase ends.
    time_keeper_->RecordEndOfPhase(kWorkItemSuspendedOnNested, lazy_now);
  }
  UpdateState(initial_state, lazy_now);
}

ThreadController::RunLevelTracker::RunLevel::~RunLevel() {
  if (!was_moved_) {
    DCHECK(exit_lazy_now_);
    UpdateState(kIdle, *exit_lazy_now_);
    if (is_nested_) {
      // Attribute the entire time in this nested RunLevel to kNested phase. If
      // this wasn't the last nested RunLevel, this is ignored and will be
      // applied on the final pop().
      time_keeper_->RecordEndOfPhase(kNested, *exit_lazy_now_);

      // TODO(crbug.com/458682617): Remove this.
      // This one is surprisingly necessary as a single racy test fails without
      // (GamepadServiceSimulationTest.SurfaceIdNotFound).
      PerformFortuitousMemoryBarrierIfNecessary();
    }
  }
}

ThreadController::RunLevelTracker::RunLevel::RunLevel(RunLevel&& other) =
    default;

void ThreadController::RunLevelTracker::RunLevel::LogPercentageMetric(
    const char* name,
    int percentage) {
  UmaHistogramPercentage(base::StrCat({name, ".", GetThreadName()}),
                         percentage);
}

void ThreadController::RunLevelTracker::RunLevel::LogPercentageMetric(
    const char* name,
    int percentage,
    base::TimeDelta interval_duration) {
  UmaHistogramPercentage(base::StrCat({name, GetSuffixForCatchAllHistogram()}),
                         percentage);
  UmaHistogramPercentage(
      base::StrCat({name, GetSuffixForHistogram(interval_duration)}),
      percentage);
}

void ThreadController::RunLevelTracker::RunLevel::LogIntervalMetric(
    const char* name,
    base::TimeDelta value,
    base::TimeDelta interval_duration) {
  // Log towards "Any" time suffix first.
  UmaHistogramTimes(base::StrCat({name, GetSuffixForCatchAllHistogram()}),
                    value);
  if (interval_duration < kNonTrivialActiveIntervalLength) {
    UmaHistogramCustomMicrosecondsTimes(
        base::StrCat({name, GetSuffixForHistogram(interval_duration)}), value,
        base::Microseconds(1), kNonTrivialActiveIntervalLength, 100);
  } else if (interval_duration < kMediumActiveIntervalLength) {
    UmaHistogramCustomTimes(
        base::StrCat({name, GetSuffixForHistogram(interval_duration)}), value,
        kNonTrivialActiveIntervalLength, kMediumActiveIntervalLength, 100);
  }
}

void ThreadController::RunLevelTracker::RunLevel::LogOnActiveMetrics(
    LazyNow& lazy_now) {
  CHECK(last_active_start_.is_null());
  CHECK(last_active_threadtick_start_.is_null());

  if (!last_active_end_.is_null()) {
    const base::TimeDelta idle_time = lazy_now.Now() - last_active_end_;
    LogIntervalMetric("Scheduling.ThreadController.IdleDuration", idle_time,
                      idle_time);
    last_active_end_ = base::TimeTicks();
    accumulated_idle_time_ += idle_time;
  }

  // Taking thread ticks can be expensive. Make sure to do it rarely enough to
  // not have a discernible impact on performance.
  static const bool thread_ticks_supported = ThreadTicks::IsSupported();
  // Disable subsampling to support wall-time based metrics. Only supported for
  // testing purposes. By default, the subsampling probability is 0.1%.
  const double probability =
      time_keeper_->wall_time_based_metrics_enabled_for_testing() ? 1.0 : 0.001;
  if (thread_ticks_supported &&
      metrics_sub_sampler_.ShouldSample(probability)) {
    last_active_start_ = lazy_now.Now();
    last_active_threadtick_start_ = ThreadTicks::Now();
  }
}

void ThreadController::RunLevelTracker::RunLevel::LogOnIdleMetrics(
    LazyNow& lazy_now) {
  if (!last_active_start_.is_null()) {
    const base::TimeDelta elapsed_ticks = lazy_now.Now() - last_active_start_;
    base::TimeDelta elapsed_thread_ticks =
        ThreadTicks::Now() - last_active_threadtick_start_;

    // Round to 100% in case of clock imprecisions making it look like
    // there's impossibly more ThreadTicks than TimeTicks elapsed.
    elapsed_thread_ticks = std::min(elapsed_thread_ticks, elapsed_ticks);

    LogIntervalMetric("Scheduling.ThreadController.ActiveIntervalDuration",
                      elapsed_ticks, elapsed_ticks);
    LogIntervalMetric(
        "Scheduling.ThreadController.ActiveIntervalOffCpuDuration",
        elapsed_ticks - elapsed_thread_ticks, elapsed_ticks);
    LogIntervalMetric("Scheduling.ThreadController.ActiveIntervalOnCpuDuration",
                      elapsed_thread_ticks, elapsed_ticks);

    // If the interval was shorter than a tick, 100% on-cpu time is assumed.
    int active_interval_cpu_percentage =
        elapsed_ticks.is_zero()
            ? 100
            : static_cast<int>(
                  (elapsed_thread_ticks * 100).IntDiv(elapsed_ticks));

    LogPercentageMetric(
        "Scheduling.ThreadController.ActiveIntervalOnCpuPercentage",
        active_interval_cpu_percentage, elapsed_ticks);

    if (time_keeper_->wall_time_based_metrics_enabled_for_testing()) {
      accumulated_active_time_ += elapsed_ticks;
      accumulated_active_on_cpu_time_ += elapsed_thread_ticks;
      accumulated_active_off_cpu_time_ +=
          (elapsed_ticks - elapsed_thread_ticks);

      // Accumulated wall-time since last wall-time based metric was stored.
      const base::TimeDelta accumulated_wall_time =
          accumulated_active_time_ + accumulated_idle_time_;

      // Add wall-time based ratio metrics (in percent) when the total sum of
      // active and idle times is larger than one second.
      if (accumulated_wall_time > Seconds(1)) {
        const int active_vs_wall_time_percentage = checked_cast<int>(
            (accumulated_active_time_ * 100).IntDiv(accumulated_wall_time));
        LogPercentageMetric(
            "Scheduling.ThreadController.ActiveVsWallTimePercentage",
            active_vs_wall_time_percentage);
        const int active_on_cpu_vs_wall_time_percentage =
            checked_cast<int>((accumulated_active_on_cpu_time_ * 100)
                                  .IntDiv(accumulated_wall_time));
        LogPercentageMetric(
            "Scheduling.ThreadController.ActiveOnCpuVsWallTimePercentage",
            active_on_cpu_vs_wall_time_percentage);
        const int active_off_cpu_vs_wall_time_percentage =
            checked_cast<int>((accumulated_active_off_cpu_time_ * 100)
                                  .IntDiv(accumulated_wall_time));
        LogPercentageMetric(
            "Scheduling.ThreadController.ActiveOffCpuVsWallTimePercentage",
            active_off_cpu_vs_wall_time_percentage);

        accumulated_idle_time_ = base::TimeDelta();
        accumulated_active_time_ = base::TimeDelta();
        accumulated_active_on_cpu_time_ = base::TimeDelta();
        accumulated_active_off_cpu_time_ = base::TimeDelta();
      }
    }

    // Reset timings.
    last_active_start_ = base::TimeTicks();
    last_active_threadtick_start_ = base::ThreadTicks();
    last_active_end_ = lazy_now.Now();
  }
}

void ThreadController::RunLevelTracker::RunLevel::UpdateState(
    State new_state,
    LazyNow& lazy_now) {
  // The only state that can be redeclared is idle, anything else should be a
  // transition.
  DCHECK(state_ != new_state || new_state == kIdle)
      << state_ << "," << new_state;

  const bool was_active = state_ != kIdle;
  const bool is_active = new_state != kIdle;

  state_ = new_state;
  if (was_active == is_active) {
    return;
  }

  // Change of state.
  if (is_active) {
    LogOnActiveMetrics(lazy_now);

    // Flow emission is found at
    // ThreadController::RunLevelTracker::RecordScheduleWork.
    TRACE_EVENT_BEGIN("base", "ThreadController active", lazy_now.Now(),
                      [&](perfetto::EventContext& ctx) {
                        time_keeper_->MaybeEmitIncomingWakeupFlow(ctx);
                      });

    // TODO(crbug.com/458682617): Remove this.
    PerformFortuitousMemoryBarrierIfNecessary();
  } else {
    // TODO(crbug.com/458682617): Remove this.
    PerformFortuitousMemoryBarrierIfNecessary();

    LogOnIdleMetrics(lazy_now);

    TRACE_EVENT_END("base", lazy_now.Now());
  }

  if (trace_observer_for_testing_) {
    if (is_active) {
      trace_observer_for_testing_->OnThreadControllerActiveBegin();
    } else {
      trace_observer_for_testing_->OnThreadControllerActiveEnd();
    }
  }
}

ThreadController::RunLevelTracker::TimeKeeper::TimeKeeper(
    const RunLevelTracker& outer)
    : outer_(outer) {}

void ThreadController::RunLevelTracker::TimeKeeper::RecordWakeUp(
    LazyNow& lazy_now) {
  if (!ShouldRecordNow(ShouldRecordReqs::kOnWakeUp)) {
    return;
  }

  // Phase::kScheduled will be accounted against `last_wakeup_` in
  // OnTaskSelected, if there's an application task in this work cycle.
  last_wakeup_ = lazy_now.Now();
  // Account the next phase starting from now.
  last_phase_end_ = last_wakeup_;

  // Emit the END of the kScheduled phase right away, this avoids incorrect
  // ordering when kScheduled is later emitted and its END matches the BEGIN of
  // an already emitted phase (tracing's sort is stable and would keep the late
  // END for kScheduled after the earlier BEGIN of the next phase):
  // crbug.com/1333460. As we just woke up, there are no events active at this
  // point (we don't record MessagePumpPhases while nested). In the absence of
  // a kScheduled phase, this unmatched END will be ignored.
  TRACE_EVENT_END(TRACE_DISABLED_BY_DEFAULT("base"), *perfetto_track_,
                  last_wakeup_);
}

void ThreadController::RunLevelTracker::TimeKeeper::OnApplicationTaskSelected(
    TimeTicks queue_time,
    LazyNow& lazy_now) {
  if (!ShouldRecordNow()) {
    return;
  }

  if (!last_wakeup_.is_null()) {
    // `queue_time` can be null on threads that did not
    // `SetAddQueueTimeToTasks(true)`. `queue_time` can also be ahead of
    // `last_wakeup` in racy cases where the first chrome task is enqueued
    // while the pump was already awake (e.g. for native work). Consider the
    // kScheduled phase inexistent in that case.
    if (!queue_time.is_null() && queue_time < last_wakeup_) {
      if (!last_sleep_.is_null() && queue_time < last_sleep_) {
        // Avoid overlapping kScheduled and kIdleWork phases when work is
        // scheduled while going to sleep.
        queue_time = last_sleep_;
      }
      RecordTimeInPhase(kScheduled, queue_time, last_wakeup_);
      // Match the END event which was already emitted by RecordWakeUp().
      TRACE_EVENT_BEGIN(TRACE_DISABLED_BY_DEFAULT("base"),
                        perfetto::StaticString(PhaseToEventName(kScheduled)),
                        *perfetto_track_, queue_time);
    }
    last_wakeup_ = TimeTicks();
  }
  RecordEndOfPhase(kSelectingApplicationTask, lazy_now);
  current_work_item_is_native_ = false;
}

void ThreadController::RunLevelTracker::TimeKeeper::RecordEndOfPhase(
    Phase phase,
    LazyNow& lazy_now) {
  if (!ShouldRecordNow(phase == kNested ? ShouldRecordReqs::kOnEndNested
                                        : ShouldRecordReqs::kRegular)) {
    return;
  }

  if (phase == kWorkItem && !current_work_item_is_native_) {
    phase = kApplicationTask;
    // Back to assuming future work is native until OnApplicationTaskSelected()
    // is invoked.
    current_work_item_is_native_ = true;
  } else if (phase == kWorkItemSuspendedOnNested) {
    // kWorkItemSuspendedOnNested temporarily marks the end of time allocated to
    // the current work item. It is reported as a separate phase to skip the
    // above `current_work_item_is_native_ = true` which assumes the work item
    // is truly complete.
    phase = current_work_item_is_native_ ? kNativeWork : kApplicationTask;
  }

  const TimeTicks phase_end = lazy_now.Now();
  RecordTimeInPhase(phase, last_phase_end_, phase_end);

  const char* event_name = PhaseToEventName(phase);
  TRACE_EVENT_BEGIN(TRACE_DISABLED_BY_DEFAULT("base"),
                    perfetto::StaticString(event_name), *perfetto_track_,
                    last_phase_end_);
  TRACE_EVENT_END(TRACE_DISABLED_BY_DEFAULT("base"), *perfetto_track_,
                  phase_end);

  last_phase_end_ = phase_end;
}

void ThreadController::RunLevelTracker::TimeKeeper::MaybeEmitIncomingWakeupFlow(
    perfetto::EventContext& ctx) {
  static const uint8_t* flow_enabled =
      TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("wakeup.flow");
  if (!*flow_enabled) {
    return;
  }

  perfetto::TerminatingFlow::ProcessScoped(
      reinterpret_cast<uint64_t>(&(outer_.get())))(ctx);
}

bool ThreadController::RunLevelTracker::TimeKeeper::ShouldRecordNow(
    ShouldRecordReqs reqs) {
  DCHECK_CALLED_ON_VALID_THREAD(
      outer_->outer_->associated_thread_->thread_checker);
  // Recording is technically enabled once `histogram_` is set, however
  // `last_phase_end_` will be null until the next RecordWakeUp in the work
  // cycle in which `histogram_` is enabled. Only start recording from there.
  // Ignore any nested phases. `reqs` may indicate exceptions to this.
  //
  // TODO(crbug.com/40226913): In a follow-up, we could probably always be
  // tracking the phases of the pump and merely ignore the reporting if
  // `histogram_` isn't set.
  switch (reqs) {
    case ShouldRecordReqs::kRegular:
      return histogram_ && !last_phase_end_.is_null() &&
             outer_->run_levels_.size() == 1;
    case ShouldRecordReqs::kOnWakeUp:
      return histogram_ && outer_->run_levels_.size() == 1;
    case ShouldRecordReqs::kOnEndNested:
      return histogram_ && !last_phase_end_.is_null() &&
             outer_->run_levels_.size() <= 2;
  }
}

void ThreadController::RunLevelTracker::TimeKeeper::RecordTimeInPhase(
    Phase phase,
    TimeTicks phase_begin,
    TimeTicks phase_end) {
  DCHECK(ShouldRecordNow(phase == kNested ? ShouldRecordReqs::kOnEndNested
                                          : ShouldRecordReqs::kRegular));

  // Report a phase only when at least 100ms has been attributed to it.
  static constexpr auto kReportInterval = Milliseconds(100);

  // Above 30s in a single phase, assume suspend-resume and ignore the report.
  static constexpr auto kSkippedDelta = Seconds(30);

  const auto delta = phase_end - phase_begin;
  DCHECK(!delta.is_negative()) << delta;
  if (delta >= kSkippedDelta) {
    return;
  }

  deltas_[phase] += delta;
  if (deltas_[phase] >= kReportInterval) {
    const int count = deltas_[phase] / Milliseconds(1);
    histogram_->AddCount(phase, count);
    deltas_[phase] -= Milliseconds(count);
  }

  if (phase == kIdleWork) {
    last_sleep_ = phase_end;
  }

  if (outer_->trace_observer_for_testing_) {
    outer_->trace_observer_for_testing_->OnPhaseRecorded(phase);
  }
}

// static
const char* ThreadController::RunLevelTracker::TimeKeeper::PhaseToEventName(
    Phase phase) {
  switch (phase) {
    case kScheduled:
      return "Scheduled";
    case kPumpOverhead:
      return "PumpOverhead";
    case kNativeWork:
      return "NativeTask";
    case kSelectingApplicationTask:
      return "SelectingApplicationTask";
    case kApplicationTask:
      return "ApplicationTask";
    case kIdleWork:
      return "IdleWork";
    case kNested:
      return "Nested";
    case kWorkItemSuspendedOnNested:
      // kWorkItemSuspendedOnNested should be transformed into kNativeWork or
      // kApplicationTask before this point.
      NOTREACHED();
  }
}

}  // namespace base::sequence_manager::internal
