#include "components/performance_manager/resource_attribution/cpu_measurement_monitor.h"
#include <algorithm>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <utility>
#include <vector>
#include "base/check_op.h"
#include "base/containers/contains.h"
#include "base/debug/crash_logging.h"
#include "base/debug/dump_without_crashing.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/overloaded.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/numerics/clamped_math.h"
#include "base/sequence_checker.h"
#include "base/strings/strcat.h"
#include "base/system/sys_info.h"
#include "base/task/task_traits.h"
#include "base/time/time.h"
#include "base/types/expected.h"
#include "base/types/optional_util.h"
#include "base/types/variant_util.h"
#include "components/performance_manager/graph/process_node_impl.h"
#include "components/performance_manager/public/features.h"
#include "components/performance_manager/public/graph/frame_node.h"
#include "components/performance_manager/public/graph/graph.h"
#include "components/performance_manager/public/graph/graph_operations.h"
#include "components/performance_manager/public/graph/node_data_describer_util.h"
#include "components/performance_manager/public/graph/page_node.h"
#include "components/performance_manager/public/graph/process_node.h"
#include "components/performance_manager/public/graph/worker_node.h"
#include "components/performance_manager/public/resource_attribution/attribution_helpers.h"
#include "components/performance_manager/public/resource_attribution/frame_context.h"
#include "components/performance_manager/public/resource_attribution/worker_context.h"
#include "components/performance_manager/resource_attribution/cpu_measurement_data.h"
#include "components/performance_manager/resource_attribution/graph_change.h"
#include "components/performance_manager/resource_attribution/node_data_describers.h"
#include "components/performance_manager/resource_attribution/worker_client_pages.h"
#include "content/public/common/process_type.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
#include "url/gurl.h"
#include "url/origin.h"
namespace resource_attribution {
namespace {
kResourceAttributionIncludeOrigins;
void ValidateCPUTimeResult(const CPUTimeResult& result) { … }
template <typename FrameOrWorkerNode>
std::optional<OriginInBrowsingInstanceContext>
OriginInBrowsingInstanceContextForNode(
const FrameOrWorkerNode* node,
content::BrowsingInstanceId browsing_instance,
GraphChange graph_change = NoGraphChange{ … }
void DestroyCPUMeasurementData(const ProcessNode* process_node) { … }
}
CPUMeasurementMonitor::CPUMeasurementMonitor()
: … { … }
CPUMeasurementMonitor::~CPUMeasurementMonitor() { … }
void CPUMeasurementMonitor::SetDelegateFactoryForTesting(
CPUMeasurementDelegate::Factory* factory) { … }
void CPUMeasurementMonitor::StartMonitoring(Graph* graph) { … }
void CPUMeasurementMonitor::StopMonitoring() { … }
bool CPUMeasurementMonitor::IsMonitoring() const { … }
void CPUMeasurementMonitor::RepeatingQueryStarted(internal::QueryId query_id) { … }
void CPUMeasurementMonitor::RepeatingQueryStopped(internal::QueryId query_id) { … }
bool CPUMeasurementMonitor::IsTrackingQueryForTesting(
internal::QueryId query_id) const { … }
size_t CPUMeasurementMonitor::GetDeadContextCountForTesting() const { … }
QueryResultMap CPUMeasurementMonitor::UpdateAndGetCPUMeasurements(
std::optional<internal::QueryId> query_id) { … }
void CPUMeasurementMonitor::RecordMemoryMetrics() { … }
void CPUMeasurementMonitor::OnFrameNodeAdded(const FrameNode* frame_node) { … }
void CPUMeasurementMonitor::OnBeforeFrameNodeRemoved(
const FrameNode* frame_node) { … }
void CPUMeasurementMonitor::OnOriginChanged(
const FrameNode* frame_node,
const std::optional<url::Origin>& previous_value) { … }
void CPUMeasurementMonitor::OnBeforePageNodeRemoved(const PageNode* page_node) { … }
void CPUMeasurementMonitor::OnProcessLifetimeChange(
const ProcessNode* process_node) { … }
void CPUMeasurementMonitor::OnBeforeProcessNodeRemoved(
const ProcessNode* process_node) { … }
void CPUMeasurementMonitor::OnPriorityChanged(
const ProcessNode* process_node,
base::TaskPriority previous_value) { … }
void CPUMeasurementMonitor::OnWorkerNodeAdded(const WorkerNode* worker_node) { … }
void CPUMeasurementMonitor::OnBeforeWorkerNodeRemoved(
const WorkerNode* worker_node) { … }
void CPUMeasurementMonitor::OnBeforeClientFrameAdded(
const WorkerNode* worker_node,
const FrameNode* client_frame_node) { … }
void CPUMeasurementMonitor::OnBeforeClientFrameRemoved(
const WorkerNode* worker_node,
const FrameNode* client_frame_node) { … }
void CPUMeasurementMonitor::OnBeforeClientWorkerAdded(
const WorkerNode* worker_node,
const WorkerNode* client_worker_node) { … }
void CPUMeasurementMonitor::OnBeforeClientWorkerRemoved(
const WorkerNode* worker_node,
const WorkerNode* client_worker_node) { … }
base::Value::Dict CPUMeasurementMonitor::DescribeFrameNodeData(
const FrameNode* node) const { … }
base::Value::Dict CPUMeasurementMonitor::DescribePageNodeData(
const PageNode* node) const { … }
base::Value::Dict CPUMeasurementMonitor::DescribeProcessNodeData(
const ProcessNode* node) const { … }
base::Value::Dict CPUMeasurementMonitor::DescribeWorkerNodeData(
const WorkerNode* node) const { … }
void CPUMeasurementMonitor::MonitorCPUUsage(const ProcessNode* process_node) { … }
void CPUMeasurementMonitor::UpdateAllCPUMeasurements() { … }
void CPUMeasurementMonitor::UpdateCPUMeasurements(
const ProcessNode* process_node,
GraphChange graph_change) { … }
std::pair<CPUTimeResult&, bool>
CPUMeasurementMonitor::GetOrCreateResultForContext(
const ResourceContext& context,
const CPUTimeResult& init_result) { … }
void CPUMeasurementMonitor::ApplyMeasurementDeltas(
const std::map<ResourceContext, CPUTimeResult>& measurement_deltas,
GraphChange graph_change) { … }
void CPUMeasurementMonitor::ApplySequentialDelta(const ResourceContext& context,
const CPUTimeResult& delta) { … }
void CPUMeasurementMonitor::ApplyOverlappingDelta(
const ResourceContext& context,
const CPUTimeResult& delta) { … }
void CPUMeasurementMonitor::SaveFinalMeasurements(
const std::vector<ResourceContext>& contexts) { … }
std::set<OriginInBrowsingInstanceContext>
CPUMeasurementMonitor::GetLiveOriginInBrowsingInstanceContexts() { … }
CPUMeasurementMonitor::ScopedCPUTimeResult::ScopedCPUTimeResult(
CPUMeasurementMonitor* monitor,
const ResourceContext& context,
const CPUTimeResult& result)
: … { … }
CPUMeasurementMonitor::ScopedCPUTimeResult::~ScopedCPUTimeResult() { … }
size_t CPUMeasurementMonitor::ScopedCPUTimeResult::EstimateMemoryUsage() const { … }
base::Value::Dict CPUMeasurementMonitor::DescribeContextData(
const ResourceContext& context) const { … }
void CPUMeasurementMonitor::MeasureAndDistributeCPUUsage(
const ProcessNode* process_node,
GraphChange graph_change,
std::map<ResourceContext, CPUTimeResult>& measurement_deltas) { … }
CPUMeasurementMonitor::DeadContextResults::DeadContextResults() = default;
CPUMeasurementMonitor::DeadContextResults::~DeadContextResults() = default;
CPUMeasurementMonitor::DeadContextResults::DeadContextResults(
DeadContextResults&&) = default;
CPUMeasurementMonitor::DeadContextResults&
CPUMeasurementMonitor::DeadContextResults::operator=(DeadContextResults&&) =
default;
}