Avi Drissman | 8ba1bad | 2022-09-13 19:22:36 | [diff] [blame^] | 1 | // Copyright 2020 The Chromium Authors |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "components/performance_manager/public/freezing/freezing.h" |
| 6 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 7 | #include <memory> |
| 8 | |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 9 | #include "base/bind.h" |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 10 | #include "base/containers/contains.h" |
| 11 | #include "base/containers/flat_map.h" |
| 12 | #include "base/containers/flat_set.h" |
| 13 | #include "base/memory/ptr_util.h" |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 14 | #include "base/memory/raw_ptr.h" |
Patrick Monette | 490a96da | 2021-02-18 02:43:46 | [diff] [blame] | 15 | #include "base/scoped_observation.h" |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 16 | #include "base/sequence_checker.h" |
Patrick Monette | 643cdf6 | 2021-10-15 19:13:42 | [diff] [blame] | 17 | #include "base/task/sequenced_task_runner.h" |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 18 | #include "base/thread_annotations.h" |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 19 | #include "components/performance_manager/freezing/freezing_vote_aggregator.h" |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 20 | #include "components/performance_manager/graph/graph_impl.h" |
| 21 | #include "components/performance_manager/graph/node_attached_data_impl.h" |
| 22 | #include "components/performance_manager/graph/page_node_impl.h" |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 23 | #include "components/performance_manager/performance_manager_impl.h" |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 24 | #include "components/performance_manager/public/graph/graph.h" |
| 25 | #include "components/performance_manager/public/graph/graph_registered.h" |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 26 | #include "components/performance_manager/public/graph/page_node.h" |
| 27 | #include "components/performance_manager/public/performance_manager.h" |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 28 | #include "content/public/browser/browser_thread.h" |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 29 | #include "content/public/browser/web_contents.h" |
| 30 | |
| 31 | namespace performance_manager { |
| 32 | |
| 33 | namespace freezing { |
| 34 | |
| 35 | namespace { |
| 36 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 37 | class FreezingVoteTokenImpl; |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 38 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 39 | // NodeAttachedData used to store the set of FreezingVoteTokenImpl objects |
| 40 | // associated with a PageNode. |
| 41 | class FreezingVoteNodeData : public NodeAttachedDataImpl<FreezingVoteNodeData> { |
| 42 | public: |
| 43 | struct Traits : public NodeAttachedDataInMap<PageNodeImpl> {}; |
| 44 | |
| 45 | ~FreezingVoteNodeData() override = default; |
| 46 | |
| 47 | void AddVote(FreezingVoteTokenImpl* token); |
| 48 | void RemoveVote(FreezingVoteTokenImpl* token); |
| 49 | bool IsEmpty() { return vote_tokens_.empty(); } |
| 50 | const base::flat_set<FreezingVoteTokenImpl*>& vote_tokens() { |
| 51 | return vote_tokens_; |
| 52 | } |
| 53 | |
| 54 | private: |
| 55 | friend class ::performance_manager::NodeAttachedDataImpl< |
| 56 | FreezingVoteNodeData>; |
| 57 | explicit FreezingVoteNodeData(const PageNodeImpl* page_node) {} |
| 58 | |
| 59 | // The freezing votes associated with this node. |
| 60 | base::flat_set<FreezingVoteTokenImpl*> vote_tokens_; |
| 61 | }; |
| 62 | |
| 63 | // A registry of FreezingVoteToken that lives on the PM sequence. |
| 64 | // |
| 65 | // There can be multiple freezing votes associated with the same page node. |
| 66 | class FreezingVoteTokenPMRegistry |
| 67 | : public PageNode::ObserverDefaultImpl, |
| 68 | public GraphOwned, |
| 69 | public GraphRegisteredImpl<FreezingVoteTokenPMRegistry> { |
| 70 | public: |
| 71 | // A map that associates a voting token to a |
| 72 | // <FreezingVotingChannel, const PageNode*> pair. |
| 73 | using VotingChannelsMap = |
| 74 | base::flat_map<FreezingVoteTokenImpl*, |
| 75 | std::pair<FreezingVotingChannel, const PageNode*>>; |
| 76 | |
| 77 | // Returns the FreezingVoteTokenPMRegistry graph owned instance, creates it if |
| 78 | // necessary. Can only be called from the PM sequence. |
| 79 | static FreezingVoteTokenPMRegistry* GetOrCreateInstance(Graph* graph); |
| 80 | |
| 81 | FreezingVoteTokenPMRegistry(const FreezingVoteTokenPMRegistry& other) = |
| 82 | delete; |
| 83 | FreezingVoteTokenPMRegistry& operator=(const FreezingVoteTokenPMRegistry&) = |
| 84 | delete; |
| 85 | |
| 86 | // Register a freezing vote for |contents|. |token| is an ID to associate with |
| 87 | // this vote, there can be only one vote associated with this ID and it as to |
| 88 | // be passed |UnregisterVote| when the vote is invalidated. This can only be |
| 89 | // called from the UI thread. |
| 90 | static void RegisterVoteForWebContents(content::WebContents* contents, |
| 91 | FreezingVoteValue vote_value, |
| 92 | const char* vote_reason, |
| 93 | FreezingVoteTokenImpl* token); |
| 94 | |
| 95 | // Unregister the vote associated with |token|. This can only be called from |
| 96 | // the UI thread. |
| 97 | static void UnregisterVote(FreezingVoteTokenImpl* token); |
| 98 | |
| 99 | const VotingChannelsMap& voting_channels_for_testing() { |
| 100 | return voting_channels_; |
| 101 | } |
| 102 | |
| 103 | private: |
| 104 | FreezingVoteTokenPMRegistry() = default; |
| 105 | |
| 106 | // Register a vote for |page_node| on the PM sequence. |token| is an ID |
| 107 | // associated with this vote that will be used when invalidating it. |
| 108 | void RegisterVoteOnPMSequence(base::WeakPtr<PageNode> page_node, |
| 109 | FreezingVote vote, |
| 110 | FreezingVoteTokenImpl* token); |
| 111 | |
| 112 | // Unregister the vote associated with |token|. |
| 113 | void UnregisterVoteOnPMSequence(FreezingVoteTokenImpl* token); |
Patrick Monette | 490a96da | 2021-02-18 02:43:46 | [diff] [blame] | 114 | |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 115 | // PageNodeObserver: |
| 116 | void OnBeforePageNodeRemoved(const PageNode* page_node) override; |
| 117 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 118 | // GraphOwned: |
| 119 | void OnPassedToGraph(Graph* graph) override; |
| 120 | void OnTakenFromGraph(Graph* graph) override; |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 121 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 122 | // Reset the voting channel associated with |voting_channel_iter| and remove |
| 123 | // this entry from |voting_channels_|. |voting_channel_iter| has to be a valid |
| 124 | // iterator from |voting_channels_| |
| 125 | void ResetAndRemoveVotingChannel( |
| 126 | VotingChannelsMap::iterator& voting_channel_iter, |
| 127 | const PageNode* page_node); |
Patrick Monette | 490a96da | 2021-02-18 02:43:46 | [diff] [blame] | 128 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 129 | VotingChannelsMap voting_channels_ GUARDED_BY_CONTEXT(sequence_checker_); |
Patrick Monette | 490a96da | 2021-02-18 02:43:46 | [diff] [blame] | 130 | |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 131 | raw_ptr<Graph> graph_ GUARDED_BY_CONTEXT(sequence_checker_); |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 132 | |
| 133 | SEQUENCE_CHECKER(sequence_checker_); |
| 134 | }; |
| 135 | |
| 136 | // Concrete implementation of a FreezingVoteToken. |
| 137 | class FreezingVoteTokenImpl : public FreezingVoteToken { |
| 138 | public: |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 139 | FreezingVoteTokenImpl(content::WebContents* contents, |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 140 | FreezingVoteValue vote_value, |
| 141 | const char* vote_reason); |
| 142 | ~FreezingVoteTokenImpl() override; |
| 143 | FreezingVoteTokenImpl(const FreezingVoteTokenImpl& other) = delete; |
| 144 | FreezingVoteTokenImpl& operator=(const FreezingVoteTokenImpl&) = delete; |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 145 | }; |
| 146 | |
| 147 | } // namespace |
| 148 | |
| 149 | FreezingVoteToken::FreezingVoteToken() = default; |
| 150 | FreezingVoteToken::~FreezingVoteToken() = default; |
| 151 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 152 | void FreezingVoteNodeData::AddVote(FreezingVoteTokenImpl* token) { |
| 153 | DCHECK(!base::Contains(vote_tokens_, token)); |
| 154 | vote_tokens_.insert(token); |
| 155 | } |
| 156 | |
| 157 | void FreezingVoteNodeData::RemoveVote(FreezingVoteTokenImpl* token) { |
| 158 | DCHECK(base::Contains(vote_tokens_, token)); |
| 159 | vote_tokens_.erase(token); |
| 160 | } |
| 161 | |
| 162 | // static |
| 163 | FreezingVoteTokenPMRegistry* FreezingVoteTokenPMRegistry::GetOrCreateInstance( |
| 164 | Graph* graph) { |
| 165 | DCHECK(PerformanceManager::GetTaskRunner()->RunsTasksInCurrentSequence()); |
| 166 | auto* instance = graph->GetRegisteredObjectAs<FreezingVoteTokenPMRegistry>(); |
| 167 | if (!instance) { |
| 168 | auto registry = base::WrapUnique(new FreezingVoteTokenPMRegistry()); |
| 169 | instance = registry.get(); |
| 170 | graph->PassToGraph(std::move(registry)); |
| 171 | } |
| 172 | return instance; |
| 173 | } |
| 174 | |
| 175 | // static |
| 176 | void FreezingVoteTokenPMRegistry::RegisterVoteForWebContents( |
| 177 | content::WebContents* contents, |
| 178 | FreezingVoteValue vote_value, |
| 179 | const char* vote_reason, |
| 180 | FreezingVoteTokenImpl* token) { |
| 181 | DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 182 | // Register the vote on the PM sequence. |
| 183 | PerformanceManager::CallOnGraph( |
| 184 | FROM_HERE, |
| 185 | base::BindOnce( |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 186 | [](base::WeakPtr<PageNode> page_node, FreezingVote vote, |
| 187 | FreezingVoteTokenImpl* token, Graph* graph) { |
| 188 | auto* registry = |
| 189 | FreezingVoteTokenPMRegistry::GetOrCreateInstance(graph); |
| 190 | registry->RegisterVoteOnPMSequence(page_node, vote, token); |
| 191 | }, |
Chris Hamilton | c763a55 | 2021-06-21 17:10:59 | [diff] [blame] | 192 | PerformanceManager::GetPrimaryPageNodeForWebContents(contents), |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 193 | FreezingVote(vote_value, vote_reason), token)); |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 194 | } |
| 195 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 196 | // static |
| 197 | void FreezingVoteTokenPMRegistry::UnregisterVote(FreezingVoteTokenImpl* token) { |
| 198 | DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 199 | // Unregister the vote on the PM sequence. |
| 200 | PerformanceManager::CallOnGraph( |
| 201 | FROM_HERE, |
| 202 | base::BindOnce( |
| 203 | [](FreezingVoteTokenImpl* token, Graph* graph) { |
| 204 | auto* registry = |
| 205 | FreezingVoteTokenPMRegistry::GetOrCreateInstance(graph); |
| 206 | registry->UnregisterVoteOnPMSequence(token); |
| 207 | }, |
| 208 | token)); |
Patrick Monette | 490a96da | 2021-02-18 02:43:46 | [diff] [blame] | 209 | } |
| 210 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 211 | void FreezingVoteTokenPMRegistry::RegisterVoteOnPMSequence( |
Patrick Monette | 490a96da | 2021-02-18 02:43:46 | [diff] [blame] | 212 | base::WeakPtr<PageNode> page_node, |
| 213 | FreezingVote vote, |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 214 | FreezingVoteTokenImpl* token) { |
Patrick Monette | 490a96da | 2021-02-18 02:43:46 | [diff] [blame] | 215 | DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 216 | DCHECK(page_node); |
Patrick Monette | 490a96da | 2021-02-18 02:43:46 | [diff] [blame] | 217 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 218 | DCHECK(!base::Contains(voting_channels_, token)); |
Patrick Monette | 490a96da | 2021-02-18 02:43:46 | [diff] [blame] | 219 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 220 | auto* node_data = FreezingVoteNodeData::GetOrCreate( |
| 221 | PageNodeImpl::FromNode(page_node.get())); |
Patrick Monette | 490a96da | 2021-02-18 02:43:46 | [diff] [blame] | 222 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 223 | auto voting_channel = graph_->GetRegisteredObjectAs<FreezingVoteAggregator>() |
| 224 | ->GetVotingChannel(); |
| 225 | voting_channel.SubmitVote(page_node.get(), vote); |
| 226 | voting_channels_[token] = |
| 227 | std::make_pair(std::move(voting_channel), page_node.get()); |
| 228 | |
| 229 | node_data->AddVote(token); |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 230 | } |
| 231 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 232 | void FreezingVoteTokenPMRegistry::UnregisterVoteOnPMSequence( |
| 233 | FreezingVoteTokenImpl* token) { |
| 234 | DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 235 | auto voting_channel = voting_channels_.find(token); |
| 236 | // The vote might be missing from |voting_channels_| if this gets called |
| 237 | // after the corresponding PageNode has been destroyed. |
| 238 | if (voting_channel == voting_channels_.end()) { |
| 239 | return; |
| 240 | } |
| 241 | |
| 242 | auto* page_node = voting_channel->second.second; |
| 243 | ResetAndRemoveVotingChannel(voting_channel, page_node); |
| 244 | |
| 245 | auto* node_data = |
| 246 | FreezingVoteNodeData::Get(PageNodeImpl::FromNode(page_node)); |
| 247 | DCHECK(node_data); |
| 248 | node_data->RemoveVote(token); |
| 249 | |
| 250 | // Removes the node attached data if there's no more vote associated with this |
| 251 | // node. |
| 252 | if (node_data->IsEmpty()) |
| 253 | FreezingVoteNodeData::Destroy(PageNodeImpl::FromNode(page_node)); |
| 254 | } |
| 255 | |
| 256 | void FreezingVoteTokenPMRegistry::OnBeforePageNodeRemoved( |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 257 | const PageNode* page_node) { |
| 258 | DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
Patrick Monette | 490a96da | 2021-02-18 02:43:46 | [diff] [blame] | 259 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 260 | auto* node_data = |
| 261 | FreezingVoteNodeData::Get(PageNodeImpl::FromNode(page_node)); |
| 262 | |
| 263 | if (!node_data) |
Patrick Monette | 490a96da | 2021-02-18 02:43:46 | [diff] [blame] | 264 | return; |
| 265 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 266 | // Invalidate the votes if its associated page node is destroyed. This can |
Patrick Monette | 490a96da | 2021-02-18 02:43:46 | [diff] [blame] | 267 | // happen if a freezing vote token is released after the destruction of the |
| 268 | // WebContents it's associated with. |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 269 | for (const auto* token_iter : node_data->vote_tokens()) { |
| 270 | auto voting_channel = voting_channels_.find(token_iter); |
| 271 | DCHECK(voting_channel != voting_channels_.end()); |
| 272 | ResetAndRemoveVotingChannel(voting_channel, page_node); |
| 273 | } |
Patrick Monette | 490a96da | 2021-02-18 02:43:46 | [diff] [blame] | 274 | } |
| 275 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 276 | void FreezingVoteTokenPMRegistry::OnPassedToGraph(Graph* graph) { |
| 277 | DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 278 | graph->RegisterObject(this); |
| 279 | graph->AddPageNodeObserver(this); |
| 280 | graph_ = graph; |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 281 | } |
| 282 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 283 | void FreezingVoteTokenPMRegistry::OnTakenFromGraph(Graph* graph) { |
| 284 | DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 285 | graph->UnregisterObject(this); |
| 286 | graph->RemovePageNodeObserver(this); |
| 287 | graph_ = nullptr; |
| 288 | } |
| 289 | |
| 290 | void FreezingVoteTokenPMRegistry::ResetAndRemoveVotingChannel( |
| 291 | VotingChannelsMap::iterator& voting_channel_iter, |
| 292 | const PageNode* page_node) { |
| 293 | DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 294 | voting_channel_iter->second.first.InvalidateVote(page_node); |
| 295 | voting_channel_iter->second.first.Reset(); |
| 296 | voting_channels_.erase(voting_channel_iter); |
| 297 | } |
| 298 | |
| 299 | FreezingVoteTokenImpl::FreezingVoteTokenImpl(content::WebContents* contents, |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 300 | FreezingVoteValue vote_value, |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 301 | const char* vote_reason) { |
| 302 | FreezingVoteTokenPMRegistry::RegisterVoteForWebContents(contents, vote_value, |
| 303 | vote_reason, this); |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 304 | } |
| 305 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 306 | FreezingVoteTokenImpl::~FreezingVoteTokenImpl() { |
| 307 | FreezingVoteTokenPMRegistry::UnregisterVote(this); |
| 308 | } |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 309 | |
| 310 | std::unique_ptr<FreezingVoteToken> EmitFreezingVoteForWebContents( |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 311 | content::WebContents* contents, |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 312 | FreezingVoteValue vote_value, |
| 313 | const char* vote_reason) { |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 314 | DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 315 | return std::make_unique<FreezingVoteTokenImpl>(contents, vote_value, |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 316 | vote_reason); |
| 317 | } |
| 318 | |
Sebastien Marchand | 24ac620 | 2020-12-17 16:13:51 | [diff] [blame] | 319 | const char* FreezingVoteValueToString(FreezingVoteValue freezing_vote_value) { |
| 320 | if (freezing_vote_value == freezing::FreezingVoteValue::kCanFreeze) { |
| 321 | return "kCanFreeze"; |
| 322 | } else { |
| 323 | return "kCannotFreeze"; |
| 324 | } |
| 325 | } |
| 326 | |
Sebastien Marchand | d7de057 | 2021-03-09 17:10:55 | [diff] [blame] | 327 | size_t FreezingVoteCountForPageOnPMForTesting(PageNode* page_node) { |
| 328 | DCHECK(PerformanceManager::GetTaskRunner()->RunsTasksInCurrentSequence()); |
| 329 | |
| 330 | auto* node_data = |
| 331 | FreezingVoteNodeData::Get(PageNodeImpl::FromNode(page_node)); |
| 332 | |
| 333 | if (!node_data) |
| 334 | return 0; |
| 335 | |
| 336 | return node_data->vote_tokens().size(); |
| 337 | } |
| 338 | |
| 339 | size_t TotalFreezingVoteCountOnPMForTesting(Graph* graph) { |
| 340 | DCHECK(PerformanceManager::GetTaskRunner()->RunsTasksInCurrentSequence()); |
| 341 | |
| 342 | auto* registry = FreezingVoteTokenPMRegistry::GetOrCreateInstance(graph); |
| 343 | |
| 344 | size_t registry_size = registry->voting_channels_for_testing().size(); |
| 345 | size_t page_nodes_vote_count = 0U; |
| 346 | |
| 347 | for (const PageNode* page_node : graph->GetAllPageNodes()) { |
| 348 | auto* node_data = |
| 349 | FreezingVoteNodeData::Get(PageNodeImpl::FromNode(page_node)); |
| 350 | if (node_data) |
| 351 | page_nodes_vote_count += node_data->vote_tokens().size(); |
| 352 | } |
| 353 | |
| 354 | DCHECK_EQ(registry_size, page_nodes_vote_count); |
| 355 | |
| 356 | return registry_size; |
| 357 | } |
| 358 | |
Sebastien Marchand | 1a8a708c | 2020-12-17 16:00:18 | [diff] [blame] | 359 | } // namespace freezing |
Patrick Monette | 490a96da | 2021-02-18 02:43:46 | [diff] [blame] | 360 | } // namespace performance_manager |