File: termination_target_policy.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (85 lines) | stat: -rw-r--r-- 4,006 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_POLICIES_TERMINATION_TARGET_POLICY_H_
#define CHROME_BROWSER_PERFORMANCE_MANAGER_POLICIES_TERMINATION_TARGET_POLICY_H_

#include "chrome/browser/performance_manager/mechanisms/termination_target_setter.h"
#include "components/performance_manager/public/graph/graph.h"
#include "components/performance_manager/public/graph/graph_registered.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/system_node.h"

namespace performance_manager {

// This policy provides to partition_alloc the handle of a process to terminate
// on commit failure, before retrying the commit. In theory, the commit is much
// more likely to succeed after this, and this allows trading browser crashes
// (very bad) for unimportant renderer crashes (less bad).
//
// Implementation notes: When a page's visibility changes, a page is removed, a
// process is removed or new per-process memory metrics are available, this
// policy looks at all renderer processes to select the best "termination
// target" and provides it to partition_alloc. In order of preference, the
// termination target has:
// 1. A private memory footprint above 100MB (70th percentile), to maximize
//    chances that the termination will free enough commit space for the commit
//    retry to succeed.
// 2. Does not host non-discardable pages. For example, this reduces the chances
//    of ending a video call or loosing form entries.
// 3. Was the least recently visible.
// For simplicity of implementation, we do not observe when #2 changes (we only
// observe changes to #1 and #3). That implementation choice could be
// re-evaluated if we make "discardable" a property of `PageNode` in the future.
// For now, we rely on the fact that new per-process memory metrics are
// available every 2 minutes (and thus a change of #2 is taken into account
// within 2 minutes) for the termination target to be "mostly correct".
//
// This class is built on all platforms to facilitate development, but since a
// "commit failure" only exists on Windows, it is only instantiated on Windows
// in production.
class TerminationTargetPolicy
    : public PageNodeObserver,
      public ProcessNodeObserver,
      public SystemNodeObserver,
      public GraphOwnedAndRegistered<TerminationTargetPolicy> {
 public:
  explicit TerminationTargetPolicy(
      std::unique_ptr<TerminationTargetSetter> termination_target_setter =
          std::make_unique<TerminationTargetSetter>());
  ~TerminationTargetPolicy() override;

  // GraphOwnedAndRegistered:
  void OnPassedToGraph(Graph* graph) override;
  void OnTakenFromGraph(Graph* graph) override;

  // PageNodeObserver:
  void OnIsVisibleChanged(const PageNode* page_node) override;
  void OnPageNodeRemoved(const PageNode* page_node) override;

  // ProcessNodeObserver:
  void OnBeforeProcessNodeRemoved(const ProcessNode* process_node) override;
  void OnProcessLifetimeChange(const ProcessNode* process_node) override;

  // SystemNodeObserver:
  void OnProcessMemoryMetricsAvailable(const SystemNode* system_node) override;

 private:
  // Determines the best termination target
  void UpdateTerminationTarget(
      const ProcessNode* process_being_deleted = nullptr);

  // The process currently set as a termination target in partition_alloc.
  raw_ptr<const ProcessNode> current_termination_target_ = nullptr;

  // The mechanism to set a termination target. In production, this calls
  // `partition_alloc::SetProcessToTerminateOnCommitFailure`. In tests, it can
  // be mocked.
  std::unique_ptr<TerminationTargetSetter> termination_target_setter_;
};

}  // namespace performance_manager

#endif  // CHROME_BROWSER_PERFORMANCE_MANAGER_POLICIES_TERMINATION_TARGET_POLICY_H_