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