trace_event_impl.h revision 58537e28ecd584eab876aee8be7156509866d23a
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.
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ConvertableToTraceFormat {
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~ConvertableToTraceFormat() {}
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
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;
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTraceMaxNumArgs = 2;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Output records are "Events" and can be obtained via the
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OutputCallback whenever the tracing system decides to flush. This
82ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// can happen at any time, on any thread, or you can programmatically
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// force it to happen.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT TraceEvent {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  union TraceValue {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool as_bool;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long long as_uint;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    long long as_int;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double as_double;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const void* as_pointer;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* as_string;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceEvent();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceEvent(int thread_id,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             TimeTicks timestamp,
983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)             TimeTicks thread_timestamp,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             char phase,
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             const unsigned char* category_group_enabled,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             const char* name,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             unsigned long long id,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             int num_args,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             const char** arg_names,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             const unsigned char* arg_types,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             const unsigned long long* arg_values,
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             scoped_ptr<ConvertableToTraceFormat> convertable_values[],
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             unsigned char flags);
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceEvent(const TraceEvent& other);
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceEvent& operator=(const TraceEvent& other);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~TraceEvent();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize event data to JSON
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void AppendEventsAsJSON(const std::vector<TraceEvent>& events,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 size_t start,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 size_t count,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 std::string* out);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AppendAsJSON(std::string* out) const;
1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void AppendPrettyPrinted(std::ostringstream* out) const;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void AppendValueAsJSON(unsigned char type,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                TraceValue value,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                std::string* out);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks timestamp() const { return timestamp_; }
1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TimeTicks thread_timestamp() const { return thread_timestamp_; }
12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  char phase() const { return phase_; }
12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int thread_id() const { return thread_id_; }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Exposed for unittesting:
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::RefCountedString* parameter_copy_storage() const {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return parameter_copy_storage_.get();
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const unsigned char* category_group_enabled() const {
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return category_group_enabled_;
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* name() const { return name_; }
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: these are ordered by size (largest first) for optimal packing.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks timestamp_;
1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TimeTicks thread_timestamp_;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // id_ can be used to store phase-specific data.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned long long id_;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceValue arg_values_[kTraceMaxNumArgs];
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* arg_names_[kTraceMaxNumArgs];
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<ConvertableToTraceFormat> convertable_values_[kTraceMaxNumArgs];
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const unsigned char* category_group_enabled_;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* name_;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::RefCountedString> parameter_copy_storage_;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int thread_id_;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char phase_;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char flags_;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char arg_types_[kTraceMaxNumArgs];
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TraceBuffer holds the events as they are collected.
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BASE_EXPORT TraceBuffer {
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TraceBuffer() {}
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddEvent(const TraceEvent& event) = 0;
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool HasMoreEvents() const = 0;
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual const TraceEvent& NextEvent() = 0;
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool IsFull() const = 0;
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual size_t CountEnabledByName(const unsigned char* category,
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const std::string& event_name) const = 0;
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual size_t Size() const = 0;
1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual size_t Capacity() const = 0;
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual const TraceEvent& GetEventAt(size_t index) const = 0;
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TraceResultBuffer collects and converts trace fragments returned by TraceLog
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to JSON output.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT TraceResultBuffer {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(const std::string&)> OutputCallback;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If you don't need to stream JSON chunks out efficiently, and just want to
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // get a complete JSON string after calling Finish, use this struct to collect
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // JSON trace output.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct BASE_EXPORT SimpleOutput {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OutputCallback GetCallback();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void Append(const std::string& json_string);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Do what you want with the json_output_ string after calling
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TraceResultBuffer::Finish.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string json_output;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceResultBuffer();
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~TraceResultBuffer();
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set callback. The callback will be called during Start with the initial
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // JSON output and during AddFragment and Finish with following JSON output
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // chunks. The callback target must live past the last calls to
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TraceResultBuffer::Start/AddFragment/Finish.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetOutputCallback(const OutputCallback& json_chunk_callback);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start JSON output. This resets all internal state, so you can reuse
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the TraceResultBuffer by calling Start.
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Start();
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call AddFragment 0 or more times to add trace fragments from TraceLog.
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddFragment(const std::string& trace_fragment);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When all fragments have been added, call Finish to complete the JSON
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // formatted output.
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Finish();
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OutputCallback output_callback_;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool append_comma_;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class BASE_EXPORT CategoryFilter {
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The default category filter, used when none is provided.
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Allows all categories through, except if they end in the suffix 'Debug' or
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // 'Test'.
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static const char* kDefaultCategoryFilterString;
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // |filter_string| is a comma-delimited list of category wildcards.
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // A category can have an optional '-' prefix to make it an excluded category.
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // All the same rules apply above, so for example, having both included and
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // excluded categories in the same list would not be supported.
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Example: CategoryFilter"test_MyTest*");
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Example: CategoryFilter("test_MyTest*,test_OtherStuff");
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Example: CategoryFilter("-excluded_category1,-excluded_category2");
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Example: CategoryFilter("-*,webkit"); would disable everything but webkit.
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Example: CategoryFilter("-webkit"); would enable everything but webkit.
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit CategoryFilter(const std::string& filter_string);
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CategoryFilter(const CategoryFilter& cf);
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ~CategoryFilter();
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CategoryFilter& operator=(const CategoryFilter& rhs);
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Writes the string representation of the CategoryFilter. This is a comma
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // separated string, similar in nature to the one used to determine
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // enabled/disabled category patterns, except here there is an arbitrary
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // order, included categories go first, then excluded categories. Excluded
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // categories are distinguished from included categories by the prefix '-'.
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string ToString() const;
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Determines whether category group would be enabled or
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // disabled by this category filter.
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool IsCategoryGroupEnabled(const char* category_group) const;
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Merges nested_filter with the current CategoryFilter
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Merge(const CategoryFilter& nested_filter);
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Clears both included/excluded pattern lists. This would be equivalent to
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // creating a CategoryFilter with an empty string, through the constructor.
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // i.e: CategoryFilter("").
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // When using an empty filter, all categories are considered included as we
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // are not excluding anything.
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Clear();
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
266b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) private:
267b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, CategoryFilter);
268b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static bool IsEmptyOrContainsLeadingOrTrailingWhitespace(
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& str);
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
272b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  typedef std::vector<std::string> StringList;
273b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Initialize(const std::string& filter_string);
275b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  void WriteString(const StringList& values,
276b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                   std::string* out,
277b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                   bool included) const;
278b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  bool HasIncludedPatterns() const;
279b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
280b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  bool DoesCategoryGroupContainCategory(const char* category_group,
281b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                        const char* category) const;
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
283b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  StringList included_;
284b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  StringList disabled_;
285b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  StringList excluded_;
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TraceSamplingThread;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT TraceLog {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notification is a mask of one or more of the following events.
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum Notification {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The trace buffer does not flush dynamically, so when it fills up,
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // subsequent trace events will be dropped. This callback is generated when
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the trace buffer is full. The callback must be thread safe.
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TRACE_BUFFER_FULL = 1 << 0,
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A subscribed trace-event occurred.
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EVENT_WATCH_NOTIFICATION = 1 << 1
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Options determines how the trace buffer stores data.
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum Options {
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Record until the trace buffer is full.
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RECORD_UNTIL_FULL = 1 << 0,
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Record until the user ends the trace. The trace buffer is a fixed size
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // and we use it as a ring buffer during recording.
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RECORD_CONTINUOUSLY = 1 << 1,
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Enable the sampling profiler.
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ENABLE_SAMPLING = 1 << 2,
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
314ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // Echo to console. Events are discarded.
31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ECHO_TO_CONSOLE = 1 << 3,
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static TraceLog* GetInstance();
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Convert the given string to trace options. Defaults to RECORD_UNTIL_FULL if
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the string does not provide valid options.
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static Options TraceOptionsFromString(const std::string& str);
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Get set of known category groups. This can change as new code paths are
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // reached. The known category groups are inserted into |category_groups|.
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void GetKnownCategoryGroups(std::vector<std::string>* category_groups);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Retrieves the current CategoryFilter.
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const CategoryFilter& GetCurrentCategoryFilter();
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Options trace_options() const {
33258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return static_cast<Options>(subtle::NoBarrier_Load(&trace_options_));
33358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Enables tracing. See CategoryFilter comments for details
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // on how to control what categories will be traced.
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void SetEnabled(const CategoryFilter& category_filter, Options options);
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disable tracing for all categories.
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetDisabled();
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsEnabled() { return !!enable_count_; }
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The number of times we have begun recording traces. If tracing is off,
344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // returns -1. If tracing is on, then it returns the number of times we have
345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // recorded a trace. By watching for this number to increment, you can
346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // passively discover when a new trace has begun. This is then used to
347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // implement the TRACE_EVENT_IS_NEW_TRACE() primitive.
348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int GetNumTracesRecorded();
349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID)
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StartATrace();
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StopATrace();
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enabled state listeners give a callback when tracing is enabled or
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // disabled. This can be used to tie into other library's tracing systems
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on-demand.
3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  class EnabledStateObserver {
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Called just after the tracing system becomes enabled, outside of the
3617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // |lock_|.  TraceLog::IsEnabled() is true at this point.
3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual void OnTraceLogEnabled() = 0;
3637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Called just after the tracing system disables, outside of the |lock_|.
3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // TraceLog::IsEnabled() is false at this point.
3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual void OnTraceLogDisabled() = 0;
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddEnabledStateObserver(EnabledStateObserver* listener);
3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RemoveEnabledStateObserver(EnabledStateObserver* listener);
370bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  bool HasEnabledStateObserver(EnabledStateObserver* listener) const;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float GetBufferPercentFull() const;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the thread-safe notification callback. The callback can occur at any
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // time and from any thread. WARNING: It is possible for the previously set
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // callback to be called during OR AFTER a call to SetNotificationCallback.
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Therefore, the target of the callback must either be a global function,
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ref-counted object or a LazyInstance with Leaky traits (or equivalent).
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(int)> NotificationCallback;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetNotificationCallback(const NotificationCallback& cb);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
382ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Not using base::Callback because of its limited by 7 parameters.
383ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Also, using primitive type allows directly passing callback from WebCore.
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WARNING: It is possible for the previously set callback to be called
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // after a call to SetEventCallback() that replaces or clears the callback.
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This callback may be invoked on any thread.
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef void (*EventCallback)(char phase,
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                const unsigned char* category_group_enabled,
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const char* name,
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                unsigned long long id,
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                int num_args,
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const char* const arg_names[],
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const unsigned char arg_types[],
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const unsigned long long arg_values[],
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                unsigned char flags);
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetEventCallback(EventCallback cb);
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Flush all collected events to the given output callback. The callback will
39958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // be called one or more times either synchronously or asynchronously from
40058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // the current thread with IPC-bite-size chunks. The string format is
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // undefined. Use TraceResultBuffer to convert one or more trace strings to
40258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // JSON. The callback can be null if the caller doesn't want any data.
40358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Due to the implementation of thread-local buffers, flush can't be
40458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // done when tracing is enabled. If called when tracing is enabled, the
40558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // callback will be called directly with (empty_string, false) to indicate
40658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // the end of this unsuccessful flush.
40758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&,
40858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              bool has_more_events)> OutputCallback;
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Flush(const OutputCallback& cb);
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called by TRACE_EVENT* macros, don't call this directly.
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The name parameter is a category group for example:
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent")
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static const unsigned char* GetCategoryGroupEnabled(const char* name);
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static const char* GetCategoryGroupName(
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const unsigned char* category_group_enabled);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called by TRACE_EVENT* macros, don't call this directly.
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above.
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddTraceEvent(char phase,
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                     const unsigned char* category_group_enabled,
423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     const char* name,
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     unsigned long long id,
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     int num_args,
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const char** arg_names,
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const unsigned char* arg_types,
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const unsigned long long* arg_values,
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                     scoped_ptr<ConvertableToTraceFormat> convertable_values[],
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     unsigned char flags);
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddTraceEventWithThreadIdAndTimestamp(
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      char phase,
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const unsigned char* category_group_enabled,
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const char* name,
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      unsigned long long id,
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int thread_id,
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const TimeTicks& timestamp,
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int num_args,
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const char** arg_names,
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const unsigned char* arg_types,
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const unsigned long long* arg_values,
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scoped_ptr<ConvertableToTraceFormat> convertable_values[],
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      unsigned char flags);
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void AddTraceEventEtw(char phase,
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               const char* category_group,
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const void* id,
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const char* extra);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void AddTraceEventEtw(char phase,
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               const char* category_group,
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const void* id,
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const std::string& extra);
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For every matching event, a notification will be fired. NOTE: the
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notification will fire for each matching event that has already occurred
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since tracing was started (including before tracing if the process was
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // started with tracing turned on).
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetWatchEvent(const std::string& category_name,
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const std::string& event_name);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancel the watch event. If tracing is enabled, this may race with the
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // watch event notification firing.
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CancelWatchEvent();
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int process_id() const { return process_id_; }
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Exposed for unittesting:
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void InstallWaitableEventForSamplingTesting(WaitableEvent* waitable_event);
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allows deleting our singleton instance.
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void DeleteForTesting();
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allow tests to inspect TraceEvents.
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t GetEventsSize() const { return logged_events_->Size(); }
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TraceEvent& GetEventAt(size_t index) const {
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return logged_events_->GetEventAt(index);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetProcessID(int process_id);
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Process sort indices, if set, override the order of a process will appear
4817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // relative to other processes in the trace viewer. Processes are sorted first
4827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // on their sort index, ascending, then by their name, and then tid.
4837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void SetProcessSortIndex(int sort_index);
4847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Sets the name of the process.
4867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void SetProcessName(const std::string& process_name);
4877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Processes can have labels in addition to their names. Use labels, for
4897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // instance, to list out the web page titles that a process is handling.
4907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void UpdateProcessLabel(int label_id, const std::string& current_label);
4917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void RemoveProcessLabel(int label_id);
4927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Thread sort indices, if set, override the order of a thread will appear
4947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // within its process in the trace viewer. Threads are sorted first on their
4957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // sort index, ascending, then by their name, and then tid.
4967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void SetThreadSortIndex(PlatformThreadId , int sort_index);
4977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Allow setting an offset between the current TimeTicks time and the time
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that should be reported.
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetTimeOffset(TimeDelta offset);
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t GetObserverCountForTest() const;
5037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This allows constructor and destructor to be private and usable only
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // by the Singleton class.
5077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  friend struct DefaultSingletonTraits<TraceLog>;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
509bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Enable/disable each category group based on the current enable_count_
510bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // and category_filter_. Disable the category group if enabled_count_ is 0, or
511bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // if the category group contains a category that matches an included category
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pattern, that category group will be enabled.
513bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // On Android, ATRACE_ENABLED flag will be applied if atrace is started.
514bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  void UpdateCategoryGroupEnabledFlags();
515bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  void UpdateCategoryGroupEnabledFlag(int category_index);
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
51790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  static void SetCategoryGroupEnabled(int category_index, bool enabled);
518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  static bool IsCategoryGroupEnabled(
519868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const unsigned char* category_group_enabled);
52090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The pointer returned from GetCategoryGroupEnabledInternal() points to a
522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // value with zero or more of the following bits. Used in this class only.
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The TRACE_EVENT macros should only use the value as a bool.
524bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  enum CategoryGroupEnabledFlags {
525bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    // Normal enabled flag for category groups enabled with Enable().
526bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    CATEGORY_GROUP_ENABLED = 1 << 0,
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // On Android if ATrace is enabled, all categories will have this bit.
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Not used on other platforms.
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ATRACE_ENABLED = 1 << 1
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper class for managing notification_thread_count_ and running
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notification callbacks. This is very similar to a reader-writer lock, but
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // shares the lock with TraceLog and manages the notification flags.
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class NotificationHelper {
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inline explicit NotificationHelper(TraceLog* trace_log);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inline ~NotificationHelper();
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Called only while TraceLog::lock_ is held. This ORs the given
541ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // notification with any existing notifications.
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inline void AddNotificationWhileLocked(int notification);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Called only while TraceLog::lock_ is NOT held. If there are any pending
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // notifications from previous calls to AddNotificationWhileLocked, this
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // will call the NotificationCallback.
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inline void SendNotificationIfAny();
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TraceLog* trace_log_;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotificationCallback callback_copy_;
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int notification_;
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  class ThreadLocalEventBuffer;
55658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceLog();
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~TraceLog();
559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const unsigned char* GetCategoryGroupEnabledInternal(const char* name);
5607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void AddMetadataEvents();
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SendToATrace(char phase,
564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    const char* category_group,
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const char* name,
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    unsigned long long id,
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int num_args,
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const char** arg_names,
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const unsigned char* arg_types,
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const unsigned long long* arg_values,
571a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                    scoped_ptr<ConvertableToTraceFormat> convertable_values[],
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    unsigned char flags);
573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static void ApplyATraceEnabledFlag(unsigned char* category_group_enabled);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TraceBuffer* GetTraceBuffer();
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
57858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void AddEventToMainBufferWhileLocked(const TraceEvent& trace_event);
57958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void CheckIfBufferIsFullWhileLocked(NotificationHelper* notifier);
58058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // |flush_count| is used in the following callbacks to check if the callback
58158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // is called for the current flush.
58258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void FlushCurrentThread(int flush_count);
58358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void FinishFlush(int flush_count);
58458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void OnFlushTimeout(int flush_count);
58558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This lock protects TraceLog member accesses from arbitrary threads.
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Lock lock_;
58858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int locked_line_;
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int enable_count_;
590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int num_traces_recorded_;
59158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  subtle::AtomicWord /* bool */ buffer_is_full_;
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotificationCallback notification_callback_;
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<TraceBuffer> logged_events_;
59458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  subtle::AtomicWord /* EventCallback */ event_callback_;
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool dispatching_to_observer_list_;
5967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::vector<EnabledStateObserver*> enabled_state_observer_list_;
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string process_name_;
5997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::hash_map<int, std::string> process_labels_;
6007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int process_sort_index_;
6017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::hash_map<int, int> thread_sort_indices_;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::hash_map<int, std::string> thread_names_;
60358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
60458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // The following two maps are used only when ECHO_TO_CONSOLE.
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_;
606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::hash_map<std::string, int> thread_colors_;
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // XORed with TraceID to make it unlikely to collide with other processes.
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned long long process_id_hash_;
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int process_id_;
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TimeDelta time_offset_;
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allow tests to wake up when certain events occur.
61658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  subtle::AtomicWord /* const unsigned char* */ watch_category_;
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string watch_event_name_;
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  subtle::AtomicWord /* Options */ trace_options_;
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sampling thread handles.
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<TraceSamplingThread> sampling_thread_;
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PlatformThreadHandle sampling_thread_handle_;
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CategoryFilter category_filter_;
626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
62758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ThreadLocalPointer<ThreadLocalEventBuffer> thread_local_event_buffer_;
62858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
62958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Contains the message loops of threads that have had at least one event
63058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // added into the local event buffer. Not using MessageLoopProxy because we
63158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // need to know the life time of the message loops.
63258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::hash_set<MessageLoop*> thread_message_loops_;
63358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
63458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Set when asynchronous Flush is in progress.
63558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OutputCallback flush_output_callback_;
63658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<MessageLoopProxy> flush_message_loop_proxy_;
63758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int flush_count_;
63858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TraceLog);
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace debug
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_DEBUG_TRACE_EVENT_IMPL_H_
646