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