1 // Copyright (c) 2012 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 6 #ifndef BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_ 7 #define BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_ 8 9 #include <stdint.h> 10 11 #include <stack> 12 #include <string> 13 #include <vector> 14 15 #include "base/atomicops.h" 16 #include "base/base_export.h" 17 #include "base/callback.h" 18 #include "base/containers/hash_tables.h" 19 #include "base/macros.h" 20 #include "base/memory/ref_counted_memory.h" 21 #include "base/observer_list.h" 22 #include "base/single_thread_task_runner.h" 23 #include "base/strings/string_util.h" 24 #include "base/synchronization/condition_variable.h" 25 #include "base/synchronization/lock.h" 26 #include "base/threading/thread.h" 27 #include "base/threading/thread_local.h" 28 #include "base/trace_event/trace_event_memory_overhead.h" 29 #include "build/build_config.h" 30 31 namespace base { 32 33 class WaitableEvent; 34 class MessageLoop; 35 36 namespace trace_event { 37 38 typedef base::Callback<bool(const char* arg_name)> ArgumentNameFilterPredicate; 39 40 typedef base::Callback<bool(const char* category_group_name, 41 const char* event_name, 42 ArgumentNameFilterPredicate*)> 43 ArgumentFilterPredicate; 44 45 // For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided 46 // class must implement this interface. 47 class BASE_EXPORT ConvertableToTraceFormat 48 : public RefCounted<ConvertableToTraceFormat> { 49 public: 50 // Append the class info to the provided |out| string. The appended 51 // data must be a valid JSON object. Strings must be properly quoted, and 52 // escaped. There is no processing applied to the content after it is 53 // appended. 54 virtual void AppendAsTraceFormat(std::string* out) const = 0; 55 56 virtual void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead); 57 ToString()58 std::string ToString() const { 59 std::string result; 60 AppendAsTraceFormat(&result); 61 return result; 62 } 63 64 protected: ~ConvertableToTraceFormat()65 virtual ~ConvertableToTraceFormat() {} 66 67 private: 68 friend class RefCounted<ConvertableToTraceFormat>; 69 }; 70 71 const int kTraceMaxNumArgs = 2; 72 73 struct TraceEventHandle { 74 uint32_t chunk_seq; 75 // These numbers of bits must be kept consistent with 76 // TraceBufferChunk::kMaxTrunkIndex and 77 // TraceBufferChunk::kTraceBufferChunkSize (in trace_buffer.h). 78 unsigned chunk_index : 26; 79 unsigned event_index : 6; 80 }; 81 82 class BASE_EXPORT TraceEvent { 83 public: 84 union TraceValue { 85 bool as_bool; 86 unsigned long long as_uint; 87 long long as_int; 88 double as_double; 89 const void* as_pointer; 90 const char* as_string; 91 }; 92 93 TraceEvent(); 94 ~TraceEvent(); 95 96 // We don't need to copy TraceEvent except when TraceEventBuffer is cloned. 97 // Use explicit copy method to avoid accidentally misuse of copy. 98 void CopyFrom(const TraceEvent& other); 99 100 void Initialize( 101 int thread_id, 102 TimeTicks timestamp, 103 ThreadTicks thread_timestamp, 104 char phase, 105 const unsigned char* category_group_enabled, 106 const char* name, 107 unsigned long long id, 108 unsigned long long bind_id, 109 int num_args, 110 const char** arg_names, 111 const unsigned char* arg_types, 112 const unsigned long long* arg_values, 113 const scoped_refptr<ConvertableToTraceFormat>* convertable_values, 114 unsigned int flags); 115 116 void Reset(); 117 118 void UpdateDuration(const TimeTicks& now, const ThreadTicks& thread_now); 119 120 void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead); 121 122 // Serialize event data to JSON 123 void AppendAsJSON( 124 std::string* out, 125 const ArgumentFilterPredicate& argument_filter_predicate) const; 126 void AppendPrettyPrinted(std::ostringstream* out) const; 127 128 static void AppendValueAsJSON(unsigned char type, 129 TraceValue value, 130 std::string* out); 131 timestamp()132 TimeTicks timestamp() const { return timestamp_; } thread_timestamp()133 ThreadTicks thread_timestamp() const { return thread_timestamp_; } phase()134 char phase() const { return phase_; } thread_id()135 int thread_id() const { return thread_id_; } duration()136 TimeDelta duration() const { return duration_; } thread_duration()137 TimeDelta thread_duration() const { return thread_duration_; } id()138 unsigned long long id() const { return id_; } flags()139 unsigned int flags() const { return flags_; } 140 141 // Exposed for unittesting: 142 parameter_copy_storage()143 const base::RefCountedString* parameter_copy_storage() const { 144 return parameter_copy_storage_.get(); 145 } 146 category_group_enabled()147 const unsigned char* category_group_enabled() const { 148 return category_group_enabled_; 149 } 150 name()151 const char* name() const { return name_; } 152 153 #if defined(OS_ANDROID) 154 void SendToATrace(); 155 #endif 156 157 private: 158 // Note: these are ordered by size (largest first) for optimal packing. 159 TimeTicks timestamp_; 160 ThreadTicks thread_timestamp_; 161 TimeDelta duration_; 162 TimeDelta thread_duration_; 163 // id_ can be used to store phase-specific data. 164 unsigned long long id_; 165 TraceValue arg_values_[kTraceMaxNumArgs]; 166 const char* arg_names_[kTraceMaxNumArgs]; 167 scoped_refptr<ConvertableToTraceFormat> convertable_values_[kTraceMaxNumArgs]; 168 const unsigned char* category_group_enabled_; 169 const char* name_; 170 scoped_refptr<base::RefCountedString> parameter_copy_storage_; 171 // Depending on TRACE_EVENT_FLAG_HAS_PROCESS_ID the event will have either: 172 // tid: thread_id_, pid: current_process_id (default case). 173 // tid: -1, pid: process_id_ (when flags_ & TRACE_EVENT_FLAG_HAS_PROCESS_ID). 174 union { 175 int thread_id_; 176 int process_id_; 177 }; 178 unsigned int flags_; 179 unsigned long long bind_id_; 180 unsigned char arg_types_[kTraceMaxNumArgs]; 181 char phase_; 182 183 DISALLOW_COPY_AND_ASSIGN(TraceEvent); 184 }; 185 186 } // namespace trace_event 187 } // namespace base 188 189 #endif // BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_ 190