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