xref: /aosp_15_r20/external/libchrome/base/trace_event/blame_context.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright 2016 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_TRACE_EVENT_BLAME_CONTEXT_H_
6*635a8641SAndroid Build Coastguard Worker #define BASE_TRACE_EVENT_BLAME_CONTEXT_H_
7*635a8641SAndroid Build Coastguard Worker 
8*635a8641SAndroid Build Coastguard Worker #include <inttypes.h>
9*635a8641SAndroid Build Coastguard Worker 
10*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h"
11*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread_checker.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/trace_log.h"
14*635a8641SAndroid Build Coastguard Worker 
15*635a8641SAndroid Build Coastguard Worker namespace base {
16*635a8641SAndroid Build Coastguard Worker namespace trace_event {
17*635a8641SAndroid Build Coastguard Worker class TracedValue;
18*635a8641SAndroid Build Coastguard Worker }
19*635a8641SAndroid Build Coastguard Worker 
20*635a8641SAndroid Build Coastguard Worker namespace trace_event {
21*635a8641SAndroid Build Coastguard Worker 
22*635a8641SAndroid Build Coastguard Worker // A blame context represents a logical unit to which we want to attribute
23*635a8641SAndroid Build Coastguard Worker // different costs (e.g., CPU, network, or memory usage). An example of a blame
24*635a8641SAndroid Build Coastguard Worker // context is an <iframe> element on a web page. Different subsystems can
25*635a8641SAndroid Build Coastguard Worker // "enter" and "leave" blame contexts to indicate that they are doing work which
26*635a8641SAndroid Build Coastguard Worker // should be accounted against this blame context.
27*635a8641SAndroid Build Coastguard Worker //
28*635a8641SAndroid Build Coastguard Worker // A blame context can optionally have a parent context, forming a blame context
29*635a8641SAndroid Build Coastguard Worker // tree. When work is attributed to a particular blame context, it is considered
30*635a8641SAndroid Build Coastguard Worker // to count against all of that context's children too. This is useful when work
31*635a8641SAndroid Build Coastguard Worker // cannot be exactly attributed into a more specific context. For example,
32*635a8641SAndroid Build Coastguard Worker // Javascript garbage collection generally needs to inspect all objects on a
33*635a8641SAndroid Build Coastguard Worker // page instead looking at each <iframe> individually. In this case the work
34*635a8641SAndroid Build Coastguard Worker // should be attributed to a blame context which is the parent of all <iframe>
35*635a8641SAndroid Build Coastguard Worker // blame contexts.
36*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT BlameContext
37*635a8641SAndroid Build Coastguard Worker     : public trace_event::TraceLog::AsyncEnabledStateObserver {
38*635a8641SAndroid Build Coastguard Worker  public:
39*635a8641SAndroid Build Coastguard Worker   // Construct a blame context belonging to the blame context tree |name|, using
40*635a8641SAndroid Build Coastguard Worker   // the tracing category |category|, identified by |id| from the |scope|
41*635a8641SAndroid Build Coastguard Worker   // namespace. |type| identifies the type of this object snapshot in the blame
42*635a8641SAndroid Build Coastguard Worker   // context tree. |parent_context| is the parent of this blame context or
43*635a8641SAndroid Build Coastguard Worker   // null. Note that all strings must have application lifetime.
44*635a8641SAndroid Build Coastguard Worker   //
45*635a8641SAndroid Build Coastguard Worker   // For example, a blame context which represents a specific <iframe> in a
46*635a8641SAndroid Build Coastguard Worker   // browser frame tree could be specified with:
47*635a8641SAndroid Build Coastguard Worker   //
48*635a8641SAndroid Build Coastguard Worker   //   category="blink",
49*635a8641SAndroid Build Coastguard Worker   //   name="FrameTree",
50*635a8641SAndroid Build Coastguard Worker   //   type="IFrame",
51*635a8641SAndroid Build Coastguard Worker   //   scope="IFrameIdentifier",
52*635a8641SAndroid Build Coastguard Worker   //   id=1234.
53*635a8641SAndroid Build Coastguard Worker   //
54*635a8641SAndroid Build Coastguard Worker   // Each <iframe> blame context could have another <iframe> context as a
55*635a8641SAndroid Build Coastguard Worker   // parent, or a top-level context which represents the entire browser:
56*635a8641SAndroid Build Coastguard Worker   //
57*635a8641SAndroid Build Coastguard Worker   //   category="blink",
58*635a8641SAndroid Build Coastguard Worker   //   name="FrameTree",
59*635a8641SAndroid Build Coastguard Worker   //   type="Browser",
60*635a8641SAndroid Build Coastguard Worker   //   scope="BrowserIdentifier",
61*635a8641SAndroid Build Coastguard Worker   //   id=1.
62*635a8641SAndroid Build Coastguard Worker   //
63*635a8641SAndroid Build Coastguard Worker   // Note that the |name| property is identical, signifying that both context
64*635a8641SAndroid Build Coastguard Worker   // types are part of the same tree.
65*635a8641SAndroid Build Coastguard Worker   //
66*635a8641SAndroid Build Coastguard Worker   BlameContext(const char* category,
67*635a8641SAndroid Build Coastguard Worker                const char* name,
68*635a8641SAndroid Build Coastguard Worker                const char* type,
69*635a8641SAndroid Build Coastguard Worker                const char* scope,
70*635a8641SAndroid Build Coastguard Worker                int64_t id,
71*635a8641SAndroid Build Coastguard Worker                const BlameContext* parent_context);
72*635a8641SAndroid Build Coastguard Worker   ~BlameContext() override;
73*635a8641SAndroid Build Coastguard Worker 
74*635a8641SAndroid Build Coastguard Worker   // Initialize the blame context, automatically taking a snapshot if tracing is
75*635a8641SAndroid Build Coastguard Worker   // enabled. Must be called before any other methods on this class.
76*635a8641SAndroid Build Coastguard Worker   void Initialize();
77*635a8641SAndroid Build Coastguard Worker 
78*635a8641SAndroid Build Coastguard Worker   // Indicate that the current thread is now doing work which should count
79*635a8641SAndroid Build Coastguard Worker   // against this blame context.  This function is allowed to be called in a
80*635a8641SAndroid Build Coastguard Worker   // thread different from where the blame context was created; However, any
81*635a8641SAndroid Build Coastguard Worker   // client doing that must be fully responsible for ensuring thready safety.
82*635a8641SAndroid Build Coastguard Worker   void Enter();
83*635a8641SAndroid Build Coastguard Worker 
84*635a8641SAndroid Build Coastguard Worker   // Leave and stop doing work for a previously entered blame context. If
85*635a8641SAndroid Build Coastguard Worker   // another blame context belonging to the same tree was entered prior to this
86*635a8641SAndroid Build Coastguard Worker   // one, it becomes the active blame context for this thread again.  Similar
87*635a8641SAndroid Build Coastguard Worker   // to Enter(), this function can be called in a thread different from where
88*635a8641SAndroid Build Coastguard Worker   // the blame context was created, and the same requirement on thread safety
89*635a8641SAndroid Build Coastguard Worker   // must be satisfied.
90*635a8641SAndroid Build Coastguard Worker   void Leave();
91*635a8641SAndroid Build Coastguard Worker 
92*635a8641SAndroid Build Coastguard Worker   // Record a snapshot of the blame context. This is normally only needed if a
93*635a8641SAndroid Build Coastguard Worker   // blame context subclass defines custom properties (see AsValueInto) and one
94*635a8641SAndroid Build Coastguard Worker   // or more of those properties have changed.
95*635a8641SAndroid Build Coastguard Worker   void TakeSnapshot();
96*635a8641SAndroid Build Coastguard Worker 
category()97*635a8641SAndroid Build Coastguard Worker   const char* category() const { return category_; }
name()98*635a8641SAndroid Build Coastguard Worker   const char* name() const { return name_; }
type()99*635a8641SAndroid Build Coastguard Worker   const char* type() const { return type_; }
scope()100*635a8641SAndroid Build Coastguard Worker   const char* scope() const { return scope_; }
id()101*635a8641SAndroid Build Coastguard Worker   int64_t id() const { return id_; }
102*635a8641SAndroid Build Coastguard Worker 
103*635a8641SAndroid Build Coastguard Worker   // trace_event::TraceLog::EnabledStateObserver implementation:
104*635a8641SAndroid Build Coastguard Worker   void OnTraceLogEnabled() override;
105*635a8641SAndroid Build Coastguard Worker   void OnTraceLogDisabled() override;
106*635a8641SAndroid Build Coastguard Worker 
107*635a8641SAndroid Build Coastguard Worker  protected:
108*635a8641SAndroid Build Coastguard Worker   // Serialize the properties of this blame context into |state|. Subclasses can
109*635a8641SAndroid Build Coastguard Worker   // override this method to record additional properties (e.g, the URL for an
110*635a8641SAndroid Build Coastguard Worker   // <iframe> blame context). Note that an overridden implementation must still
111*635a8641SAndroid Build Coastguard Worker   // call this base method.
112*635a8641SAndroid Build Coastguard Worker   virtual void AsValueInto(trace_event::TracedValue* state);
113*635a8641SAndroid Build Coastguard Worker 
114*635a8641SAndroid Build Coastguard Worker  private:
115*635a8641SAndroid Build Coastguard Worker   bool WasInitialized() const;
116*635a8641SAndroid Build Coastguard Worker 
117*635a8641SAndroid Build Coastguard Worker   // The following string pointers have application lifetime.
118*635a8641SAndroid Build Coastguard Worker   const char* category_;
119*635a8641SAndroid Build Coastguard Worker   const char* name_;
120*635a8641SAndroid Build Coastguard Worker   const char* type_;
121*635a8641SAndroid Build Coastguard Worker   const char* scope_;
122*635a8641SAndroid Build Coastguard Worker   const int64_t id_;
123*635a8641SAndroid Build Coastguard Worker 
124*635a8641SAndroid Build Coastguard Worker   const char* parent_scope_;
125*635a8641SAndroid Build Coastguard Worker   const int64_t parent_id_;
126*635a8641SAndroid Build Coastguard Worker 
127*635a8641SAndroid Build Coastguard Worker   const unsigned char* category_group_enabled_;
128*635a8641SAndroid Build Coastguard Worker 
129*635a8641SAndroid Build Coastguard Worker   ThreadChecker thread_checker_;
130*635a8641SAndroid Build Coastguard Worker   WeakPtrFactory<BlameContext> weak_factory_;
131*635a8641SAndroid Build Coastguard Worker 
132*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(BlameContext);
133*635a8641SAndroid Build Coastguard Worker };
134*635a8641SAndroid Build Coastguard Worker 
135*635a8641SAndroid Build Coastguard Worker }  // namespace trace_event
136*635a8641SAndroid Build Coastguard Worker }  // namespace base
137*635a8641SAndroid Build Coastguard Worker 
138*635a8641SAndroid Build Coastguard Worker #endif  // BASE_TRACE_EVENT_BLAME_CONTEXT_H_
139