trace_event_impl.h revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/hash_tables.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted_memory.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_vector.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/observer_list.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_util.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/condition_variable.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/timer.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Older style trace macros with explicit id and extra data
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Only these macros result in publishing data to ETW as currently implemented.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACE_EVENT_BEGIN_ETW(name, id, extra) \
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::debug::TraceLog::AddTraceEventEtw( \
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TRACE_EVENT_PHASE_BEGIN, \
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name, reinterpret_cast<const void*>(id), extra)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACE_EVENT_END_ETW(name, id, extra) \
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::debug::TraceLog::AddTraceEventEtw( \
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TRACE_EVENT_PHASE_END, \
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name, reinterpret_cast<const void*>(id), extra)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACE_EVENT_INSTANT_ETW(name, id, extra) \
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::debug::TraceLog::AddTraceEventEtw( \
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TRACE_EVENT_PHASE_INSTANT, \
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name, reinterpret_cast<const void*>(id), extra)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type>
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct StaticMemorySingletonTraits;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WaitableEvent;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace debug {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// class must implement this interface.
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ConvertableToTraceFormat {
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~ConvertableToTraceFormat() {}
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Append the class info to the provided |out| string. The appended
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // data must be a valid JSON object. Strings must be propertly quoted, and
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // escaped. There is no processing applied to the content after it is
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // appended.
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void AppendAsTraceFormat(std::string* out) const = 0;
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTraceMaxNumArgs = 2;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Output records are "Events" and can be obtained via the
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OutputCallback whenever the tracing system decides to flush. This
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can happen at any time, on any thread, or you can programatically
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// force it to happen.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT TraceEvent {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  union TraceValue {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool as_bool;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long long as_uint;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    long long as_int;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double as_double;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const void* as_pointer;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* as_string;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceEvent();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceEvent(int thread_id,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             TimeTicks timestamp,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             char phase,
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             const unsigned char* category_group_enabled,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             const char* name,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             unsigned long long id,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             int num_args,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             const char** arg_names,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             const unsigned char* arg_types,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             const unsigned long long* arg_values,
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             scoped_ptr<ConvertableToTraceFormat> convertable_values[],
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             unsigned char flags);
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceEvent(const TraceEvent& other);
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceEvent& operator=(const TraceEvent& other);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~TraceEvent();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize event data to JSON
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void AppendEventsAsJSON(const std::vector<TraceEvent>& events,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 size_t start,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 size_t count,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 std::string* out);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AppendAsJSON(std::string* out) const;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void AppendValueAsJSON(unsigned char type,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                TraceValue value,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                std::string* out);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks timestamp() const { return timestamp_; }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Exposed for unittesting:
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::RefCountedString* parameter_copy_storage() const {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return parameter_copy_storage_.get();
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const unsigned char* category_group_enabled() const {
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return category_group_enabled_;
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* name() const { return name_; }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: these are ordered by size (largest first) for optimal packing.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks timestamp_;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // id_ can be used to store phase-specific data.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned long long id_;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceValue arg_values_[kTraceMaxNumArgs];
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* arg_names_[kTraceMaxNumArgs];
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<ConvertableToTraceFormat> convertable_values_[kTraceMaxNumArgs];
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const unsigned char* category_group_enabled_;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* name_;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::RefCountedString> parameter_copy_storage_;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int thread_id_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char phase_;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char flags_;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char arg_types_[kTraceMaxNumArgs];
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TraceBuffer holds the events as they are collected.
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BASE_EXPORT TraceBuffer {
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TraceBuffer() {}
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddEvent(const TraceEvent& event) = 0;
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool HasMoreEvents() const = 0;
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual const TraceEvent& NextEvent() = 0;
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool IsFull() const = 0;
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual size_t CountEnabledByName(const unsigned char* category,
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const std::string& event_name) const = 0;
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual size_t Size() const = 0;
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual const TraceEvent& GetEventAt(size_t index) const = 0;
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TraceResultBuffer collects and converts trace fragments returned by TraceLog
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to JSON output.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT TraceResultBuffer {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(const std::string&)> OutputCallback;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If you don't need to stream JSON chunks out efficiently, and just want to
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // get a complete JSON string after calling Finish, use this struct to collect
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // JSON trace output.
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct BASE_EXPORT SimpleOutput {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OutputCallback GetCallback();
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void Append(const std::string& json_string);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Do what you want with the json_output_ string after calling
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TraceResultBuffer::Finish.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string json_output;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceResultBuffer();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~TraceResultBuffer();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set callback. The callback will be called during Start with the initial
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // JSON output and during AddFragment and Finish with following JSON output
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // chunks. The callback target must live past the last calls to
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TraceResultBuffer::Start/AddFragment/Finish.
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetOutputCallback(const OutputCallback& json_chunk_callback);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start JSON output. This resets all internal state, so you can reuse
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the TraceResultBuffer by calling Start.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Start();
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call AddFragment 0 or more times to add trace fragments from TraceLog.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddFragment(const std::string& trace_fragment);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When all fragments have been added, call Finish to complete the JSON
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // formatted output.
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Finish();
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OutputCallback output_callback_;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool append_comma_;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class BASE_EXPORT CategoryFilter {
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The default category filter, used when none is provided.
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Allows all categories through, except if they end in the suffix 'Debug' or
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // 'Test'.
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static const char* kDefaultCategoryFilterString;
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // |filter_string| is a comma-delimited list of category wildcards.
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // A category can have an optional '-' prefix to make it an excluded category.
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // All the same rules apply above, so for example, having both included and
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // excluded categories in the same list would not be supported.
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Example: CategoryFilter"test_MyTest*");
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Example: CategoryFilter("test_MyTest*,test_OtherStuff");
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Example: CategoryFilter("-excluded_category1,-excluded_category2");
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Example: CategoryFilter("-*,webkit"); would disable everything but webkit.
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Example: CategoryFilter("-webkit"); would enable everything but webkit.
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit CategoryFilter(const std::string& filter_string);
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CategoryFilter(const CategoryFilter& cf);
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ~CategoryFilter();
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CategoryFilter& operator=(const CategoryFilter& rhs);
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Writes the string representation of the CategoryFilter. This is a comma
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // separated string, similar in nature to the one used to determine
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // enabled/disabled category patterns, except here there is an arbitrary
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // order, included categories go first, then excluded categories. Excluded
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // categories are distinguished from included categories by the prefix '-'.
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string ToString() const;
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Determines whether category group would be enabled or
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // disabled by this category filter.
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool IsCategoryGroupEnabled(const char* category_group) const;
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Merges nested_filter with the current CategoryFilter
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Merge(const CategoryFilter& nested_filter);
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Determines whether or not we have explicitly allowed category patterns.
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool HasIncludedPatterns() const;
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Clears both included/excluded pattern lists. This would be equivalent to
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // creating a CategoryFilter with an empty string, through the constructor.
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // i.e: CategoryFilter("").
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // When using an empty filter, all categories are considered included as we
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // are not excluding anything.
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Clear();
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static bool IsEmptyOrContainsLeadingOrTrailingWhitespace(
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& str);
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Initialize(const std::string& filter_string);
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void WriteString(std::string* out, bool included) const;
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<std::string> included_;
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<std::string> excluded_;
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TraceSamplingThread;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT TraceLog {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notification is a mask of one or more of the following events.
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum Notification {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The trace buffer does not flush dynamically, so when it fills up,
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // subsequent trace events will be dropped. This callback is generated when
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the trace buffer is full. The callback must be thread safe.
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TRACE_BUFFER_FULL = 1 << 0,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A subscribed trace-event occurred.
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EVENT_WATCH_NOTIFICATION = 1 << 1
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Options determines how the trace buffer stores data.
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum Options {
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Record until the trace buffer is full.
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RECORD_UNTIL_FULL = 1 << 0,
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Record until the user ends the trace. The trace buffer is a fixed size
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // and we use it as a ring buffer during recording.
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RECORD_CONTINUOUSLY = 1 << 1,
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Enable the sampling profiler.
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ENABLE_SAMPLING = 1 << 2,
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Echo to VLOG. Events are discared.
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ECHO_TO_VLOG = 1 << 3
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static TraceLog* GetInstance();
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Convert the given string to trace options. Defaults to RECORD_UNTIL_FULL if
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the string does not provide valid options.
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static Options TraceOptionsFromString(const std::string& str);
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Get set of known category groups. This can change as new code paths are
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // reached. The known category groups are inserted into |category_groups|.
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void GetKnownCategoryGroups(std::vector<std::string>* category_groups);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Retrieves the current CategoryFilter.
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const CategoryFilter& GetCurrentCategoryFilter();
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Options trace_options() const { return trace_options_; }
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Enables tracing. See CategoryFilter comments for details
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // on how to control what categories will be traced.
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void SetEnabled(const CategoryFilter& category_filter, Options options);
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disable tracing for all categories.
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetDisabled();
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsEnabled() { return !!enable_count_; }
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID)
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StartATrace();
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StopATrace();
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enabled state listeners give a callback when tracing is enabled or
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // disabled. This can be used to tie into other library's tracing systems
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on-demand.
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class EnabledStateChangedObserver {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Called just before the tracing system becomes
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // enabled. TraceLog::IsEnabled will return false at this point and trace
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // macros and methods called within the observer will deadlock.
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnTraceLogWillEnable() { }
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Called just before the tracing system disables. TraceLog::IsEnabled is
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // still false at this point TRACE macros will still be capturing
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // data. However, trace macros and methods called within the observer will
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // deadlock.
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnTraceLogWillDisable() { }
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddEnabledStateObserver(EnabledStateChangedObserver* listener);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RemoveEnabledStateObserver(EnabledStateChangedObserver* listener);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float GetBufferPercentFull() const;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the thread-safe notification callback. The callback can occur at any
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // time and from any thread. WARNING: It is possible for the previously set
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // callback to be called during OR AFTER a call to SetNotificationCallback.
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Therefore, the target of the callback must either be a global function,
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ref-counted object or a LazyInstance with Leaky traits (or equivalent).
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(int)> NotificationCallback;
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetNotificationCallback(const NotificationCallback& cb);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Not using base::Callback because of its limited by 7 parameteters.
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Also, using primitive type allows directly passsing callback from WebCore.
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WARNING: It is possible for the previously set callback to be called
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // after a call to SetEventCallback() that replaces or clears the callback.
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This callback may be invoked on any thread.
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef void (*EventCallback)(char phase,
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                const unsigned char* category_group_enabled,
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const char* name,
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                unsigned long long id,
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                int num_args,
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const char* const arg_names[],
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const unsigned char arg_types[],
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const unsigned long long arg_values[],
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                unsigned char flags);
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetEventCallback(EventCallback cb);
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Flush all collected events to the given output callback. The callback will
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be called one or more times with IPC-bite-size chunks. The string format is
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // undefined. Use TraceResultBuffer to convert one or more trace strings to
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // JSON.
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)>
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OutputCallback;
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Flush(const OutputCallback& cb);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called by TRACE_EVENT* macros, don't call this directly.
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The name parameter is a category group for example:
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent")
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static const unsigned char* GetCategoryGroupEnabled(const char* name);
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static const char* GetCategoryGroupName(
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const unsigned char* category_group_enabled);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called by TRACE_EVENT* macros, don't call this directly.
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above.
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddTraceEvent(char phase,
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                     const unsigned char* category_group_enabled,
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                     const char* category_group,
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     unsigned long long id,
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     int num_args,
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const char** arg_names,
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const unsigned char* arg_types,
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const unsigned long long* arg_values,
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                     scoped_ptr<ConvertableToTraceFormat> convertable_values[],
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     unsigned char flags);
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddTraceEventWithThreadIdAndTimestamp(
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      char phase,
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const unsigned char* category_group_enabled,
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const char* name,
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      unsigned long long id,
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int thread_id,
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const TimeTicks& timestamp,
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int num_args,
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const char** arg_names,
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const unsigned char* arg_types,
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const unsigned long long* arg_values,
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scoped_ptr<ConvertableToTraceFormat> convertable_values[],
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      unsigned char flags);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void AddTraceEventEtw(char phase,
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               const char* category_group,
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const void* id,
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const char* extra);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void AddTraceEventEtw(char phase,
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               const char* category_group,
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const void* id,
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const std::string& extra);
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For every matching event, a notification will be fired. NOTE: the
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notification will fire for each matching event that has already occurred
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since tracing was started (including before tracing if the process was
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // started with tracing turned on).
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetWatchEvent(const std::string& category_name,
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const std::string& event_name);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancel the watch event. If tracing is enabled, this may race with the
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // watch event notification firing.
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CancelWatchEvent();
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int process_id() const { return process_id_; }
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Exposed for unittesting:
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void InstallWaitableEventForSamplingTesting(WaitableEvent* waitable_event);
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allows deleting our singleton instance.
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void DeleteForTesting();
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allows resurrecting our singleton instance post-AtExit processing.
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Resurrect();
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allow tests to inspect TraceEvents.
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t GetEventsSize() const { return logged_events_->Size(); }
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TraceEvent& GetEventAt(size_t index) const {
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return logged_events_->GetEventAt(index);
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetProcessID(int process_id);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Allow setting an offset between the current TimeTicks time and the time
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that should be reported.
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetTimeOffset(TimeDelta offset);
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This allows constructor and destructor to be private and usable only
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // by the Singleton class.
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend struct StaticMemorySingletonTraits<TraceLog>;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Enable/disable each category group based on the current category_filter_.
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If the category group contains a category that matches an included category
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pattern, that category group will be enabled.
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void EnableIncludedCategoryGroups();
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void EnableIncludedCategoryGroup(int category_index);
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The pointer returned from GetCategoryGroupEnabledInternal() points to a
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // value with zero or more of the following bits. Used in this class only.
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The TRACE_EVENT macros should only use the value as a bool.
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum CategoryEnabledFlags {
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Normal enabled flag for categories enabled with Enable().
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CATEGORY_ENABLED = 1 << 0,
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // On Android if ATrace is enabled, all categories will have this bit.
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Not used on other platforms.
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ATRACE_ENABLED = 1 << 1
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper class for managing notification_thread_count_ and running
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notification callbacks. This is very similar to a reader-writer lock, but
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // shares the lock with TraceLog and manages the notification flags.
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class NotificationHelper {
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inline explicit NotificationHelper(TraceLog* trace_log);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inline ~NotificationHelper();
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Called only while TraceLog::lock_ is held. This ORs the given
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // notification with any existing notifcations.
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inline void AddNotificationWhileLocked(int notification);
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Called only while TraceLog::lock_ is NOT held. If there are any pending
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // notifications from previous calls to AddNotificationWhileLocked, this
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // will call the NotificationCallback.
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inline void SendNotificationIfAny();
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TraceLog* trace_log_;
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotificationCallback callback_copy_;
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int notification_;
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceLog();
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~TraceLog();
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const unsigned char* GetCategoryGroupEnabledInternal(const char* name);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddThreadNameMetadataEvents();
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SendToATrace(char phase,
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    const char* category_group,
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const char* name,
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    unsigned long long id,
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int num_args,
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const char** arg_names,
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const unsigned char* arg_types,
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const unsigned long long* arg_values,
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    unsigned char flags);
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static void ApplyATraceEnabledFlag(unsigned char* category_group_enabled);
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TraceBuffer* GetTraceBuffer();
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(nduca): switch to per-thread trace buffers to reduce thread
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // synchronization.
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This lock protects TraceLog member accesses from arbitrary threads.
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Lock lock_;
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int enable_count_;
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotificationCallback notification_callback_;
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<TraceBuffer> logged_events_;
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCallback event_callback_;
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool dispatching_to_observer_list_;
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObserverList<EnabledStateChangedObserver> enabled_state_observer_list_;
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::hash_map<int, std::string> thread_names_;
522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_;
523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::hash_map<std::string, int> thread_colors_;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // XORed with TraceID to make it unlikely to collide with other processes.
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned long long process_id_hash_;
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int process_id_;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TimeDelta time_offset_;
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allow tests to wake up when certain events occur.
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char* watch_category_;
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string watch_event_name_;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Options trace_options_;
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sampling thread handles.
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<TraceSamplingThread> sampling_thread_;
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PlatformThreadHandle sampling_thread_handle_;
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CategoryFilter category_filter_;
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TraceLog);
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace debug
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_DEBUG_TRACE_EVENT_IMPL_H_
551