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 <string> 13 #include <vector> 14 15 #include "base/atomicops.h" 16 #include "base/base_export.h" 17 #include "base/callback.h" 18 #include "base/macros.h" 19 #include "base/observer_list.h" 20 #include "base/single_thread_task_runner.h" 21 #include "base/strings/string_util.h" 22 #include "base/synchronization/condition_variable.h" 23 #include "base/synchronization/lock.h" 24 #include "base/threading/thread_local.h" 25 #include "base/trace_event/common/trace_event_common.h" 26 #include "base/trace_event/thread_instruction_count.h" 27 #include "base/trace_event/trace_arguments.h" 28 #include "base/trace_event/trace_event_memory_overhead.h" 29 #include "build/build_config.h" 30 31 namespace base { 32 namespace trace_event { 33 34 typedef base::RepeatingCallback<bool(const char* arg_name)> 35 ArgumentNameFilterPredicate; 36 37 typedef base::RepeatingCallback<bool(const char* category_group_name, 38 const char* event_name, 39 ArgumentNameFilterPredicate*)> 40 ArgumentFilterPredicate; 41 42 typedef base::RepeatingCallback<bool(const std::string& metadata_name)> 43 MetadataFilterPredicate; 44 45 struct TraceEventHandle { 46 uint32_t chunk_seq; 47 // These numbers of bits must be kept consistent with 48 // TraceBufferChunk::kMaxTrunkIndex and 49 // TraceBufferChunk::kTraceBufferChunkSize (in trace_buffer.h). 50 unsigned chunk_index : 26; 51 unsigned event_index : 6; 52 }; 53 54 class BASE_EXPORT TraceEvent { 55 public: 56 // TODO(898794): Remove once all users have been updated. 57 using TraceValue = base::trace_event::TraceValue; 58 59 TraceEvent(); 60 61 TraceEvent(int thread_id, 62 TimeTicks timestamp, 63 ThreadTicks thread_timestamp, 64 ThreadInstructionCount thread_instruction_count, 65 char phase, 66 const unsigned char* category_group_enabled, 67 const char* name, 68 const char* scope, 69 unsigned long long id, 70 unsigned long long bind_id, 71 TraceArguments* args, 72 unsigned int flags); 73 74 ~TraceEvent(); 75 76 // Allow move operations. 77 TraceEvent(TraceEvent&&) noexcept; 78 TraceEvent& operator=(TraceEvent&&) noexcept; 79 80 // Reset instance to empty state. 81 void Reset(); 82 83 // Reset instance to new state. This is equivalent but slightly more 84 // efficient than doing a move assignment, since it avoids creating 85 // temporary copies. I.e. compare these two statements: 86 // 87 // event = TraceEvent(thread_id, ....); // Create and destroy temporary. 88 // event.Reset(thread_id, ...); // Direct re-initialization. 89 // 90 void Reset(int thread_id, 91 TimeTicks timestamp, 92 ThreadTicks thread_timestamp, 93 ThreadInstructionCount thread_instruction_count, 94 char phase, 95 const unsigned char* category_group_enabled, 96 const char* name, 97 const char* scope, 98 unsigned long long id, 99 unsigned long long bind_id, 100 TraceArguments* args, 101 unsigned int flags); 102 103 void UpdateDuration(const TimeTicks& now, 104 const ThreadTicks& thread_now, 105 ThreadInstructionCount thread_instruction_now); 106 107 void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead); 108 109 // Serialize event data to JSON 110 void AppendAsJSON( 111 std::string* out, 112 const ArgumentFilterPredicate& argument_filter_predicate) const; 113 void AppendPrettyPrinted(std::ostringstream* out) const; 114 timestamp()115 TimeTicks timestamp() const { return timestamp_; } thread_timestamp()116 ThreadTicks thread_timestamp() const { return thread_timestamp_; } thread_instruction_count()117 ThreadInstructionCount thread_instruction_count() const { 118 return thread_instruction_count_; 119 } phase()120 char phase() const { return phase_; } thread_id()121 int thread_id() const { return thread_id_; } process_id()122 int process_id() const { return process_id_; } duration()123 TimeDelta duration() const { return duration_; } thread_duration()124 TimeDelta thread_duration() const { return thread_duration_; } thread_instruction_delta()125 ThreadInstructionDelta thread_instruction_delta() const { 126 return thread_instruction_delta_; 127 } scope()128 const char* scope() const { return scope_; } id()129 unsigned long long id() const { return id_; } flags()130 unsigned int flags() const { return flags_; } bind_id()131 unsigned long long bind_id() const { return bind_id_; } 132 // Exposed for unittesting: 133 parameter_copy_storage()134 const StringStorage& parameter_copy_storage() const { 135 return parameter_copy_storage_; 136 } 137 category_group_enabled()138 const unsigned char* category_group_enabled() const { 139 return category_group_enabled_; 140 } 141 name()142 const char* name() const { return name_; } 143 arg_size()144 size_t arg_size() const { return args_.size(); } arg_type(size_t index)145 unsigned char arg_type(size_t index) const { return args_.types()[index]; } arg_name(size_t index)146 const char* arg_name(size_t index) const { return args_.names()[index]; } arg_value(size_t index)147 const TraceValue& arg_value(size_t index) const { 148 return args_.values()[index]; 149 } 150 arg_convertible_value(size_t index)151 ConvertableToTraceFormat* arg_convertible_value(size_t index) { 152 return (arg_type(index) == TRACE_VALUE_TYPE_CONVERTABLE) 153 ? arg_value(index).as_convertable 154 : nullptr; 155 } 156 157 #if defined(OS_ANDROID) 158 void SendToATrace(); 159 #endif 160 161 private: 162 void InitArgs(TraceArguments* args); 163 164 // Note: these are ordered by size (largest first) for optimal packing. 165 TimeTicks timestamp_ = TimeTicks(); 166 ThreadTicks thread_timestamp_ = ThreadTicks(); 167 TimeDelta duration_ = TimeDelta::FromInternalValue(-1); 168 TimeDelta thread_duration_ = TimeDelta(); 169 ThreadInstructionCount thread_instruction_count_ = ThreadInstructionCount(); 170 ThreadInstructionDelta thread_instruction_delta_ = ThreadInstructionDelta(); 171 // scope_ and id_ can be used to store phase-specific data. 172 // The following should be default-initialized to the expression 173 // trace_event_internal::kGlobalScope, which is nullptr, but its definition 174 // cannot be included here due to cyclical header dependencies. 175 // The equivalence is checked with a static_assert() in trace_event_impl.cc. 176 const char* scope_ = nullptr; 177 unsigned long long id_ = 0u; 178 const unsigned char* category_group_enabled_ = nullptr; 179 const char* name_ = nullptr; 180 StringStorage parameter_copy_storage_; 181 TraceArguments args_; 182 // Depending on TRACE_EVENT_FLAG_HAS_PROCESS_ID the event will have either: 183 // tid: thread_id_, pid: current_process_id (default case). 184 // tid: -1, pid: process_id_ (when flags_ & TRACE_EVENT_FLAG_HAS_PROCESS_ID). 185 union { 186 int thread_id_ = 0; 187 int process_id_; 188 }; 189 unsigned int flags_ = 0; 190 unsigned long long bind_id_ = 0; 191 char phase_ = TRACE_EVENT_PHASE_BEGIN; 192 193 DISALLOW_COPY_AND_ASSIGN(TraceEvent); 194 }; 195 196 } // namespace trace_event 197 } // namespace base 198 199 #endif // BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_ 200