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) uint32 chunk_seq; 848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) uint16 chunk_index; 858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) uint16 event_index; 868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}; 878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTraceMaxNumArgs = 2; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT TraceEvent { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union TraceValue { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool as_bool; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long as_uint; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long long as_int; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double as_double; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* as_pointer; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* as_string; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceEvent(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~TraceEvent(); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // We don't need to copy TraceEvent except when TraceEventBuffer is cloned. 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Use explicit copy method to avoid accidentally misuse of copy. 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void CopyFrom(const TraceEvent& other); 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void Initialize( 1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int thread_id, 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TimeTicks timestamp, 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TimeTicks thread_timestamp, 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) char phase, 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const unsigned char* category_group_enabled, 1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const char* name, 1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) unsigned long long id, 1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int num_args, 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const char** arg_names, 1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const unsigned char* arg_types, 1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const unsigned long long* arg_values, 1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const scoped_refptr<ConvertableToTraceFormat>* convertable_values, 1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) unsigned char flags); 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void Reset(); 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void UpdateDuration(const TimeTicks& now, const TimeTicks& thread_now); 1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Serialize event data to JSON 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AppendAsJSON(std::string* out) const; 1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void AppendPrettyPrinted(std::ostringstream* out) const; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AppendValueAsJSON(unsigned char type, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceValue value, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* out); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks timestamp() const { return timestamp_; } 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) TimeTicks thread_timestamp() const { return thread_timestamp_; } 13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) char phase() const { return phase_; } 13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int thread_id() const { return thread_id_; } 1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TimeDelta duration() const { return duration_; } 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TimeDelta thread_duration() const { return thread_duration_; } 1411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) unsigned long long id() const { return id_; } 1421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) unsigned char flags() const { return flags_; } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Exposed for unittesting: 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::RefCountedString* parameter_copy_storage() const { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return parameter_copy_storage_.get(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled() const { 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return category_group_enabled_; 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* name() const { return name_; } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_ANDROID) 1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) void SendToATrace(); 1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif 1598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: these are ordered by size (largest first) for optimal packing. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks timestamp_; 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) TimeTicks thread_timestamp_; 1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TimeDelta duration_; 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TimeDelta thread_duration_; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // id_ can be used to store phase-specific data. 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long id_; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceValue arg_values_[kTraceMaxNumArgs]; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* arg_names_[kTraceMaxNumArgs]; 1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<ConvertableToTraceFormat> convertable_values_[kTraceMaxNumArgs]; 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled_; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* name_; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::RefCountedString> parameter_copy_storage_; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int thread_id_; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char phase_; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char flags_; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char arg_types_[kTraceMaxNumArgs]; 1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TraceEvent); 1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// TraceBufferChunk is the basic unit of TraceBuffer. 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class BASE_EXPORT TraceBufferChunk { 1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceBufferChunk(uint32 seq) 1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : next_free_(0), 1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) seq_(seq) { 1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void Reset(uint32 new_seq); 1918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceEvent* AddTraceEvent(size_t* event_index); 1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool IsFull() const { return next_free_ == kTraceBufferChunkSize; } 1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32 seq() const { return seq_; } 1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t capacity() const { return kTraceBufferChunkSize; } 1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t size() const { return next_free_; } 1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceEvent* GetEventAt(size_t index) { 1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(index < size()); 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return &chunk_[index]; 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const TraceEvent* GetEventAt(size_t index) const { 2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(index < size()); 2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return &chunk_[index]; 2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<TraceBufferChunk> Clone() const; 2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static const size_t kTraceBufferChunkSize = 64; 2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private: 2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t next_free_; 2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceEvent chunk_[kTraceBufferChunkSize]; 2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32 seq_; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TraceBuffer holds the events as they are collected. 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BASE_EXPORT TraceBuffer { 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~TraceBuffer() {} 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual scoped_ptr<TraceBufferChunk> GetChunk(size_t *index) = 0; 2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void ReturnChunk(size_t index, 2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<TraceBufferChunk> chunk) = 0; 2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool IsFull() const = 0; 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual size_t Size() const = 0; 2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual size_t Capacity() const = 0; 2298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual TraceEvent* GetEventByHandle(TraceEventHandle handle) = 0; 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // For iteration. Each TraceBuffer can only be iterated once. 2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual const TraceBufferChunk* NextChunk() = 0; 2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual scoped_ptr<TraceBuffer> CloneForIteration() const = 0; 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TraceResultBuffer collects and converts trace fragments returned by TraceLog 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to JSON output. 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT TraceResultBuffer { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef base::Callback<void(const std::string&)> OutputCallback; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If you don't need to stream JSON chunks out efficiently, and just want to 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // get a complete JSON string after calling Finish, use this struct to collect 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // JSON trace output. 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct BASE_EXPORT SimpleOutput { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OutputCallback GetCallback(); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Append(const std::string& json_string); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do what you want with the json_output_ string after calling 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TraceResultBuffer::Finish. 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string json_output; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceResultBuffer(); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~TraceResultBuffer(); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set callback. The callback will be called during Start with the initial 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // JSON output and during AddFragment and Finish with following JSON output 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // chunks. The callback target must live past the last calls to 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TraceResultBuffer::Start/AddFragment/Finish. 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetOutputCallback(const OutputCallback& json_chunk_callback); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start JSON output. This resets all internal state, so you can reuse 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the TraceResultBuffer by calling Start. 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Start(); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Call AddFragment 0 or more times to add trace fragments from TraceLog. 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddFragment(const std::string& trace_fragment); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When all fragments have been added, call Finish to complete the JSON 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // formatted output. 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Finish(); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OutputCallback output_callback_; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool append_comma_; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class BASE_EXPORT CategoryFilter { 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef std::vector<std::string> StringList; 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The default category filter, used when none is provided. 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Allows all categories through, except if they end in the suffix 'Debug' or 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 'Test'. 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static const char* kDefaultCategoryFilterString; 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |filter_string| is a comma-delimited list of category wildcards. 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // A category can have an optional '-' prefix to make it an excluded category. 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // All the same rules apply above, so for example, having both included and 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // excluded categories in the same list would not be supported. 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Example: CategoryFilter"test_MyTest*"); 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Example: CategoryFilter("test_MyTest*,test_OtherStuff"); 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Example: CategoryFilter("-excluded_category1,-excluded_category2"); 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Example: CategoryFilter("-*,webkit"); would disable everything but webkit. 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Example: CategoryFilter("-webkit"); would enable everything but webkit. 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Category filters can also be used to configure synthetic delays. 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 3025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Example: CategoryFilter("DELAY(gpu.PresentingFrame;16)"); would make swap 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // buffers always take at least 16 ms. 3045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Example: CategoryFilter("DELAY(gpu.PresentingFrame;16;oneshot)"); would 3055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // make swap buffers take at least 16 ms the first time it is 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // called. 3075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Example: CategoryFilter("DELAY(gpu.PresentingFrame;16;alternating)"); 3085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // would make swap buffers take at least 16 ms every other time it 3095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // is called. 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) explicit CategoryFilter(const std::string& filter_string); 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CategoryFilter(const CategoryFilter& cf); 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ~CategoryFilter(); 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CategoryFilter& operator=(const CategoryFilter& rhs); 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Writes the string representation of the CategoryFilter. This is a comma 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // separated string, similar in nature to the one used to determine 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // enabled/disabled category patterns, except here there is an arbitrary 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // order, included categories go first, then excluded categories. Excluded 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // categories are distinguished from included categories by the prefix '-'. 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string ToString() const; 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Determines whether category group would be enabled or 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // disabled by this category filter. 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool IsCategoryGroupEnabled(const char* category_group) const; 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Return a list of the synthetic delays specified in this category filter. 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const StringList& GetSyntheticDelayValues() const; 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Merges nested_filter with the current CategoryFilter 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Merge(const CategoryFilter& nested_filter); 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Clears both included/excluded pattern lists. This would be equivalent to 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // creating a CategoryFilter with an empty string, through the constructor. 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // i.e: CategoryFilter(""). 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // When using an empty filter, all categories are considered included as we 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // are not excluding anything. 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Clear(); 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 343b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) private: 344b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, CategoryFilter); 345b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static bool IsEmptyOrContainsLeadingOrTrailingWhitespace( 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& str); 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Initialize(const std::string& filter_string); 350b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) void WriteString(const StringList& values, 351b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) std::string* out, 352b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) bool included) const; 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void WriteString(const StringList& delays, std::string* out) const; 354b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) bool HasIncludedPatterns() const; 355b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 356b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) bool DoesCategoryGroupContainCategory(const char* category_group, 357b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const char* category) const; 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 359b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) StringList included_; 360b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) StringList disabled_; 361b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) StringList excluded_; 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StringList delays_; 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TraceSamplingThread; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT TraceLog { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) enum Mode { 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISABLED = 0, 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RECORDING_MODE, 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MONITORING_MODE, 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Options determines how the trace buffer stores data. 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enum Options { 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Record until the trace buffer is full. 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RECORD_UNTIL_FULL = 1 << 0, 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Record until the user ends the trace. The trace buffer is a fixed size 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // and we use it as a ring buffer during recording. 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RECORD_CONTINUOUSLY = 1 << 1, 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Enable the sampling profiler in the recording mode. 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ENABLE_SAMPLING = 1 << 2, 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 387ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Echo to console. Events are discarded. 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ECHO_TO_CONSOLE = 1 << 3, 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The pointer returned from GetCategoryGroupEnabledInternal() points to a 392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // value with zero or more of the following bits. Used in this class only. 393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The TRACE_EVENT macros should only use the value as a bool. 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // These values must be in sync with macro values in TraceEvent.h in Blink. 395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) enum CategoryGroupEnabledFlags { 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Category group enabled for the recording mode. 397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ENABLED_FOR_RECORDING = 1 << 0, 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Category group enabled for the monitoring mode. 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ENABLED_FOR_MONITORING = 1 << 1, 400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Category group enabled by SetEventCallbackEnabled(). 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ENABLED_FOR_EVENT_CALLBACK = 1 << 2, 402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) }; 403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static TraceLog* GetInstance(); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Get set of known category groups. This can change as new code paths are 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // reached. The known category groups are inserted into |category_groups|. 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void GetKnownCategoryGroups(std::vector<std::string>* category_groups); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Retrieves a copy (for thread-safety) of the current CategoryFilter. 411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CategoryFilter GetCurrentCategoryFilter(); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Options trace_options() const { 41458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return static_cast<Options>(subtle::NoBarrier_Load(&trace_options_)); 41558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Enables normal tracing (recording trace events in the trace buffer). 418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // See CategoryFilter comments for details on how to control what categories 419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // will be traced. If tracing has already been enabled, |category_filter| will 420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // be merged into the current category filter. 4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void SetEnabled(const CategoryFilter& category_filter, 4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Mode mode, Options options); 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Disables normal tracing for all categories. 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetDisabled(); 426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool IsEnabled() { return mode_ != DISABLED; } 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 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (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; 460a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool BufferIsFull() const; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 462ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Not using base::Callback because of its limited by 7 parameters. 463ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Also, using primitive type allows directly passing callback from WebCore. 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // WARNING: It is possible for the previously set callback to be called 465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // after a call to SetEventCallbackEnabled() that replaces or a call to 466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // SetEventCallbackDisabled() that disables the callback. 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This callback may be invoked on any thread. 468f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // For TRACE_EVENT_PHASE_COMPLETE events, the client will still receive pairs 469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // of TRACE_EVENT_PHASE_BEGIN and TRACE_EVENT_PHASE_END events to keep the 470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // interface simple. 4711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) typedef void (*EventCallback)(TimeTicks timestamp, 4721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) char phase, 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled, 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* name, 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned long long id, 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_args, 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* const arg_names[], 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned char arg_types[], 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned long long arg_values[], 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned char flags); 481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Enable tracing for EventCallback. 483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void SetEventCallbackEnabled(const CategoryFilter& category_filter, 484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EventCallback cb); 485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void SetEventCallbackDisabled(); 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flush all collected events to the given output callback. The callback will 48858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // be called one or more times either synchronously or asynchronously from 48958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // the current thread with IPC-bite-size chunks. The string format is 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // undefined. Use TraceResultBuffer to convert one or more trace strings to 49158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // JSON. The callback can be null if the caller doesn't want any data. 49258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Due to the implementation of thread-local buffers, flush can't be 49358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // done when tracing is enabled. If called when tracing is enabled, the 49458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // callback will be called directly with (empty_string, false) to indicate 49558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // the end of this unsuccessful flush. 49658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&, 49758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool has_more_events)> OutputCallback; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Flush(const OutputCallback& cb); 4994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void FlushButLeaveBufferIntact(const OutputCallback& flush_output_callback); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by TRACE_EVENT* macros, don't call this directly. 502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The name parameter is a category group for example: 503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent") 504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static const unsigned char* GetCategoryGroupEnabled(const char* name); 505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static const char* GetCategoryGroupName( 506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by TRACE_EVENT* macros, don't call this directly. 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above. 5118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceEventHandle AddTraceEvent( 5124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) char phase, 5134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const unsigned char* category_group_enabled, 5144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const char* name, 5154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) unsigned long long id, 5164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int num_args, 5174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const char** arg_names, 5184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const unsigned char* arg_types, 5194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const unsigned long long* arg_values, 5204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const scoped_refptr<ConvertableToTraceFormat>* convertable_values, 5214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) unsigned char flags); 5228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceEventHandle AddTraceEventWithThreadIdAndTimestamp( 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char phase, 524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled, 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* name, 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned long long id, 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int thread_id, 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const TimeTicks& timestamp, 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_args, 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char** arg_names, 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned char* arg_types, 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned long long* arg_values, 5334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const scoped_refptr<ConvertableToTraceFormat>* convertable_values, 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned char flags); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AddTraceEventEtw(char phase, 536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* category_group, 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* id, 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* extra); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AddTraceEventEtw(char phase, 540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* category_group, 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* id, 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extra); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void UpdateTraceEventDuration(const unsigned char* category_group_enabled, 545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char* name, 546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TraceEventHandle handle); 5478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 548a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // For every matching event, the callback will be called. 549a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typedef base::Callback<void()> WatchEventCallback; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetWatchEvent(const std::string& category_name, 551a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& event_name, 552a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const WatchEventCallback& callback); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel the watch event. If tracing is enabled, this may race with the 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // watch event notification firing. 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CancelWatchEvent(); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int process_id() const { return process_id_; } 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Exposed for unittesting: 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void WaitSamplingEventForTesting(); 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allows deleting our singleton instance. 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void DeleteForTesting(); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allow tests to inspect TraceEvents. 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t GetEventsSize() const { return logged_events_->Size(); } 5688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceEvent* GetEventByHandle(TraceEventHandle handle); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetProcessID(int process_id); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Process sort indices, if set, override the order of a process will appear 5737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // relative to other processes in the trace viewer. Processes are sorted first 5747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // on their sort index, ascending, then by their name, and then tid. 5757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void SetProcessSortIndex(int sort_index); 5767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Sets the name of the process. 5787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void SetProcessName(const std::string& process_name); 5797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Processes can have labels in addition to their names. Use labels, for 5817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // instance, to list out the web page titles that a process is handling. 5827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void UpdateProcessLabel(int label_id, const std::string& current_label); 5837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void RemoveProcessLabel(int label_id); 5847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Thread sort indices, if set, override the order of a thread will appear 5867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // within its process in the trace viewer. Threads are sorted first on their 5877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // sort index, ascending, then by their name, and then tid. 5887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void SetThreadSortIndex(PlatformThreadId , int sort_index); 5897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Allow setting an offset between the current TimeTicks time and the time 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that should be reported. 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetTimeOffset(TimeDelta offset); 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) size_t GetObserverCountForTest() const; 5957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Call this method if the current thread may block the message loop to 5978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // prevent the thread from using the thread-local buffer because the thread 5988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // may not handle the flush request in time causing lost of unflushed events. 5998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) void SetCurrentThreadBlocksMessageLoop(); 6008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 6024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, 6034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceBufferRingBufferGetReturnChunk); 6044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, 6054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceBufferRingBufferHalfIteration); 6064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, 6074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceBufferRingBufferFullIteration); 6084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This allows constructor and destructor to be private and usable only 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by the Singleton class. 6117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch friend struct DefaultSingletonTraits<TraceLog>; 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Enable/disable each category group based on the current mode_, 614f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // category_filter_, event_callback_ and event_callback_category_filter_. 6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Enable the category group in the enabled mode if category_filter_ matches 616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // the category group, or event_callback_ is not null and 617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // event_callback_category_filter_ matches the category group. 618bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch void UpdateCategoryGroupEnabledFlags(); 619bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch void UpdateCategoryGroupEnabledFlag(int category_index); 620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Configure synthetic delays based on the values set in the current 6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // category filter. 6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void UpdateSyntheticDelaysFromCategoryFilter(); 6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 62558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) class ThreadLocalEventBuffer; 6268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) class OptionalAutoLock; 62758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceLog(); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~TraceLog(); 630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* GetCategoryGroupEnabledInternal(const char* name); 6314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void AddMetadataEventsWhileLocked(); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceBuffer* trace_buffer() const { return logged_events_.get(); } 6344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceBuffer* CreateTraceBuffer(); 6354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 636a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string EventToConsoleMessage(unsigned char phase, 637a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const TimeTicks& timestamp, 638a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TraceEvent* trace_event); 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 640a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TraceEvent* AddEventToThreadSharedChunkWhileLocked(TraceEventHandle* handle, 641a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool check_buffer_is_full); 642a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void CheckIfBufferIsFullWhileLocked(); 643a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void SetDisabledWhileLocked(); 6444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceEvent* GetEventByHandleInternal(TraceEventHandle handle, 6468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OptionalAutoLock* lock); 6478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // |generation| is used in the following callbacks to check if the callback 6494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // is called for the flush of the current |logged_events_|. 6504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void FlushCurrentThread(int generation); 6514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void ConvertTraceEventsToTraceFormat(scoped_ptr<TraceBuffer> logged_events, 6524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const TraceLog::OutputCallback& flush_output_callback); 6534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void FinishFlush(int generation); 6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void OnFlushTimeout(int generation); 6554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int generation() const { 6574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return static_cast<int>(subtle::NoBarrier_Load(&generation_)); 6584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool CheckGeneration(int generation) const { 6604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return generation == this->generation(); 6614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void UseNextTraceBuffer(); 66358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 6640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) TimeTicks OffsetNow() const { 6650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return OffsetTimestamp(TimeTicks::NowFromSystemTraceTime()); 6660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 6670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) TimeTicks OffsetTimestamp(const TimeTicks& timestamp) const { 6680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return timestamp - time_offset_; 6690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 6700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 671a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // This lock protects TraceLog member accesses (except for members protected 672a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // by thread_info_lock_) from arbitrary threads. 673a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) mutable Lock lock_; 674a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // This lock protects accesses to thread_names_, thread_event_start_times_ 675a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // and thread_colors_. 676a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Lock thread_info_lock_; 67758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int locked_line_; 6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Mode mode_; 679868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int num_traces_recorded_; 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<TraceBuffer> logged_events_; 68158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) subtle::AtomicWord /* EventCallback */ event_callback_; 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool dispatching_to_observer_list_; 6837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::vector<EnabledStateObserver*> enabled_state_observer_list_; 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string process_name_; 6867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::hash_map<int, std::string> process_labels_; 6877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int process_sort_index_; 6887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::hash_map<int, int> thread_sort_indices_; 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::hash_map<int, std::string> thread_names_; 69058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 69158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The following two maps are used only when ECHO_TO_CONSOLE. 692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_; 693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::hash_map<std::string, int> thread_colors_; 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // XORed with TraceID to make it unlikely to collide with other processes. 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long process_id_hash_; 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int process_id_; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TimeDelta time_offset_; 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allow tests to wake up when certain events occur. 703a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) WatchEventCallback watch_event_callback_; 70458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) subtle::AtomicWord /* const unsigned char* */ watch_category_; 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string watch_event_name_; 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 70758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) subtle::AtomicWord /* Options */ trace_options_; 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sampling thread handles. 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<TraceSamplingThread> sampling_thread_; 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PlatformThreadHandle sampling_thread_handle_; 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CategoryFilter category_filter_; 714f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CategoryFilter event_callback_category_filter_; 715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 71658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ThreadLocalPointer<ThreadLocalEventBuffer> thread_local_event_buffer_; 7178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ThreadLocalBoolean thread_blocks_message_loop_; 718a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ThreadLocalBoolean thread_is_in_trace_event_; 71958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 72058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Contains the message loops of threads that have had at least one event 72158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // added into the local event buffer. Not using MessageLoopProxy because we 72258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // need to know the life time of the message loops. 7234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) hash_set<MessageLoop*> thread_message_loops_; 7244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // For events which can't be added into the thread local buffer, e.g. events 7264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // from threads without a message loop. 7274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<TraceBufferChunk> thread_shared_chunk_; 7284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t thread_shared_chunk_index_; 72958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 73058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Set when asynchronous Flush is in progress. 73158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) OutputCallback flush_output_callback_; 73258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<MessageLoopProxy> flush_message_loop_proxy_; 7334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) subtle::AtomicWord generation_; 73458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TraceLog); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace debug 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ 742