trace_event_impl.h revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_DEBUG_TRACE_EVENT_IMPL_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_DEBUG_TRACE_EVENT_IMPL_H_ 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <stack> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/atomicops.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h" 16b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/gtest_prod_util.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted_memory.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_vector.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/observer_list.h" 205e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/condition_variable.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h" 2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/threading/thread_local.h" 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Older style trace macros with explicit id and extra data 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Only these macros result in publishing data to ETW as currently implemented. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::debug::TraceLog::AddTraceEventEtw( \ 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_PHASE_BEGIN, \ 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name, reinterpret_cast<const void*>(id), extra) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACE_EVENT_END_ETW(name, id, extra) \ 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::debug::TraceLog::AddTraceEventEtw( \ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_PHASE_END, \ 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name, reinterpret_cast<const void*>(id), extra) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACE_EVENT_INSTANT_ETW(name, id, extra) \ 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::debug::TraceLog::AddTraceEventEtw( \ 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_PHASE_INSTANT, \ 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name, reinterpret_cast<const void*>(id), extra) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type> 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstruct DefaultSingletonTraits; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(COMPILER_GCC) 4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace BASE_HASH_NAMESPACE { 4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)template <> 5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)struct hash<base::MessageLoop*> { 5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::size_t operator()(base::MessageLoop* value) const { 5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return reinterpret_cast<std::size_t>(value); 5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}; 5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} // BASE_HASH_NAMESPACE 5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif 5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WaitableEvent; 6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class MessageLoop; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace debug { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// class must implement this interface. 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class ConvertableToTraceFormat : public RefCounted<ConvertableToTraceFormat> { 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Append the class info to the provided |out| string. The appended 70ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // data must be a valid JSON object. Strings must be properly quoted, and 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // escaped. There is no processing applied to the content after it is 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // appended. 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void AppendAsTraceFormat(std::string* out) const = 0; 744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) protected: 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual ~ConvertableToTraceFormat() {} 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private: 794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) friend class RefCounted<ConvertableToTraceFormat>; 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)struct TraceEventHandle { 838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceEventHandle() 848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : chunk_seq(0), 858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) chunk_index(0), 868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) event_index(0) { 878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceEventHandle(uint32 a_chunk_seq, 908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) size_t a_chunk_index, 918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) size_t a_event_index) 928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : chunk_seq(a_chunk_seq), 938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) chunk_index(static_cast<uint16>(a_chunk_index)), 948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) event_index(static_cast<uint16>(a_event_index)) { 958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(chunk_seq); 968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(a_chunk_index < (1u << 16)); 978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(a_event_index < (1u << 16)); 988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bool IsNull() const { return chunk_seq == 0; } 1018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) uint32 chunk_seq; 1038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) uint16 chunk_index; 1048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) uint16 event_index; 1058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}; 1068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTraceMaxNumArgs = 2; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT TraceEvent { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union TraceValue { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool as_bool; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long as_uint; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long long as_int; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double as_double; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* as_pointer; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* as_string; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceEvent(); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~TraceEvent(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // We don't need to copy TraceEvent except when TraceEventBuffer is cloned. 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Use explicit copy method to avoid accidentally misuse of copy. 1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void CopyFrom(const TraceEvent& other); 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void Initialize( 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int thread_id, 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TimeTicks timestamp, 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TimeTicks thread_timestamp, 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) char phase, 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const unsigned char* category_group_enabled, 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const char* name, 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) unsigned long long id, 1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int num_args, 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const char** arg_names, 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const unsigned char* arg_types, 1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const unsigned long long* arg_values, 1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const scoped_refptr<ConvertableToTraceFormat>* convertable_values, 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) unsigned char flags); 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void Reset(); 1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) void UpdateDuration() { 1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(duration_.ToInternalValue() == -1); 1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) duration_ = TimeTicks::NowFromSystemTraceTime() - timestamp_; 1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Serialize event data to JSON 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AppendEventsAsJSON(const std::vector<TraceEvent>& events, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t start, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t count, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* out); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AppendAsJSON(std::string* out) const; 1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void AppendPrettyPrinted(std::ostringstream* out) const; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AppendValueAsJSON(unsigned char type, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceValue value, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* out); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks timestamp() const { return timestamp_; } 1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) TimeTicks thread_timestamp() const { return thread_timestamp_; } 16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) char phase() const { return phase_; } 16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int thread_id() const { return thread_id_; } 1658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TimeDelta duration() const { return duration_; } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Exposed for unittesting: 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::RefCountedString* parameter_copy_storage() const { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return parameter_copy_storage_.get(); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled() const { 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return category_group_enabled_; 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* name() const { return name_; } 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_ANDROID) 1808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) void SendToATrace(); 1818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif 1828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: these are ordered by size (largest first) for optimal packing. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks timestamp_; 1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) TimeTicks thread_timestamp_; 1878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TimeDelta duration_; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // id_ can be used to store phase-specific data. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long id_; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceValue arg_values_[kTraceMaxNumArgs]; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* arg_names_[kTraceMaxNumArgs]; 1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<ConvertableToTraceFormat> convertable_values_[kTraceMaxNumArgs]; 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled_; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* name_; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::RefCountedString> parameter_copy_storage_; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int thread_id_; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char phase_; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char flags_; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char arg_types_[kTraceMaxNumArgs]; 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TraceEvent); 2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// TraceBufferChunk is the basic unit of TraceBuffer. 2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class BASE_EXPORT TraceBufferChunk { 2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceBufferChunk(uint32 seq) 2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : next_free_(0), 2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) seq_(seq) { 2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void Reset(uint32 new_seq); 2138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceEvent* AddTraceEvent(size_t* event_index); 2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool IsFull() const { return next_free_ == kTraceBufferChunkSize; } 2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32 seq() const { return seq_; } 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t capacity() const { return kTraceBufferChunkSize; } 2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t size() const { return next_free_; } 2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceEvent* GetEventAt(size_t index) { 2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(index < size()); 2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return &chunk_[index]; 2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const TraceEvent* GetEventAt(size_t index) const { 2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(index < size()); 2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return &chunk_[index]; 2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<TraceBufferChunk> Clone() const; 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static const size_t kTraceBufferChunkSize = 64; 2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private: 2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t next_free_; 2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceEvent chunk_[kTraceBufferChunkSize]; 2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32 seq_; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TraceBuffer holds the events as they are collected. 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BASE_EXPORT TraceBuffer { 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~TraceBuffer() {} 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual scoped_ptr<TraceBufferChunk> GetChunk(size_t *index) = 0; 2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void ReturnChunk(size_t index, 2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<TraceBufferChunk> chunk) = 0; 2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool IsFull() const = 0; 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual size_t Size() const = 0; 2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual size_t Capacity() const = 0; 2518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual TraceEvent* GetEventByHandle(TraceEventHandle handle) = 0; 2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // For iteration. Each TraceBuffer can only be iterated once. 2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual const TraceBufferChunk* NextChunk() = 0; 2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual scoped_ptr<TraceBuffer> CloneForIteration() const = 0; 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TraceResultBuffer collects and converts trace fragments returned by TraceLog 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to JSON output. 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT TraceResultBuffer { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef base::Callback<void(const std::string&)> OutputCallback; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If you don't need to stream JSON chunks out efficiently, and just want to 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // get a complete JSON string after calling Finish, use this struct to collect 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // JSON trace output. 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct BASE_EXPORT SimpleOutput { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OutputCallback GetCallback(); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Append(const std::string& json_string); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do what you want with the json_output_ string after calling 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TraceResultBuffer::Finish. 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string json_output; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceResultBuffer(); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~TraceResultBuffer(); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set callback. The callback will be called during Start with the initial 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // JSON output and during AddFragment and Finish with following JSON output 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // chunks. The callback target must live past the last calls to 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TraceResultBuffer::Start/AddFragment/Finish. 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetOutputCallback(const OutputCallback& json_chunk_callback); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start JSON output. This resets all internal state, so you can reuse 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the TraceResultBuffer by calling Start. 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Start(); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Call AddFragment 0 or more times to add trace fragments from TraceLog. 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddFragment(const std::string& trace_fragment); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When all fragments have been added, call Finish to complete the JSON 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // formatted output. 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Finish(); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OutputCallback output_callback_; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool append_comma_; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class BASE_EXPORT CategoryFilter { 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The default category filter, used when none is provided. 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Allows all categories through, except if they end in the suffix 'Debug' or 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 'Test'. 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static const char* kDefaultCategoryFilterString; 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |filter_string| is a comma-delimited list of category wildcards. 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // A category can have an optional '-' prefix to make it an excluded category. 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // All the same rules apply above, so for example, having both included and 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // excluded categories in the same list would not be supported. 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Example: CategoryFilter"test_MyTest*"); 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Example: CategoryFilter("test_MyTest*,test_OtherStuff"); 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Example: CategoryFilter("-excluded_category1,-excluded_category2"); 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Example: CategoryFilter("-*,webkit"); would disable everything but webkit. 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Example: CategoryFilter("-webkit"); would enable everything but webkit. 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) explicit CategoryFilter(const std::string& filter_string); 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CategoryFilter(const CategoryFilter& cf); 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ~CategoryFilter(); 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CategoryFilter& operator=(const CategoryFilter& rhs); 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Writes the string representation of the CategoryFilter. This is a comma 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // separated string, similar in nature to the one used to determine 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // enabled/disabled category patterns, except here there is an arbitrary 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // order, included categories go first, then excluded categories. Excluded 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // categories are distinguished from included categories by the prefix '-'. 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string ToString() const; 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Determines whether category group would be enabled or 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // disabled by this category filter. 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool IsCategoryGroupEnabled(const char* category_group) const; 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Merges nested_filter with the current CategoryFilter 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Merge(const CategoryFilter& nested_filter); 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Clears both included/excluded pattern lists. This would be equivalent to 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // creating a CategoryFilter with an empty string, through the constructor. 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // i.e: CategoryFilter(""). 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // When using an empty filter, all categories are considered included as we 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // are not excluding anything. 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Clear(); 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 349b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) private: 350b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, CategoryFilter); 351b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static bool IsEmptyOrContainsLeadingOrTrailingWhitespace( 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& str); 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 355b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) typedef std::vector<std::string> StringList; 356b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Initialize(const std::string& filter_string); 358b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) void WriteString(const StringList& values, 359b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) std::string* out, 360b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) bool included) const; 361b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) bool HasIncludedPatterns() const; 362b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 363b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) bool DoesCategoryGroupContainCategory(const char* category_group, 364b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const char* category) const; 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 366b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) StringList included_; 367b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) StringList disabled_; 368b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) StringList excluded_; 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TraceSamplingThread; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT TraceLog { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notification is a mask of one or more of the following events. 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum Notification { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The trace buffer does not flush dynamically, so when it fills up, 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subsequent trace events will be dropped. This callback is generated when 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the trace buffer is full. The callback must be thread safe. 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_BUFFER_FULL = 1 << 0, 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A subscribed trace-event occurred. 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EVENT_WATCH_NOTIFICATION = 1 << 1 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Options determines how the trace buffer stores data. 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enum Options { 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Record until the trace buffer is full. 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RECORD_UNTIL_FULL = 1 << 0, 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Record until the user ends the trace. The trace buffer is a fixed size 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // and we use it as a ring buffer during recording. 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RECORD_CONTINUOUSLY = 1 << 1, 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Enable the sampling profiler in the recording mode. 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ENABLE_SAMPLING = 1 << 2, 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Enable the sampling profiler in the monitoring mode. 3984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MONITOR_SAMPLING = 1 << 3, 3994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 400ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Echo to console. Events are discarded. 4014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ECHO_TO_CONSOLE = 1 << 4, 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static TraceLog* GetInstance(); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Convert the given string to trace options. Defaults to RECORD_UNTIL_FULL if 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the string does not provide valid options. 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static Options TraceOptionsFromString(const std::string& str); 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Get set of known category groups. This can change as new code paths are 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // reached. The known category groups are inserted into |category_groups|. 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void GetKnownCategoryGroups(std::vector<std::string>* category_groups); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Retrieves the current CategoryFilter. 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const CategoryFilter& GetCurrentCategoryFilter(); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Options trace_options() const { 41858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return static_cast<Options>(subtle::NoBarrier_Load(&trace_options_)); 41958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Enables tracing. See CategoryFilter comments for details 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // on how to control what categories will be traced. 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void SetEnabled(const CategoryFilter& category_filter, Options options); 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Disables tracing for all categories. 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetDisabled(); 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool IsEnabled() { return !!enable_count_; } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The number of times we have begun recording traces. If tracing is off, 430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // returns -1. If tracing is on, then it returns the number of times we have 431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // recorded a trace. By watching for this number to increment, you can 432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // passively discover when a new trace has begun. This is then used to 433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // implement the TRACE_EVENT_IS_NEW_TRACE() primitive. 434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int GetNumTracesRecorded(); 435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void StartATrace(); 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void StopATrace(); 4394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void AddClockSyncMetadataEvent(); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enabled state listeners give a callback when tracing is enabled or 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // disabled. This can be used to tie into other library's tracing systems 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on-demand. 4457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) class EnabledStateObserver { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Called just after the tracing system becomes enabled, outside of the 4487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // |lock_|. TraceLog::IsEnabled() is true at this point. 4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual void OnTraceLogEnabled() = 0; 4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Called just after the tracing system disables, outside of the |lock_|. 4527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // TraceLog::IsEnabled() is false at this point. 4537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual void OnTraceLogDisabled() = 0; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 4557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) void AddEnabledStateObserver(EnabledStateObserver* listener); 4567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) void RemoveEnabledStateObserver(EnabledStateObserver* listener); 457bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch bool HasEnabledStateObserver(EnabledStateObserver* listener) const; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float GetBufferPercentFull() const; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the thread-safe notification callback. The callback can occur at any 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // time and from any thread. WARNING: It is possible for the previously set 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callback to be called during OR AFTER a call to SetNotificationCallback. 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Therefore, the target of the callback must either be a global function, 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ref-counted object or a LazyInstance with Leaky traits (or equivalent). 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef base::Callback<void(int)> NotificationCallback; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetNotificationCallback(const NotificationCallback& cb); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 469ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Not using base::Callback because of its limited by 7 parameters. 470ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Also, using primitive type allows directly passing callback from WebCore. 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // WARNING: It is possible for the previously set callback to be called 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // after a call to SetEventCallback() that replaces or clears the callback. 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This callback may be invoked on any thread. 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef void (*EventCallback)(char phase, 475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled, 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* name, 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned long long id, 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_args, 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* const arg_names[], 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned char arg_types[], 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned long long arg_values[], 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned char flags); 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetEventCallback(EventCallback cb); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flush all collected events to the given output callback. The callback will 48658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // be called one or more times either synchronously or asynchronously from 48758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // the current thread with IPC-bite-size chunks. The string format is 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // undefined. Use TraceResultBuffer to convert one or more trace strings to 48958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // JSON. The callback can be null if the caller doesn't want any data. 49058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Due to the implementation of thread-local buffers, flush can't be 49158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // done when tracing is enabled. If called when tracing is enabled, the 49258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // callback will be called directly with (empty_string, false) to indicate 49358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // the end of this unsuccessful flush. 49458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&, 49558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool has_more_events)> OutputCallback; 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Flush(const OutputCallback& cb); 4974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void FlushButLeaveBufferIntact(const OutputCallback& flush_output_callback); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by TRACE_EVENT* macros, don't call this directly. 500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The name parameter is a category group for example: 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent") 502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static const unsigned char* GetCategoryGroupEnabled(const char* name); 503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static const char* GetCategoryGroupName( 504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by TRACE_EVENT* macros, don't call this directly. 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above. 5098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceEventHandle AddTraceEvent( 5104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) char phase, 5114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const unsigned char* category_group_enabled, 5124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const char* name, 5134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) unsigned long long id, 5144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int num_args, 5154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const char** arg_names, 5164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const unsigned char* arg_types, 5174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const unsigned long long* arg_values, 5184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const scoped_refptr<ConvertableToTraceFormat>* convertable_values, 5194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) unsigned char flags); 5208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceEventHandle AddTraceEventWithThreadIdAndTimestamp( 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char phase, 522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled, 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* name, 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned long long id, 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int thread_id, 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const TimeTicks& timestamp, 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_args, 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char** arg_names, 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned char* arg_types, 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned long long* arg_values, 5314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const scoped_refptr<ConvertableToTraceFormat>* convertable_values, 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned char flags); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AddTraceEventEtw(char phase, 534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* category_group, 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* id, 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* extra); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AddTraceEventEtw(char phase, 538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* category_group, 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* id, 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extra); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) void UpdateTraceEventDuration(TraceEventHandle handle); 5438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For every matching event, a notification will be fired. NOTE: the 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notification will fire for each matching event that has already occurred 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // since tracing was started (including before tracing if the process was 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // started with tracing turned on). 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetWatchEvent(const std::string& category_name, 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel the watch event. If tracing is enabled, this may race with the 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // watch event notification firing. 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CancelWatchEvent(); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int process_id() const { return process_id_; } 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Exposed for unittesting: 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void InstallWaitableEventForSamplingTesting(WaitableEvent* waitable_event); 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allows deleting our singleton instance. 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void DeleteForTesting(); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allow tests to inspect TraceEvents. 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t GetEventsSize() const { return logged_events_->Size(); } 5658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceEvent* GetEventByHandle(TraceEventHandle handle); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetProcessID(int process_id); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Process sort indices, if set, override the order of a process will appear 5707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // relative to other processes in the trace viewer. Processes are sorted first 5717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // on their sort index, ascending, then by their name, and then tid. 5727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void SetProcessSortIndex(int sort_index); 5737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Sets the name of the process. 5757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void SetProcessName(const std::string& process_name); 5767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Processes can have labels in addition to their names. Use labels, for 5787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // instance, to list out the web page titles that a process is handling. 5797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void UpdateProcessLabel(int label_id, const std::string& current_label); 5807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void RemoveProcessLabel(int label_id); 5817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Thread sort indices, if set, override the order of a thread will appear 5837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // within its process in the trace viewer. Threads are sorted first on their 5847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // sort index, ascending, then by their name, and then tid. 5857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void SetThreadSortIndex(PlatformThreadId , int sort_index); 5867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Allow setting an offset between the current TimeTicks time and the time 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that should be reported. 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetTimeOffset(TimeDelta offset); 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) size_t GetObserverCountForTest() const; 5927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Call this method if the current thread may block the message loop to 5948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // prevent the thread from using the thread-local buffer because the thread 5958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // may not handle the flush request in time causing lost of unflushed events. 5968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) void SetCurrentThreadBlocksMessageLoop(); 5978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 5994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, 6004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceBufferRingBufferGetReturnChunk); 6014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, 6024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceBufferRingBufferHalfIteration); 6034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, 6044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceBufferRingBufferFullIteration); 6054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This allows constructor and destructor to be private and usable only 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by the Singleton class. 6087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch friend struct DefaultSingletonTraits<TraceLog>; 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 610bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Enable/disable each category group based on the current enable_count_ 611bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // and category_filter_. Disable the category group if enabled_count_ is 0, or 612bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // if the category group contains a category that matches an included category 613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // pattern, that category group will be enabled. 614bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // On Android, ATRACE_ENABLED flag will be applied if atrace is started. 615bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch void UpdateCategoryGroupEnabledFlags(); 616bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch void UpdateCategoryGroupEnabledFlag(int category_index); 617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper class for managing notification_thread_count_ and running 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notification callbacks. This is very similar to a reader-writer lock, but 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shares the lock with TraceLog and manages the notification flags. 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class NotificationHelper { 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline explicit NotificationHelper(TraceLog* trace_log); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline ~NotificationHelper(); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called only while TraceLog::lock_ is held. This ORs the given 627ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // notification with any existing notifications. 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void AddNotificationWhileLocked(int notification); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called only while TraceLog::lock_ is NOT held. If there are any pending 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notifications from previous calls to AddNotificationWhileLocked, this 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will call the NotificationCallback. 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void SendNotificationIfAny(); 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceLog* trace_log_; 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotificationCallback callback_copy_; 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int notification_; 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) class ThreadLocalEventBuffer; 6428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) class OptionalAutoLock; 64358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceLog(); 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~TraceLog(); 646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* GetCategoryGroupEnabledInternal(const char* name); 6474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void AddMetadataEventsWhileLocked(); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceBuffer* trace_buffer() const { return logged_events_.get(); } 6504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceBuffer* CreateTraceBuffer(); 6514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void OutputEventToConsoleWhileLocked(TraceEvent* trace_event); 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceEvent* AddEventToThreadSharedChunkWhileLocked( 6558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) NotificationHelper* notifier, TraceEventHandle* handle); 65658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void CheckIfBufferIsFullWhileLocked(NotificationHelper* notifier); 6574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceEvent* GetEventByHandleInternal(TraceEventHandle handle, 6598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OptionalAutoLock* lock); 6608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // |generation| is used in the following callbacks to check if the callback 6624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // is called for the flush of the current |logged_events_|. 6634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void FlushCurrentThread(int generation); 6644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void ConvertTraceEventsToTraceFormat(scoped_ptr<TraceBuffer> logged_events, 6654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const TraceLog::OutputCallback& flush_output_callback); 6664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void FinishFlush(int generation); 6674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void OnFlushTimeout(int generation); 6684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int generation() const { 6704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return static_cast<int>(subtle::NoBarrier_Load(&generation_)); 6714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool CheckGeneration(int generation) const { 6734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return generation == this->generation(); 6744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int NextGeneration() { 6764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return static_cast<int>(subtle::NoBarrier_AtomicIncrement(&generation_, 1)); 6774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 67858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This lock protects TraceLog member accesses from arbitrary threads. 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Lock lock_; 68158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int locked_line_; 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int enable_count_; 683868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int num_traces_recorded_; 68458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) subtle::AtomicWord /* bool */ buffer_is_full_; 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotificationCallback notification_callback_; 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<TraceBuffer> logged_events_; 68758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) subtle::AtomicWord /* EventCallback */ event_callback_; 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool dispatching_to_observer_list_; 6897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::vector<EnabledStateObserver*> enabled_state_observer_list_; 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string process_name_; 6927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::hash_map<int, std::string> process_labels_; 6937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int process_sort_index_; 6947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::hash_map<int, int> thread_sort_indices_; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::hash_map<int, std::string> thread_names_; 69658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 69758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The following two maps are used only when ECHO_TO_CONSOLE. 698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_; 699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::hash_map<std::string, int> thread_colors_; 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // XORed with TraceID to make it unlikely to collide with other processes. 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long process_id_hash_; 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int process_id_; 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TimeDelta time_offset_; 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allow tests to wake up when certain events occur. 70958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) subtle::AtomicWord /* const unsigned char* */ watch_category_; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string watch_event_name_; 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 71258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) subtle::AtomicWord /* Options */ trace_options_; 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sampling thread handles. 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<TraceSamplingThread> sampling_thread_; 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PlatformThreadHandle sampling_thread_handle_; 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CategoryFilter category_filter_; 719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 72058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ThreadLocalPointer<ThreadLocalEventBuffer> thread_local_event_buffer_; 7218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ThreadLocalBoolean thread_blocks_message_loop_; 72258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 72358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Contains the message loops of threads that have had at least one event 72458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // added into the local event buffer. Not using MessageLoopProxy because we 72558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // need to know the life time of the message loops. 7264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) hash_set<MessageLoop*> thread_message_loops_; 7274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // For events which can't be added into the thread local buffer, e.g. events 7294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // from threads without a message loop. 7304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<TraceBufferChunk> thread_shared_chunk_; 7314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t thread_shared_chunk_index_; 73258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 73358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Set when asynchronous Flush is in progress. 73458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) OutputCallback flush_output_callback_; 73558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<MessageLoopProxy> flush_message_loop_proxy_; 7364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) subtle::AtomicWord generation_; 73758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TraceLog); 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace debug 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ 745