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 <memory> 12 #include <stack> 13 #include <string> 14 #include <vector> 15 16 #include "base/atomicops.h" 17 #include "base/base_export.h" 18 #include "base/callback.h" 19 #include "base/containers/hash_tables.h" 20 #include "base/macros.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: ConvertableToTraceFormat()49 ConvertableToTraceFormat() {} ~ConvertableToTraceFormat()50 virtual ~ConvertableToTraceFormat() {} 51 52 // Append the class info to the provided |out| string. The appended 53 // data must be a valid JSON object. Strings must be properly quoted, and 54 // escaped. There is no processing applied to the content after it is 55 // appended. 56 virtual void AppendAsTraceFormat(std::string* out) const = 0; 57 58 virtual void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead); 59 ToString()60 std::string ToString() const { 61 std::string result; 62 AppendAsTraceFormat(&result); 63 return result; 64 } 65 66 private: 67 DISALLOW_COPY_AND_ASSIGN(ConvertableToTraceFormat); 68 }; 69 70 const int kTraceMaxNumArgs = 2; 71 72 struct TraceEventHandle { 73 uint32_t chunk_seq; 74 // These numbers of bits must be kept consistent with 75 // TraceBufferChunk::kMaxTrunkIndex and 76 // TraceBufferChunk::kTraceBufferChunkSize (in trace_buffer.h). 77 unsigned chunk_index : 26; 78 unsigned event_index : 6; 79 }; 80 81 class BASE_EXPORT TraceEvent { 82 public: 83 union TraceValue { 84 bool as_bool; 85 unsigned long long as_uint; 86 long long as_int; 87 double as_double; 88 const void* as_pointer; 89 const char* as_string; 90 }; 91 92 TraceEvent(); 93 ~TraceEvent(); 94 95 void MoveFrom(std::unique_ptr<TraceEvent> other); 96 97 void Initialize(int thread_id, 98 TimeTicks timestamp, 99 ThreadTicks thread_timestamp, 100 char phase, 101 const unsigned char* category_group_enabled, 102 const char* name, 103 const char* scope, 104 unsigned long long id, 105 unsigned long long bind_id, 106 int num_args, 107 const char** arg_names, 108 const unsigned char* arg_types, 109 const unsigned long long* arg_values, 110 std::unique_ptr<ConvertableToTraceFormat>* convertable_values, 111 unsigned int flags); 112 113 void Reset(); 114 115 void UpdateDuration(const TimeTicks& now, const ThreadTicks& thread_now); 116 117 void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead); 118 119 // Serialize event data to JSON 120 void AppendAsJSON( 121 std::string* out, 122 const ArgumentFilterPredicate& argument_filter_predicate) const; 123 void AppendPrettyPrinted(std::ostringstream* out) const; 124 125 static void AppendValueAsJSON(unsigned char type, 126 TraceValue value, 127 std::string* out); 128 timestamp()129 TimeTicks timestamp() const { return timestamp_; } thread_timestamp()130 ThreadTicks thread_timestamp() const { return thread_timestamp_; } phase()131 char phase() const { return phase_; } thread_id()132 int thread_id() const { return thread_id_; } duration()133 TimeDelta duration() const { return duration_; } thread_duration()134 TimeDelta thread_duration() const { return thread_duration_; } scope()135 const char* scope() const { return scope_; } id()136 unsigned long long id() const { return id_; } flags()137 unsigned int flags() const { return flags_; } 138 139 // Exposed for unittesting: 140 parameter_copy_storage()141 const std::string* parameter_copy_storage() const { 142 return parameter_copy_storage_.get(); 143 } 144 category_group_enabled()145 const unsigned char* category_group_enabled() const { 146 return category_group_enabled_; 147 } 148 name()149 const char* name() const { return name_; } 150 151 #if defined(OS_ANDROID) 152 void SendToATrace(); 153 #endif 154 155 private: 156 // Note: these are ordered by size (largest first) for optimal packing. 157 TimeTicks timestamp_; 158 ThreadTicks thread_timestamp_; 159 TimeDelta duration_; 160 TimeDelta thread_duration_; 161 // scope_ and id_ can be used to store phase-specific data. 162 const char* scope_; 163 unsigned long long id_; 164 TraceValue arg_values_[kTraceMaxNumArgs]; 165 const char* arg_names_[kTraceMaxNumArgs]; 166 std::unique_ptr<ConvertableToTraceFormat> 167 convertable_values_[kTraceMaxNumArgs]; 168 const unsigned char* category_group_enabled_; 169 const char* name_; 170 std::unique_ptr<std::string> 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