1b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Use of this source code is governed by a BSD-style license that can be 3b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// found in the LICENSE file. 4b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 5b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 6b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#ifndef BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_ 7b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#define BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_ 8b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 90d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include <stdint.h> 100d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko 1194ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez#include <memory> 12b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <stack> 13b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <string> 14b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <vector> 15b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 16b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/atomicops.h" 17b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/base_export.h" 18b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/callback.h" 19b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/containers/hash_tables.h" 200d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/macros.h" 21b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/observer_list.h" 22b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/single_thread_task_runner.h" 23b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/strings/string_util.h" 24b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/synchronization/condition_variable.h" 25b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/synchronization/lock.h" 26b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/threading/thread.h" 27b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/threading/thread_local.h" 28b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/trace_event/trace_event_memory_overhead.h" 290d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "build/build_config.h" 30b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 31b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace base { 32b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 33b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass WaitableEvent; 34b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass MessageLoop; 35b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 36b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace trace_event { 37b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 380d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotypedef base::Callback<bool(const char* arg_name)> ArgumentNameFilterPredicate; 390d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko 400d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotypedef base::Callback<bool(const char* category_group_name, 410d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko const char* event_name, 420d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko ArgumentNameFilterPredicate*)> 430d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko ArgumentFilterPredicate; 440d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko 45b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided 46b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// class must implement this interface. 4745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkoclass BASE_EXPORT ConvertableToTraceFormat { 48b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat public: 4945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko ConvertableToTraceFormat() {} 5045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko virtual ~ConvertableToTraceFormat() {} 5145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 52b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Append the class info to the provided |out| string. The appended 53b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // data must be a valid JSON object. Strings must be properly quoted, and 54b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // escaped. There is no processing applied to the content after it is 55b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // appended. 56b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat virtual void AppendAsTraceFormat(std::string* out) const = 0; 57b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 58b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat virtual void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead); 59b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 60b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat std::string ToString() const { 61b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat std::string result; 62b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat AppendAsTraceFormat(&result); 63b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return result; 64b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 65b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 66b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat private: 6745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko DISALLOW_COPY_AND_ASSIGN(ConvertableToTraceFormat); 68b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}; 69b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 700d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoconst int kTraceMaxNumArgs = 2; 710d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko 72b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratstruct TraceEventHandle { 730d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko uint32_t chunk_seq; 740d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko // These numbers of bits must be kept consistent with 750d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko // TraceBufferChunk::kMaxTrunkIndex and 760d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko // TraceBufferChunk::kTraceBufferChunkSize (in trace_buffer.h). 770d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko unsigned chunk_index : 26; 780d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko unsigned event_index : 6; 79b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}; 80b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 81b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass BASE_EXPORT TraceEvent { 82b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat public: 83b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat union TraceValue { 84b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat bool as_bool; 85b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat unsigned long long as_uint; 86b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat long long as_int; 87b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat double as_double; 88b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const void* as_pointer; 89b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* as_string; 90b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat }; 91b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 92b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat TraceEvent(); 93b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ~TraceEvent(); 94b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 9594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez void MoveFrom(std::unique_ptr<TraceEvent> other); 9645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 9745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko void Initialize(int thread_id, 9845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko TimeTicks timestamp, 9945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko ThreadTicks thread_timestamp, 10045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko char phase, 10145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko const unsigned char* category_group_enabled, 10245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko const char* name, 10345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko const char* scope, 10445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko unsigned long long id, 10545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko unsigned long long bind_id, 10645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko int num_args, 10745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko const char** arg_names, 10845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko const unsigned char* arg_types, 10945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko const unsigned long long* arg_values, 11094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez std::unique_ptr<ConvertableToTraceFormat>* convertable_values, 11145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko unsigned int flags); 112b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 113b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void Reset(); 114b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 1150d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko void UpdateDuration(const TimeTicks& now, const ThreadTicks& thread_now); 116b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 1170d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead); 118b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 119b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Serialize event data to JSON 120b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void AppendAsJSON( 121b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat std::string* out, 122b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const ArgumentFilterPredicate& argument_filter_predicate) const; 123b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void AppendPrettyPrinted(std::ostringstream* out) const; 124b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 125b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat static void AppendValueAsJSON(unsigned char type, 126b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat TraceValue value, 127b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat std::string* out); 128b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 1290d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko TimeTicks timestamp() const { return timestamp_; } 130b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ThreadTicks thread_timestamp() const { return thread_timestamp_; } 131b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat char phase() const { return phase_; } 132b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int thread_id() const { return thread_id_; } 133b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat TimeDelta duration() const { return duration_; } 134b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat TimeDelta thread_duration() const { return thread_duration_; } 13545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko const char* scope() const { return scope_; } 136b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat unsigned long long id() const { return id_; } 1370d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko unsigned int flags() const { return flags_; } 138b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 139b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Exposed for unittesting: 140b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 14145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko const std::string* parameter_copy_storage() const { 142b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return parameter_copy_storage_.get(); 143b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 144b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 145b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const unsigned char* category_group_enabled() const { 146b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return category_group_enabled_; 147b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 148b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 149b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* name() const { return name_; } 150b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 151b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if defined(OS_ANDROID) 152b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void SendToATrace(); 153b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif 154b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 155b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat private: 156b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Note: these are ordered by size (largest first) for optimal packing. 1570d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko TimeTicks timestamp_; 158b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ThreadTicks thread_timestamp_; 159b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat TimeDelta duration_; 160b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat TimeDelta thread_duration_; 16145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko // scope_ and id_ can be used to store phase-specific data. 16245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko const char* scope_; 163b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat unsigned long long id_; 164b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat TraceValue arg_values_[kTraceMaxNumArgs]; 165b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* arg_names_[kTraceMaxNumArgs]; 16694ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez std::unique_ptr<ConvertableToTraceFormat> 16794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez convertable_values_[kTraceMaxNumArgs]; 168b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const unsigned char* category_group_enabled_; 169b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* name_; 17094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez std::unique_ptr<std::string> parameter_copy_storage_; 1710d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko // Depending on TRACE_EVENT_FLAG_HAS_PROCESS_ID the event will have either: 1720d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko // tid: thread_id_, pid: current_process_id (default case). 1730d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko // tid: -1, pid: process_id_ (when flags_ & TRACE_EVENT_FLAG_HAS_PROCESS_ID). 1740d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko union { 1750d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko int thread_id_; 1760d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko int process_id_; 1770d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko }; 1780d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko unsigned int flags_; 1790d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko unsigned long long bind_id_; 180b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat unsigned char arg_types_[kTraceMaxNumArgs]; 1810d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko char phase_; 182b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 183b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DISALLOW_COPY_AND_ASSIGN(TraceEvent); 184b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}; 185b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 186b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} // namespace trace_event 187b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} // namespace base 188b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 189b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif // BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_ 190