blob: 2abebf538f239df185a3e6e99baeaeccd6ed5399 [file]
// Copyright 2026 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/priority/priority_setter.h"
#include "base/check_op.h"
#include "base/process/process.h"
#include "components/performance_manager/graph/frame_node_impl.h"
#include "components/performance_manager/graph/process_node_impl.h"
#include "components/performance_manager/graph/worker_node_impl.h"
#include "components/performance_manager/public/graph/node_state.h"
namespace performance_manager::priority {
namespace {
// Sets the priority and reason of a frame or worker from its vote, or to its
// default priority and reason if it has no vote.
template <typename NodeImplType>
void SetPriorityAndReason(NodeImplType* node_impl,
const std::optional<Vote>& vote) {
// No property changes while the node is leaving graph.
if (node_impl->GetNodeState() == NodeState::kLeavingGraph) {
return;
}
node_impl->SetPriorityAndReason(
vote.has_value()
? PriorityAndReason(vote->value(), vote->reason())
: PriorityAndReason(base::Process::Priority::kMinValue,
NodeImplType::kDefaultPriorityReason));
}
} // namespace
PrioritySetter::PrioritySetter(MaxVoteAggregator* max_vote_aggregator)
: max_vote_aggregator_(max_vote_aggregator) {
max_vote_aggregator_->AddObserver(this);
}
PrioritySetter::~PrioritySetter() {
max_vote_aggregator_->RemoveObserver(this);
}
void PrioritySetter::OnFrameTopVoteChanged(const FrameNode* frame_node,
const std::optional<Vote>& vote) {
SetPriorityAndReason(FrameNodeImpl::FromNode(frame_node), vote);
}
void PrioritySetter::OnWorkerTopVoteChanged(const WorkerNode* worker_node,
const std::optional<Vote>& vote) {
SetPriorityAndReason(WorkerNodeImpl::FromNode(worker_node), vote);
}
// A process has no priority reason, so the reason of the vote is dropped.
void PrioritySetter::OnProcessTopVoteChanged(const ProcessNode* process_node,
const std::optional<Vote>& vote) {
ProcessNodeImpl* process_node_impl = ProcessNodeImpl::FromNode(process_node);
// The voting system only manages the priority of renderer processes.
CHECK_EQ(process_node_impl->GetProcessType(), content::PROCESS_TYPE_RENDERER);
// No property changes while the node is leaving graph.
if (process_node_impl->GetNodeState() == NodeState::kLeavingGraph) {
return;
}
process_node_impl->set_priority(
vote.has_value() ? vote->value() : base::Process::Priority::kMinValue);
}
} // namespace performance_manager::priority