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 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
|
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PROCESS_NODE_H_
#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PROCESS_NODE_H_
#include "base/containers/enum_set.h"
#include "base/containers/flat_set.h"
#include "base/observer_list_types.h"
#include "base/process/process.h"
#include "base/task/task_traits.h"
#include "components/performance_manager/public/graph/node.h"
#include "components/performance_manager/public/graph/node_set_view.h"
#include "components/performance_manager/public/render_process_host_id.h"
#include "components/performance_manager/public/resource_attribution/process_context.h"
#include "content/public/common/process_type.h"
namespace base {
class Process;
} // namespace base
namespace performance_manager {
class FrameNode;
class WorkerNode;
class RenderProcessHostProxy;
class BrowserChildProcessHostProxy;
// A process node follows the lifetime of a RenderProcessHost.
// It may reference zero or one processes at a time, but during its lifetime, it
// may reference more than one process. This can happen if the associated
// renderer crashes, and an associated frame is then reloaded or re-navigated.
// The state of the process node goes through:
// 1. Created, no PID.
// 2. Process started, have PID - in the case where the associated render
// process fails to start, this state may not occur.
// 3. Process died or failed to start, have exit status.
// 4. Back to 2.
//
// It is only valid to access this object on the sequence of the graph that owns
// it.
class ProcessNode : public TypedNode<ProcessNode> {
public:
using NodeSet = base::flat_set<const Node*>;
template <class ReturnType>
using NodeSetView = NodeSetView<NodeSet, ReturnType>;
// The type of content a renderer can host.
enum class ContentType : uint32_t {
// Hosted an extension.
kExtension = 1 << 0,
// Hosted a frame with no parent.
kMainFrame = 1 << 1,
// Hosted a frame with a parent.
kSubframe = 1 << 2,
// Hosted a frame (main frame or subframe) with a committed navigation. A
// "speculative" frame will not have a committed navigation.
kNavigatedFrame = 1 << 3,
// Hosted a frame that was tagged as an ad.
kAd = 1 << 4,
// Hosted a worker (service worker, dedicated worker, shared worker).
kWorker = 1 << 5,
};
using ContentTypes =
base::EnumSet<ContentType, ContentType::kExtension, ContentType::kWorker>;
static constexpr NodeTypeEnum Type() { return NodeTypeEnum::kProcess; }
ProcessNode();
ProcessNode(const ProcessNode&) = delete;
ProcessNode& operator=(const ProcessNode&) = delete;
~ProcessNode() override;
// Returns the type of this process.
virtual content::ProcessType GetProcessType() const = 0;
// Returns the process ID associated with this process. Use this in preference
// to querying GetProcess.Pid(). It's always valid to access, but will return
// kNullProcessId if the process has yet started. It will also retain the
// process ID for a process that has exited (at least until the underlying
// RenderProcessHost gets reused in the case of a crash). Refrain from using
// this as a unique identifier as on some platforms PIDs are reused
// aggressively.
virtual base::ProcessId GetProcessId() const = 0;
// Returns the base::Process backing this process. This will be an invalid
// process if it has not yet started, or if it has exited.
virtual const base::Process& GetProcess() const = 0;
// Gets the unique token identifying this node for resource attribution. This
// token will not be reused after the node is destroyed.
virtual resource_attribution::ProcessContext GetResourceContext() const = 0;
// Returns a time captured as early as possible after the process is launched.
virtual base::TimeTicks GetLaunchTime() const = 0;
// Returns the exit status of this process. This will be empty if the process
// has not yet exited.
virtual std::optional<int32_t> GetExitStatus() const = 0;
// Returns the non-localized name of the process used for metrics reporting
// metrics as specified in content::ChildProcessData during process creation.
virtual const std::string& GetMetricsName() const = 0;
// Returns the set of frame nodes that are hosted in this process.
virtual NodeSetView<const FrameNode*> GetFrameNodes() const = 0;
// Returns the set of worker nodes that are hosted in this process.
virtual NodeSetView<const WorkerNode*> GetWorkerNodes() const = 0;
// Returns true if the main thread task load is low (below some threshold
// of usage). See ProcessNodeObserver::OnMainThreadTaskLoadIsLow.
virtual bool GetMainThreadTaskLoadIsLow() const = 0;
// Returns the most recently measured private memory footprint of the process.
// This is roughly private, anonymous, non-discardable, resident or swapped
// memory in kilobytes. For more details, see https://goo.gl/3kPb9S.
//
// Note: This is only valid if at least one component has expressed interest
// for process memory metrics by calling
// ProcessMetricsDecorator::RegisterInterestForProcessMetrics.
virtual uint64_t GetPrivateFootprintKb() const = 0;
// Returns the most recently measured resident set of the process, in
// kilobytes.
virtual uint64_t GetResidentSetKb() const = 0;
// Returns the most recently measured size of private swap, in kilobytes. Will
// only be non-zero on Linux, ChromeOS, and Android.
virtual uint64_t GetPrivateSwapKb() const = 0;
// Returns the render process id (equivalent to RenderProcessHost::GetID()),
// or kInvalidChildProcessUniqueId if this is not a renderer.
virtual RenderProcessHostId GetRenderProcessHostId() const = 0;
// Returns a proxy to the RenderProcessHost associated with this node. The
// proxy may only be dereferenced on the UI thread. The proxy is only valid
// for renderer processes.
virtual const RenderProcessHostProxy& GetRenderProcessHostProxy() const = 0;
// Returns a proxy to the BrowserChildProcessHost associated with this node.
// The proxy may only be dereferenced on the UI thread. The proxy is only
// valid for non-renderer child processes.
virtual const BrowserChildProcessHostProxy& GetBrowserChildProcessHostProxy()
const = 0;
// Returns the current priority of the process.
virtual base::TaskPriority GetPriority() const = 0;
// Returns a bit field indicating what type of content this process has
// hosted, either currently or in the past.
virtual ContentTypes GetHostedContentTypes() const = 0;
};
// Observer interface for process node
class ProcessNodeObserver : public base::CheckedObserver {
public:
ProcessNodeObserver();
ProcessNodeObserver(const ProcessNodeObserver&) = delete;
ProcessNodeObserver& operator=(const ProcessNodeObserver&) = delete;
~ProcessNodeObserver() override;
// Node lifetime notifications.
// Called before a `process_node` is added to the graph. OnPageNodeAdded() is
// better for most purposes, but this can be useful if an observer needs to
// check the state of the graph without including `process_node`, or to set
// initial properties on the node that should be visible to other observers in
// OnProcessNodeAdded().
//
// Observers may make property changes during the scope of this call, as long
// as they don't cause notifications to be sent and don't modify pointers
// to/from other nodes, since the node is still isolated from the graph. To
// change a property that causes notifications, post a task (which will run
// after OnProcessNodeAdded().
//
// Note that observers are notified in an arbitrary order, so property changes
// made here may or may not be visible to other observers in
// OnBeforeProcessNodeAdded().
virtual void OnBeforeProcessNodeAdded(const ProcessNode* process_node) {}
// Called after a `process_node` is added to the graph. Observers may *not*
// make property changes during the scope of this call. To change a property,
// post a task which will run after all observers.
virtual void OnProcessNodeAdded(const ProcessNode* process_node) {}
// The process associated with `process_node` has been started or has exited.
// This implies some or all of the process, process_id, launch time and/or
// exit status properties have changed.
virtual void OnProcessLifetimeChange(const ProcessNode* process_node) {}
// Called before a `process_node` is removed from the graph. Observers may
// *not* make property changes during the scope of this call. The node will be
// deleted before any task posted from this scope runs.
virtual void OnBeforeProcessNodeRemoved(const ProcessNode* process_node) {}
// Called after a `process_node` is removed from the graph.
// OnBeforeProcessNodeRemoved() is better for most purposes, but this can be
// useful if an observer needs to check the state of the graph without
// including `process_node`.
//
// Observers may *not* make property changes during the scope of this call.
// The node will be deleted before any task posted from this scope runs.
virtual void OnProcessNodeRemoved(const ProcessNode* process_node) {}
// Notifications of property changes.
// Invoked when the |main_thread_task_load_is_low| property changes.
virtual void OnMainThreadTaskLoadIsLow(const ProcessNode* process_node) {}
// Invoked when the process priority changes.
virtual void OnPriorityChanged(const ProcessNode* process_node,
base::TaskPriority previous_value) {}
// Events with no property changes.
// Fired when all frames in a process have transitioned to being frozen.
virtual void OnAllFramesInProcessFrozen(const ProcessNode* process_node) {}
};
} // namespace performance_manager
#endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PROCESS_NODE_H_
|