blob: 838359fa03d29fe2b49fe9025ac2ba083247a152 [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/performance_manager/scenarios/performance_scenario_data.h"
#include <memory>
#include <optional>
#include <utility>
#include "base/logging.h"
#include "base/memory/shared_memory_mapper.h"
#include "base/memory/structured_shared_memory.h"
#include "base/metrics/histogram_functions.h"
#include "base/types/optional_util.h"
#include "components/performance_manager/graph/process_node_impl.h"
#include "components/performance_manager/public/tracing_support.h"
#include "components/performance_manager/scenario_api/performance_scenario_memory.h"
#include "third_party/perfetto/include/perfetto/tracing/track.h"
namespace performance_manager {
namespace {
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
//
// LINT.IfChange(CreateScenarioMemoryResult)
enum class CreateScenarioMemoryResult {
kSuccess = 0,
kSystemError = 1,
kMaxValue = kSystemError,
};
// LINT.ThenChange(//tools/metrics/histograms/metadata/performance_manager/enums.xml:CreateScenarioMemoryResult)
void LogCreateScenarioMemoryResult(
CreateScenarioMemoryResult result,
std::optional<logging::SystemErrorCode> system_error = std::nullopt) {
base::UmaHistogramEnumeration("PerformanceManager.CreateScenarioMemoryResult",
result);
if (system_error.has_value()) {
base::UmaHistogramSparse(
"PerformanceManager.CreateScenarioMemorySystemError",
system_error.value());
}
}
perfetto::NamedTrack CreateTracingTrack(const ProcessNode* process_node,
perfetto::StaticString name,
uint64_t track_id) {
if (process_node) {
return CreateProcessTracingTrack(process_node, name, track_id);
} else {
return perfetto::NamedTrack(name, track_id, perfetto::Track::Global(0));
}
}
} // namespace
// static
PerformanceScenarioData& PerformanceScenarioData::GetOrCreate(
const ProcessNode* process_node,
base::SharedMemoryMapper* mapper) {
auto* process_node_impl = ProcessNodeImpl::FromNode(process_node);
if (Exists(process_node_impl)) {
return Get(process_node_impl);
}
return Create(process_node_impl, mapper);
}
PerformanceScenarioData::PerformanceScenarioData(
base::SharedMemoryMapper* mapper)
: shared_state_(mapper ? SharedScenarioState::CreateWithCustomMapper(mapper)
: SharedScenarioState::Create()) {
if (shared_state_.has_value()) {
LogCreateScenarioMemoryResult(CreateScenarioMemoryResult::kSuccess);
} else {
LogCreateScenarioMemoryResult(CreateScenarioMemoryResult::kSystemError,
logging::GetLastSystemErrorCode());
}
}
PerformanceScenarioData::~PerformanceScenarioData() = default;
PerformanceScenarioData::PerformanceScenarioData(PerformanceScenarioData&&) =
default;
PerformanceScenarioData& PerformanceScenarioData::operator=(
PerformanceScenarioData&&) = default;
const perfetto::NamedTrack* PerformanceScenarioData::loading_tracing_track()
const {
return base::OptionalToPtr(tracing_tracks_->loading_track);
}
const perfetto::NamedTrack* PerformanceScenarioData::input_tracing_track()
const {
return base::OptionalToPtr(tracing_tracks_->input_track);
}
void PerformanceScenarioData::EnsureTracingTracks(
const ProcessNode* process_node) {
uint64_t track_id = reinterpret_cast<uint64_t>(tracing_tracks_.get());
if (!tracing_tracks_->loading_track.has_value()) {
tracing_tracks_->loading_track.emplace(CreateTracingTrack(
process_node, "LoadingPerformanceScenario", track_id));
}
if (!tracing_tracks_->input_track.has_value()) {
tracing_tracks_->input_track.emplace(
CreateTracingTrack(process_node, "InputPerformanceScenario", track_id));
}
}
} // namespace performance_manager