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