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"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/base_export.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h"
17b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/gtest_prod_util.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted_memory.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_vector.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/observer_list.h"
215e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/condition_variable.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h"
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/threading/thread_local.h"
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Older style trace macros with explicit id and extra data
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Only these macros result in publishing data to ETW as currently implemented.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACE_EVENT_BEGIN_ETW(name, id, extra) \
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::debug::TraceLog::AddTraceEventEtw( \
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TRACE_EVENT_PHASE_BEGIN, \
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name, reinterpret_cast<const void*>(id), extra)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACE_EVENT_END_ETW(name, id, extra) \
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::debug::TraceLog::AddTraceEventEtw( \
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TRACE_EVENT_PHASE_END, \
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name, reinterpret_cast<const void*>(id), extra)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACE_EVENT_INSTANT_ETW(name, id, extra) \
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::debug::TraceLog::AddTraceEventEtw( \
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TRACE_EVENT_PHASE_INSTANT, \
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name, reinterpret_cast<const void*>(id), extra)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type>
467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstruct DefaultSingletonTraits;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(COMPILER_GCC)
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace BASE_HASH_NAMESPACE {
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)template <>
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)struct hash<base::MessageLoop*> {
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::size_t operator()(base::MessageLoop* value) const {
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return reinterpret_cast<std::size_t>(value);
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // BASE_HASH_NAMESPACE
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WaitableEvent;
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class MessageLoop;
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace debug {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// class must implement this interface.
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class BASE_EXPORT ConvertableToTraceFormat
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : public RefCounted<ConvertableToTraceFormat> {
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Append the class info to the provided |out| string. The appended
72ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // data must be a valid JSON object. Strings must be properly quoted, and
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // escaped. There is no processing applied to the content after it is
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // appended.
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void AppendAsTraceFormat(std::string* out) const = 0;
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string ToString() const {
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    std::string result;
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    AppendAsTraceFormat(&result);
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return result;
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) protected:
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual ~ConvertableToTraceFormat() {}
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  friend class RefCounted<ConvertableToTraceFormat>;
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)struct TraceEventHandle {
918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  uint32 chunk_seq;
928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  uint16 chunk_index;
938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  uint16 event_index;
948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)};
958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTraceMaxNumArgs = 2;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT TraceEvent {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  union TraceValue {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool as_bool;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long long as_uint;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    long long as_int;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double as_double;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const void* as_pointer;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* as_string;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceEvent();
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~TraceEvent();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // We don't need to copy TraceEvent except when TraceEventBuffer is cloned.
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Use explicit copy method to avoid accidentally misuse of copy.
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void CopyFrom(const TraceEvent& other);
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void Initialize(
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      int thread_id,
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      TimeTicks timestamp,
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      TimeTicks thread_timestamp,
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      char phase,
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const unsigned char* category_group_enabled,
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const char* name,
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      unsigned long long id,
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      int num_args,
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const char** arg_names,
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const unsigned char* arg_types,
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const unsigned long long* arg_values,
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      unsigned char flags);
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void Reset();
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void UpdateDuration(const TimeTicks& now, const TimeTicks& thread_now);
1348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize event data to JSON
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AppendAsJSON(std::string* out) const;
1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void AppendPrettyPrinted(std::ostringstream* out) const;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void AppendValueAsJSON(unsigned char type,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                TraceValue value,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                std::string* out);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks timestamp() const { return timestamp_; }
1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TimeTicks thread_timestamp() const { return thread_timestamp_; }
14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  char phase() const { return phase_; }
14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int thread_id() const { return thread_id_; }
1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TimeDelta duration() const { return duration_; }
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TimeDelta thread_duration() const { return thread_duration_; }
1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  unsigned long long id() const { return id_; }
1501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  unsigned char flags() const { return flags_; }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Exposed for unittesting:
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::RefCountedString* parameter_copy_storage() const {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return parameter_copy_storage_.get();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const unsigned char* category_group_enabled() const {
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return category_group_enabled_;
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* name() const { return name_; }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_ANDROID)
1658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  void SendToATrace();
1668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif
1678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: these are ordered by size (largest first) for optimal packing.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks timestamp_;
1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TimeTicks thread_timestamp_;
1728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TimeDelta duration_;
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TimeDelta thread_duration_;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // id_ can be used to store phase-specific data.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned long long id_;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceValue arg_values_[kTraceMaxNumArgs];
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* arg_names_[kTraceMaxNumArgs];
1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_refptr<ConvertableToTraceFormat> convertable_values_[kTraceMaxNumArgs];
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const unsigned char* category_group_enabled_;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* name_;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::RefCountedString> parameter_copy_storage_;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int thread_id_;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char phase_;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char flags_;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char arg_types_[kTraceMaxNumArgs];
1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TraceEvent);
1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// TraceBufferChunk is the basic unit of TraceBuffer.
1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class BASE_EXPORT TraceBufferChunk {
1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TraceBufferChunk(uint32 seq)
1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      : next_free_(0),
1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        seq_(seq) {
1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void Reset(uint32 new_seq);
1998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TraceEvent* AddTraceEvent(size_t* event_index);
2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool IsFull() const { return next_free_ == kTraceBufferChunkSize; }
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  uint32 seq() const { return seq_; }
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t capacity() const { return kTraceBufferChunkSize; }
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t size() const { return next_free_; }
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TraceEvent* GetEventAt(size_t index) {
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    DCHECK(index < size());
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return &chunk_[index];
2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const TraceEvent* GetEventAt(size_t index) const {
2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    DCHECK(index < size());
2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return &chunk_[index];
2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<TraceBufferChunk> Clone() const;
2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  static const size_t kTraceBufferChunkSize = 64;
2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t next_free_;
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TraceEvent chunk_[kTraceBufferChunkSize];
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  uint32 seq_;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TraceBuffer holds the events as they are collected.
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BASE_EXPORT TraceBuffer {
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TraceBuffer() {}
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual scoped_ptr<TraceBufferChunk> GetChunk(size_t *index) = 0;
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void ReturnChunk(size_t index,
2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           scoped_ptr<TraceBufferChunk> chunk) = 0;
2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool IsFull() const = 0;
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual size_t Size() const = 0;
2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual size_t Capacity() const = 0;
2378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual TraceEvent* GetEventByHandle(TraceEventHandle handle) = 0;
2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // For iteration. Each TraceBuffer can only be iterated once.
2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual const TraceBufferChunk* NextChunk() = 0;
2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual scoped_ptr<TraceBuffer> CloneForIteration() const = 0;
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TraceResultBuffer collects and converts trace fragments returned by TraceLog
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to JSON output.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT TraceResultBuffer {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(const std::string&)> OutputCallback;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If you don't need to stream JSON chunks out efficiently, and just want to
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // get a complete JSON string after calling Finish, use this struct to collect
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // JSON trace output.
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct BASE_EXPORT SimpleOutput {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OutputCallback GetCallback();
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void Append(const std::string& json_string);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Do what you want with the json_output_ string after calling
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TraceResultBuffer::Finish.
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string json_output;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceResultBuffer();
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~TraceResultBuffer();
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set callback. The callback will be called during Start with the initial
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // JSON output and during AddFragment and Finish with following JSON output
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // chunks. The callback target must live past the last calls to
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TraceResultBuffer::Start/AddFragment/Finish.
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetOutputCallback(const OutputCallback& json_chunk_callback);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start JSON output. This resets all internal state, so you can reuse
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the TraceResultBuffer by calling Start.
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Start();
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call AddFragment 0 or more times to add trace fragments from TraceLog.
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddFragment(const std::string& trace_fragment);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When all fragments have been added, call Finish to complete the JSON
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // formatted output.
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Finish();
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OutputCallback output_callback_;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool append_comma_;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class BASE_EXPORT CategoryFilter {
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef std::vector<std::string> StringList;
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The default category filter, used when none is provided.
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Allows all categories through, except if they end in the suffix 'Debug' or
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // 'Test'.
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static const char* kDefaultCategoryFilterString;
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // |filter_string| is a comma-delimited list of category wildcards.
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // A category can have an optional '-' prefix to make it an excluded category.
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // All the same rules apply above, so for example, having both included and
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // excluded categories in the same list would not be supported.
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Example: CategoryFilter"test_MyTest*");
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Example: CategoryFilter("test_MyTest*,test_OtherStuff");
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Example: CategoryFilter("-excluded_category1,-excluded_category2");
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Example: CategoryFilter("-*,webkit"); would disable everything but webkit.
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Example: CategoryFilter("-webkit"); would enable everything but webkit.
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Category filters can also be used to configure synthetic delays.
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //
3105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Example: CategoryFilter("DELAY(gpu.PresentingFrame;16)"); would make swap
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //          buffers always take at least 16 ms.
3125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Example: CategoryFilter("DELAY(gpu.PresentingFrame;16;oneshot)"); would
3135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  //          make swap buffers take at least 16 ms the first time it is
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //          called.
3155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Example: CategoryFilter("DELAY(gpu.PresentingFrame;16;alternating)");
3165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  //          would make swap buffers take at least 16 ms every other time it
3175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  //          is called.
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit CategoryFilter(const std::string& filter_string);
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CategoryFilter();
3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CategoryFilter(const CategoryFilter& cf);
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ~CategoryFilter();
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CategoryFilter& operator=(const CategoryFilter& rhs);
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Writes the string representation of the CategoryFilter. This is a comma
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // separated string, similar in nature to the one used to determine
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // enabled/disabled category patterns, except here there is an arbitrary
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // order, included categories go first, then excluded categories. Excluded
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // categories are distinguished from included categories by the prefix '-'.
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string ToString() const;
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Determines whether category group would be enabled or
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // disabled by this category filter.
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool IsCategoryGroupEnabled(const char* category_group) const;
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Return a list of the synthetic delays specified in this category filter.
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const StringList& GetSyntheticDelayValues() const;
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Merges nested_filter with the current CategoryFilter
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Merge(const CategoryFilter& nested_filter);
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Clears both included/excluded pattern lists. This would be equivalent to
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // creating a CategoryFilter with an empty string, through the constructor.
3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // i.e: CategoryFilter().
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // When using an empty filter, all categories are considered included as we
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // are not excluding anything.
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Clear();
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
353b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) private:
354b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, CategoryFilter);
355b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static bool IsEmptyOrContainsLeadingOrTrailingWhitespace(
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& str);
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Initialize(const std::string& filter_string);
360b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  void WriteString(const StringList& values,
361b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                   std::string* out,
362b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                   bool included) const;
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void WriteString(const StringList& delays, std::string* out) const;
364b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  bool HasIncludedPatterns() const;
365b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
366b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  bool DoesCategoryGroupContainCategory(const char* category_group,
367b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                        const char* category) const;
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
369b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  StringList included_;
370b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  StringList disabled_;
371b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  StringList excluded_;
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StringList delays_;
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TraceSamplingThread;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Options determines how the trace buffer stores data.
3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)enum TraceRecordMode {
3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Record until the trace buffer is full.
3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RECORD_UNTIL_FULL,
3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Record until the user ends the trace. The trace buffer is a fixed size
3835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // and we use it as a ring buffer during recording.
3845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RECORD_CONTINUOUSLY,
3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Echo to console. Events are discarded.
3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ECHO_TO_CONSOLE,
3886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Record until the trace buffer is full, but with a huge buffer size.
3906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  RECORD_AS_MUCH_AS_POSSIBLE
3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)struct BASE_EXPORT TraceOptions {
3945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TraceOptions()
3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : record_mode(RECORD_UNTIL_FULL),
3975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        enable_sampling(false),
3985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        enable_systrace(false) {}
3995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TraceOptions(TraceRecordMode record_mode)
4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : record_mode(record_mode),
4025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        enable_sampling(false),
4035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        enable_systrace(false) {}
4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // |options_string| is a comma-delimited list of trace options.
4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Possible options are: "record-until-full", "record-continuously",
4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // "trace-to-console", "enable-sampling" and "enable-systrace".
4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The first 3 options are trace recoding modes and hence
4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // mutually exclusive. If more than one trace recording modes appear in the
4105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // options_string, the last one takes precedence. If none of the trace
4115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // recording mode is specified, recording mode is RECORD_UNTIL_FULL.
4125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  //
4136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // The trace option will first be reset to the default option
4146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // (record_mode set to RECORD_UNTIL_FULL, enable_sampling and enable_systrace
4156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // set to false) before options parsed from |options_string| are applied on
4166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // it.
4176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // If |options_string| is invalid, the final state of trace_options is
4186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // undefined.
4196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  //
4206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Example: trace_options.SetFromString("record-until-full")
4216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Example: trace_options.SetFromString(
4226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  //              "record-continuously, enable-sampling")
4236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Example: trace_options.SetFromString("record-until-full, trace-to-console")
4246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // will set ECHO_TO_CONSOLE as the recording mode.
4256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  //
4266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Returns true on success.
4276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  bool SetFromString(const std::string& options_string);
4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string ToString() const;
4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TraceRecordMode record_mode;
4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool enable_sampling;
4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool enable_systrace;
4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT TraceLog {
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  enum Mode {
4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DISABLED = 0,
4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RECORDING_MODE,
4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MONITORING_MODE,
4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The pointer returned from GetCategoryGroupEnabledInternal() points to a
445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // value with zero or more of the following bits. Used in this class only.
446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The TRACE_EVENT macros should only use the value as a bool.
4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // These values must be in sync with macro values in TraceEvent.h in Blink.
448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  enum CategoryGroupEnabledFlags {
4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Category group enabled for the recording mode.
450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ENABLED_FOR_RECORDING = 1 << 0,
4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Category group enabled for the monitoring mode.
4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ENABLED_FOR_MONITORING = 1 << 1,
453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Category group enabled by SetEventCallbackEnabled().
4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ENABLED_FOR_EVENT_CALLBACK = 1 << 2,
455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static TraceLog* GetInstance();
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Get set of known category groups. This can change as new code paths are
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // reached. The known category groups are inserted into |category_groups|.
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void GetKnownCategoryGroups(std::vector<std::string>* category_groups);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Retrieves a copy (for thread-safety) of the current CategoryFilter.
464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CategoryFilter GetCurrentCategoryFilter();
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Retrieves a copy (for thread-safety) of the current TraceOptions.
4675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TraceOptions GetCurrentTraceOptions() const;
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Enables normal tracing (recording trace events in the trace buffer).
470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // See CategoryFilter comments for details on how to control what categories
471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // will be traced. If tracing has already been enabled, |category_filter| will
472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // be merged into the current category filter.
4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetEnabled(const CategoryFilter& category_filter,
4745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                  Mode mode, const TraceOptions& options);
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Disables normal tracing for all categories.
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetDisabled();
478f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool IsEnabled() { return mode_ != DISABLED; }
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The number of times we have begun recording traces. If tracing is off,
482868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // returns -1. If tracing is on, then it returns the number of times we have
483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // recorded a trace. By watching for this number to increment, you can
484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // passively discover when a new trace has begun. This is then used to
485868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // implement the TRACE_EVENT_IS_NEW_TRACE() primitive.
486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int GetNumTracesRecorded();
487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID)
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StartATrace();
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StopATrace();
4914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void AddClockSyncMetadataEvent();
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enabled state listeners give a callback when tracing is enabled or
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // disabled. This can be used to tie into other library's tracing systems
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on-demand.
4971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  class BASE_EXPORT EnabledStateObserver {
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
4997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Called just after the tracing system becomes enabled, outside of the
5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // |lock_|. TraceLog::IsEnabled() is true at this point.
5017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual void OnTraceLogEnabled() = 0;
5027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Called just after the tracing system disables, outside of the |lock_|.
5047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // TraceLog::IsEnabled() is false at this point.
5057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual void OnTraceLogDisabled() = 0;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
5077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddEnabledStateObserver(EnabledStateObserver* listener);
5087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RemoveEnabledStateObserver(EnabledStateObserver* listener);
509bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  bool HasEnabledStateObserver(EnabledStateObserver* listener) const;
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float GetBufferPercentFull() const;
512a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool BufferIsFull() const;
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
514ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Not using base::Callback because of its limited by 7 parameters.
515ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Also, using primitive type allows directly passing callback from WebCore.
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WARNING: It is possible for the previously set callback to be called
517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // after a call to SetEventCallbackEnabled() that replaces or a call to
518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // SetEventCallbackDisabled() that disables the callback.
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This callback may be invoked on any thread.
520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // For TRACE_EVENT_PHASE_COMPLETE events, the client will still receive pairs
521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // of TRACE_EVENT_PHASE_BEGIN and TRACE_EVENT_PHASE_END events to keep the
522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // interface simple.
5231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  typedef void (*EventCallback)(TimeTicks timestamp,
5241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                char phase,
525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                const unsigned char* category_group_enabled,
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const char* name,
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                unsigned long long id,
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                int num_args,
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const char* const arg_names[],
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const unsigned char arg_types[],
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const unsigned long long arg_values[],
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                unsigned char flags);
533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Enable tracing for EventCallback.
535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void SetEventCallbackEnabled(const CategoryFilter& category_filter,
536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               EventCallback cb);
537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void SetEventCallbackDisabled();
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Flush all collected events to the given output callback. The callback will
54058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // be called one or more times either synchronously or asynchronously from
54158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // the current thread with IPC-bite-size chunks. The string format is
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // undefined. Use TraceResultBuffer to convert one or more trace strings to
54358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // JSON. The callback can be null if the caller doesn't want any data.
54458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Due to the implementation of thread-local buffers, flush can't be
54558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // done when tracing is enabled. If called when tracing is enabled, the
54658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // callback will be called directly with (empty_string, false) to indicate
54758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // the end of this unsuccessful flush.
54858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&,
54958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              bool has_more_events)> OutputCallback;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Flush(const OutputCallback& cb);
5514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void FlushButLeaveBufferIntact(const OutputCallback& flush_output_callback);
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called by TRACE_EVENT* macros, don't call this directly.
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The name parameter is a category group for example:
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent")
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static const unsigned char* GetCategoryGroupEnabled(const char* name);
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static const char* GetCategoryGroupName(
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const unsigned char* category_group_enabled);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called by TRACE_EVENT* macros, don't call this directly.
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above.
5638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TraceEventHandle AddTraceEvent(
5644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      char phase,
5654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const unsigned char* category_group_enabled,
5664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const char* name,
5674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      unsigned long long id,
5684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      int num_args,
5694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const char** arg_names,
5704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const unsigned char* arg_types,
5714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const unsigned long long* arg_values,
5724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
5734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      unsigned char flags);
5748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TraceEventHandle AddTraceEventWithThreadIdAndTimestamp(
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      char phase,
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const unsigned char* category_group_enabled,
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const char* name,
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      unsigned long long id,
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int thread_id,
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const TimeTicks& timestamp,
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int num_args,
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const char** arg_names,
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const unsigned char* arg_types,
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const unsigned long long* arg_values,
5854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      unsigned char flags);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void AddTraceEventEtw(char phase,
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               const char* category_group,
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const void* id,
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const char* extra);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void AddTraceEventEtw(char phase,
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               const char* category_group,
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const void* id,
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const std::string& extra);
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
596f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void UpdateTraceEventDuration(const unsigned char* category_group_enabled,
597f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                const char* name,
598f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                TraceEventHandle handle);
5998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
600a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // For every matching event, the callback will be called.
601a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  typedef base::Callback<void()> WatchEventCallback;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetWatchEvent(const std::string& category_name,
603a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     const std::string& event_name,
604a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     const WatchEventCallback& callback);
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancel the watch event. If tracing is enabled, this may race with the
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // watch event notification firing.
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CancelWatchEvent();
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int process_id() const { return process_id_; }
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Exposed for unittesting:
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
613f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void WaitSamplingEventForTesting();
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allows deleting our singleton instance.
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void DeleteForTesting();
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allow tests to inspect TraceEvents.
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t GetEventsSize() const { return logged_events_->Size(); }
6208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TraceEvent* GetEventByHandle(TraceEventHandle handle);
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetProcessID(int process_id);
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Process sort indices, if set, override the order of a process will appear
6257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // relative to other processes in the trace viewer. Processes are sorted first
6267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // on their sort index, ascending, then by their name, and then tid.
6277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void SetProcessSortIndex(int sort_index);
6287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Sets the name of the process.
6307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void SetProcessName(const std::string& process_name);
6317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Processes can have labels in addition to their names. Use labels, for
6337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // instance, to list out the web page titles that a process is handling.
6347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void UpdateProcessLabel(int label_id, const std::string& current_label);
6357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void RemoveProcessLabel(int label_id);
6367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Thread sort indices, if set, override the order of a thread will appear
6387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // within its process in the trace viewer. Threads are sorted first on their
6397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // sort index, ascending, then by their name, and then tid.
6407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void SetThreadSortIndex(PlatformThreadId , int sort_index);
6417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Allow setting an offset between the current TimeTicks time and the time
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that should be reported.
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetTimeOffset(TimeDelta offset);
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t GetObserverCountForTest() const;
6477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Call this method if the current thread may block the message loop to
6498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // prevent the thread from using the thread-local buffer because the thread
6508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // may not handle the flush request in time causing lost of unflushed events.
6518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  void SetCurrentThreadBlocksMessageLoop();
6528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
6545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  typedef unsigned int InternalTraceOptions;
6555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
6574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           TraceBufferRingBufferGetReturnChunk);
6584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
6594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           TraceBufferRingBufferHalfIteration);
6604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
6614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           TraceBufferRingBufferFullIteration);
6625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
6635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                           TraceBufferVectorReportFull);
6645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
6655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                           ConvertTraceOptionsToInternalOptions);
6666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
6676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           TraceRecordAsMuchAsPossibleMode);
6684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This allows constructor and destructor to be private and usable only
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // by the Singleton class.
6717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  friend struct DefaultSingletonTraits<TraceLog>;
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Enable/disable each category group based on the current mode_,
674f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // category_filter_, event_callback_ and event_callback_category_filter_.
6755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Enable the category group in the enabled mode if category_filter_ matches
676f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // the category group, or event_callback_ is not null and
677f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // event_callback_category_filter_ matches the category group.
678bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  void UpdateCategoryGroupEnabledFlags();
679116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void UpdateCategoryGroupEnabledFlag(size_t category_index);
680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Configure synthetic delays based on the values set in the current
6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // category filter.
6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void UpdateSyntheticDelaysFromCategoryFilter();
6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  InternalTraceOptions GetInternalOptionsFromTraceOptions(
6865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const TraceOptions& options);
6875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
68858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  class ThreadLocalEventBuffer;
6898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  class OptionalAutoLock;
69058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceLog();
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~TraceLog();
693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const unsigned char* GetCategoryGroupEnabledInternal(const char* name);
6944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void AddMetadataEventsWhileLocked();
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  InternalTraceOptions trace_options() const {
6975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return static_cast<InternalTraceOptions>(
6985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        subtle::NoBarrier_Load(&trace_options_));
6995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
7005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TraceBuffer* trace_buffer() const { return logged_events_.get(); }
7024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TraceBuffer* CreateTraceBuffer();
7035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TraceBuffer* CreateTraceBufferVectorOfSize(size_t max_chunks);
7044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
705a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string EventToConsoleMessage(unsigned char phase,
706a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    const TimeTicks& timestamp,
707a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    TraceEvent* trace_event);
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
709a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  TraceEvent* AddEventToThreadSharedChunkWhileLocked(TraceEventHandle* handle,
710a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                     bool check_buffer_is_full);
711a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void CheckIfBufferIsFullWhileLocked();
712a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void SetDisabledWhileLocked();
7134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TraceEvent* GetEventByHandleInternal(TraceEventHandle handle,
7158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                       OptionalAutoLock* lock);
7168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
7174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |generation| is used in the following callbacks to check if the callback
7184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // is called for the flush of the current |logged_events_|.
7194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void FlushCurrentThread(int generation);
7204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void ConvertTraceEventsToTraceFormat(scoped_ptr<TraceBuffer> logged_events,
7214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const TraceLog::OutputCallback& flush_output_callback);
7224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void FinishFlush(int generation);
7234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void OnFlushTimeout(int generation);
7244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int generation() const {
7264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return static_cast<int>(subtle::NoBarrier_Load(&generation_));
7274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
7284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool CheckGeneration(int generation) const {
7294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return generation == this->generation();
7304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void UseNextTraceBuffer();
73258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  TimeTicks OffsetNow() const {
7340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return OffsetTimestamp(TimeTicks::NowFromSystemTraceTime());
7350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
7360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  TimeTicks OffsetTimestamp(const TimeTicks& timestamp) const {
7370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return timestamp - time_offset_;
7380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
7390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
7405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Internal representation of trace options since we store the currently used
7415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // trace option as an AtomicWord.
7425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static const InternalTraceOptions kInternalNone;
7435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static const InternalTraceOptions kInternalRecordUntilFull;
7445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static const InternalTraceOptions kInternalRecordContinuously;
7455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static const InternalTraceOptions kInternalEchoToConsole;
7465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static const InternalTraceOptions kInternalEnableSampling;
7476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  static const InternalTraceOptions kInternalRecordAsMuchAsPossible;
7485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
749a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // This lock protects TraceLog member accesses (except for members protected
750a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // by thread_info_lock_) from arbitrary threads.
751a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  mutable Lock lock_;
752a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // This lock protects accesses to thread_names_, thread_event_start_times_
753a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // and thread_colors_.
754a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Lock thread_info_lock_;
75558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int locked_line_;
7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Mode mode_;
757868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int num_traces_recorded_;
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<TraceBuffer> logged_events_;
75958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  subtle::AtomicWord /* EventCallback */ event_callback_;
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool dispatching_to_observer_list_;
7617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::vector<EnabledStateObserver*> enabled_state_observer_list_;
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string process_name_;
7647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::hash_map<int, std::string> process_labels_;
7657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int process_sort_index_;
7667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::hash_map<int, int> thread_sort_indices_;
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::hash_map<int, std::string> thread_names_;
76858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
76958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // The following two maps are used only when ECHO_TO_CONSOLE.
770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_;
771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::hash_map<std::string, int> thread_colors_;
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TimeTicks buffer_limit_reached_timestamp_;
7745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // XORed with TraceID to make it unlikely to collide with other processes.
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned long long process_id_hash_;
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int process_id_;
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TimeDelta time_offset_;
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allow tests to wake up when certain events occur.
783a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  WatchEventCallback watch_event_callback_;
78458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  subtle::AtomicWord /* const unsigned char* */ watch_category_;
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string watch_event_name_;
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  subtle::AtomicWord /* Options */ trace_options_;
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sampling thread handles.
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<TraceSamplingThread> sampling_thread_;
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PlatformThreadHandle sampling_thread_handle_;
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CategoryFilter category_filter_;
794f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CategoryFilter event_callback_category_filter_;
795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
79658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ThreadLocalPointer<ThreadLocalEventBuffer> thread_local_event_buffer_;
7978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ThreadLocalBoolean thread_blocks_message_loop_;
798a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ThreadLocalBoolean thread_is_in_trace_event_;
79958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
80058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Contains the message loops of threads that have had at least one event
80158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // added into the local event buffer. Not using MessageLoopProxy because we
80258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // need to know the life time of the message loops.
8034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  hash_set<MessageLoop*> thread_message_loops_;
8044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // For events which can't be added into the thread local buffer, e.g. events
8064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // from threads without a message loop.
8074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<TraceBufferChunk> thread_shared_chunk_;
8084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t thread_shared_chunk_index_;
80958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
81058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Set when asynchronous Flush is in progress.
81158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OutputCallback flush_output_callback_;
81258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<MessageLoopProxy> flush_message_loop_proxy_;
8134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  subtle::AtomicWord generation_;
81458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TraceLog);
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace debug
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_DEBUG_TRACE_EVENT_IMPL_H_
822