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