|  | // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  |  | 
|  | #ifndef BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_ | 
|  | #define BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_ | 
|  |  | 
|  | #include <memory> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | #include "base/atomicops.h" | 
|  | #include "base/base_export.h" | 
|  | #include "base/callback.h" | 
|  | #include "base/containers/hash_tables.h" | 
|  | #include "base/macros.h" | 
|  | #include "base/observer_list.h" | 
|  | #include "base/single_thread_task_runner.h" | 
|  | #include "base/strings/string_util.h" | 
|  | #include "base/synchronization/condition_variable.h" | 
|  | #include "base/synchronization/lock.h" | 
|  | #include "base/threading/thread_local.h" | 
|  | #include "base/trace_event/trace_event_memory_overhead.h" | 
|  | #include "build/build_config.h" | 
|  | #include "starboard/types.h" | 
|  |  | 
|  | namespace base { | 
|  | namespace trace_event { | 
|  |  | 
|  | typedef base::Callback<bool(const char* arg_name)> ArgumentNameFilterPredicate; | 
|  |  | 
|  | typedef base::Callback<bool(const char* category_group_name, | 
|  | const char* event_name, | 
|  | ArgumentNameFilterPredicate*)> | 
|  | ArgumentFilterPredicate; | 
|  |  | 
|  | // For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided | 
|  | // class must implement this interface. | 
|  | class BASE_EXPORT ConvertableToTraceFormat { | 
|  | public: | 
|  | ConvertableToTraceFormat() = default; | 
|  | virtual ~ConvertableToTraceFormat() = default; | 
|  |  | 
|  | // Append the class info to the provided |out| string. The appended | 
|  | // data must be a valid JSON object. Strings must be properly quoted, and | 
|  | // escaped. There is no processing applied to the content after it is | 
|  | // appended. | 
|  | virtual void AppendAsTraceFormat(std::string* out) const = 0; | 
|  |  | 
|  | virtual void EstimateTraceMemoryOverhead( | 
|  | TraceEventMemoryOverhead* /*overhead*/){}; | 
|  |  | 
|  | std::string ToString() const { | 
|  | std::string result; | 
|  | AppendAsTraceFormat(&result); | 
|  | return result; | 
|  | } | 
|  |  | 
|  | private: | 
|  | DISALLOW_COPY_AND_ASSIGN(ConvertableToTraceFormat); | 
|  | }; | 
|  |  | 
|  | const int kTraceMaxNumArgs = 2; | 
|  |  | 
|  | struct TraceEventHandle { | 
|  | uint32_t chunk_seq; | 
|  | // These numbers of bits must be kept consistent with | 
|  | // TraceBufferChunk::kMaxTrunkIndex and | 
|  | // TraceBufferChunk::kTraceBufferChunkSize (in trace_buffer.h). | 
|  | unsigned chunk_index : 26; | 
|  | unsigned event_index : 6; | 
|  | }; | 
|  |  | 
|  | class BASE_EXPORT TraceEvent { | 
|  | public: | 
|  | union TraceValue { | 
|  | bool as_bool; | 
|  | unsigned long long as_uint; | 
|  | long long as_int; | 
|  | double as_double; | 
|  | const void* as_pointer; | 
|  | const char* as_string; | 
|  | }; | 
|  |  | 
|  | TraceEvent(); | 
|  | ~TraceEvent(); | 
|  |  | 
|  | void MoveFrom(std::unique_ptr<TraceEvent> other); | 
|  |  | 
|  | void Initialize(int thread_id, | 
|  | TimeTicks timestamp, | 
|  | ThreadTicks thread_timestamp, | 
|  | char phase, | 
|  | const unsigned char* category_group_enabled, | 
|  | const char* name, | 
|  | const char* scope, | 
|  | unsigned long long id, | 
|  | unsigned long long bind_id, | 
|  | int num_args, | 
|  | const char* const* arg_names, | 
|  | const unsigned char* arg_types, | 
|  | const unsigned long long* arg_values, | 
|  | std::unique_ptr<ConvertableToTraceFormat>* convertable_values, | 
|  | unsigned int flags); | 
|  |  | 
|  | void Reset(); | 
|  |  | 
|  | void UpdateDuration(const TimeTicks& now, const ThreadTicks& thread_now); | 
|  |  | 
|  | void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead); | 
|  |  | 
|  | // Serialize event data to JSON | 
|  | void AppendAsJSON( | 
|  | std::string* out, | 
|  | const ArgumentFilterPredicate& argument_filter_predicate) const; | 
|  | void AppendPrettyPrinted(std::ostringstream* out) const; | 
|  |  | 
|  | static void AppendValueAsJSON(unsigned char type, | 
|  | TraceValue value, | 
|  | std::string* out); | 
|  |  | 
|  | TimeTicks timestamp() const { return timestamp_; } | 
|  | ThreadTicks thread_timestamp() const { return thread_timestamp_; } | 
|  | char phase() const { return phase_; } | 
|  | int thread_id() const { return thread_id_; } | 
|  | TimeDelta duration() const { return duration_; } | 
|  | TimeDelta thread_duration() const { return thread_duration_; } | 
|  | const char* scope() const { return scope_; } | 
|  | unsigned long long id() const { return id_; } | 
|  | unsigned int flags() const { return flags_; } | 
|  | unsigned long long bind_id() const { return bind_id_; } | 
|  | // Exposed for unittesting: | 
|  |  | 
|  | const std::string* parameter_copy_storage() const { | 
|  | return parameter_copy_storage_.get(); | 
|  | } | 
|  |  | 
|  | const unsigned char* category_group_enabled() const { | 
|  | return category_group_enabled_; | 
|  | } | 
|  |  | 
|  | const char* name() const { return name_; } | 
|  |  | 
|  | unsigned char arg_type(size_t index) const { return arg_types_[index]; } | 
|  | const char* arg_name(size_t index) const { return arg_names_[index]; } | 
|  | const TraceValue& arg_value(size_t index) const { return arg_values_[index]; } | 
|  |  | 
|  | const ConvertableToTraceFormat* arg_convertible_value(size_t index) const { | 
|  | return convertable_values_[index].get(); | 
|  | } | 
|  |  | 
|  | #if defined(OS_ANDROID) | 
|  | void SendToATrace(); | 
|  | #endif | 
|  |  | 
|  | private: | 
|  | // Note: these are ordered by size (largest first) for optimal packing. | 
|  | TimeTicks timestamp_; | 
|  | ThreadTicks thread_timestamp_; | 
|  | TimeDelta duration_; | 
|  | TimeDelta thread_duration_; | 
|  | // scope_ and id_ can be used to store phase-specific data. | 
|  | const char* scope_; | 
|  | unsigned long long id_; | 
|  | TraceValue arg_values_[kTraceMaxNumArgs]; | 
|  | const char* arg_names_[kTraceMaxNumArgs]; | 
|  | std::unique_ptr<ConvertableToTraceFormat> | 
|  | convertable_values_[kTraceMaxNumArgs]; | 
|  | const unsigned char* category_group_enabled_; | 
|  | const char* name_; | 
|  | std::unique_ptr<std::string> parameter_copy_storage_; | 
|  | // Depending on TRACE_EVENT_FLAG_HAS_PROCESS_ID the event will have either: | 
|  | //  tid: thread_id_, pid: current_process_id (default case). | 
|  | //  tid: -1, pid: process_id_ (when flags_ & TRACE_EVENT_FLAG_HAS_PROCESS_ID). | 
|  | union { | 
|  | int thread_id_; | 
|  | int process_id_; | 
|  | }; | 
|  | unsigned int flags_; | 
|  | unsigned long long bind_id_; | 
|  | unsigned char arg_types_[kTraceMaxNumArgs]; | 
|  | char phase_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(TraceEvent); | 
|  | }; | 
|  |  | 
|  | }  // namespace trace_event | 
|  | }  // namespace base | 
|  |  | 
|  | #endif  // BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_ |