10d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// Copyright 2015 The Chromium Authors. All rights reserved.
20d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// Use of this source code is governed by a BSD-style license that can be
30d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// found in the LICENSE file.
40d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
50d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#ifndef BASE_TRACE_EVENT_TRACE_LOG_H_
60d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#define BASE_TRACE_EVENT_TRACE_LOG_H_
70d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
80d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include <stddef.h>
90d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include <stdint.h>
100d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1194ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez#include <memory>
120d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include <string>
130d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include <vector>
140d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
150d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/atomicops.h"
160d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/containers/hash_tables.h"
170d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/gtest_prod_util.h"
180d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/macros.h"
190d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/memory/scoped_vector.h"
200d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/trace_event/memory_dump_provider.h"
210d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/trace_event/trace_config.h"
220d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/trace_event/trace_event_impl.h"
230d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "build/build_config.h"
240d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
250d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkonamespace base {
260d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
270d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotemplate <typename Type>
280d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkostruct DefaultSingletonTraits;
293a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelliclass MessageLoop;
300d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass RefCountedString;
310d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
320d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkonamespace trace_event {
330d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
343a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civellistruct TraceCategory;
350d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass TraceBuffer;
360d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass TraceBufferChunk;
370d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass TraceEvent;
383a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelliclass TraceEventFilter;
390d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass TraceEventMemoryOverhead;
400d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
410d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkostruct BASE_EXPORT TraceLogStatus {
420d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TraceLogStatus();
430d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  ~TraceLogStatus();
4445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  uint32_t event_capacity;
4545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  uint32_t event_count;
460d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko};
470d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
480d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass BASE_EXPORT TraceLog : public MemoryDumpProvider {
490d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko public:
503a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // Argument passed to TraceLog::SetEnabled.
513a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  enum Mode : uint8_t {
523a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli    // Enables normal tracing (recording trace events in the trace buffer).
533a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli    RECORDING_MODE = 1 << 0,
543a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli
553a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli    // Trace events are enabled just for filtering but not for recording. Only
563a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli    // event filters config of |trace_config| argument is used.
573a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli    FILTERING_MODE = 1 << 1
580d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  };
590d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
600d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  static TraceLog* GetInstance();
610d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
620d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Get set of known category groups. This can change as new code paths are
630d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // reached. The known category groups are inserted into |category_groups|.
640d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void GetKnownCategoryGroups(std::vector<std::string>* category_groups);
650d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
660d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Retrieves a copy (for thread-safety) of the current TraceConfig.
670d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TraceConfig GetCurrentTraceConfig() const;
680d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
690d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Initializes the thread-local event buffer, if not already initialized and
700d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // if the current thread supports that (has a message loop).
710d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void InitializeThreadLocalEventBufferIfSupported();
720d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
733a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // See TraceConfig comments for details on how to control which categories
743a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // will be traced. SetDisabled must be called distinctly for each mode that is
753a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // enabled. If tracing has already been enabled for recording, category filter
763a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // (enabled and disabled categories) will be merged into the current category
773a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // filter. Enabling RECORDING_MODE does not enable filters. Trace event
783a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // filters will be used only if FILTERING_MODE is set on |modes_to_enable|.
793a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // Conversely to RECORDING_MODE, FILTERING_MODE doesn't support upgrading,
803a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // i.e. filters can only be enabled if not previously enabled.
813a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  void SetEnabled(const TraceConfig& trace_config, uint8_t modes_to_enable);
823a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli
833a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // TODO(ssid): Remove the default SetEnabled and IsEnabled. They should take
843a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // Mode as argument.
853a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli
863a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // Disables tracing for all categories for the specified |modes_to_disable|
873a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // only. Only RECORDING_MODE is taken as default |modes_to_disable|.
88e5b2c6fa6f923f3a2f66346c2f169d9f0fceb3dcLuis Hector Chavez  void SetDisabled();
893a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  void SetDisabled(uint8_t modes_to_disable);
900601274935e7f632eb0d6ce0fd223b744349d20bJay Civelli
913a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // Returns true if TraceLog is enabled on recording mode.
923a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // Note: Returns false even if FILTERING_MODE is enabled.
933a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  bool IsEnabled() { return enabled_modes_ & RECORDING_MODE; }
943a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli
953a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // Returns a bitmap of enabled modes from TraceLog::Mode.
963a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  uint8_t enabled_modes() { return enabled_modes_; }
970d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
980d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // The number of times we have begun recording traces. If tracing is off,
990d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // returns -1. If tracing is on, then it returns the number of times we have
1000d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // recorded a trace. By watching for this number to increment, you can
1010d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // passively discover when a new trace has begun. This is then used to
1020d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // implement the TRACE_EVENT_IS_NEW_TRACE() primitive.
1030d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  int GetNumTracesRecorded();
1040d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1050d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#if defined(OS_ANDROID)
1060d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void StartATrace();
1070d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void StopATrace();
1080d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void AddClockSyncMetadataEvent();
1090d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#endif
1100d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1110d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Enabled state listeners give a callback when tracing is enabled or
1120d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // disabled. This can be used to tie into other library's tracing systems
1130d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // on-demand.
1140d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  class BASE_EXPORT EnabledStateObserver {
1150d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko   public:
1160d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    virtual ~EnabledStateObserver() = default;
1170d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1180d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    // Called just after the tracing system becomes enabled, outside of the
1190d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    // |lock_|. TraceLog::IsEnabled() is true at this point.
1200d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    virtual void OnTraceLogEnabled() = 0;
1210d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1220d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    // Called just after the tracing system disables, outside of the |lock_|.
1230d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    // TraceLog::IsEnabled() is false at this point.
1240d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    virtual void OnTraceLogDisabled() = 0;
1250d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  };
1260d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void AddEnabledStateObserver(EnabledStateObserver* listener);
1270d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void RemoveEnabledStateObserver(EnabledStateObserver* listener);
1280d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool HasEnabledStateObserver(EnabledStateObserver* listener) const;
1290d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
13094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  // Asynchronous enabled state listeners. When tracing is enabled or disabled,
13194ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  // for each observer, a task for invoking its appropriate callback is posted
13294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  // to the thread from which AddAsyncEnabledStateObserver() was called. This
13394ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  // allows the observer to be safely destroyed, provided that it happens on the
13494ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  // same thread that invoked AddAsyncEnabledStateObserver().
13594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  class BASE_EXPORT AsyncEnabledStateObserver {
13694ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez   public:
13794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez    virtual ~AsyncEnabledStateObserver() = default;
13894ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
13994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez    // Posted just after the tracing system becomes enabled, outside |lock_|.
14094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez    // TraceLog::IsEnabled() is true at this point.
14194ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez    virtual void OnTraceLogEnabled() = 0;
14294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
14394ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez    // Posted just after the tracing system becomes disabled, outside |lock_|.
14494ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez    // TraceLog::IsEnabled() is false at this point.
14594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez    virtual void OnTraceLogDisabled() = 0;
14694ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  };
14794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  void AddAsyncEnabledStateObserver(
14894ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez      WeakPtr<AsyncEnabledStateObserver> listener);
14994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  void RemoveAsyncEnabledStateObserver(AsyncEnabledStateObserver* listener);
15094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  bool HasAsyncEnabledStateObserver(AsyncEnabledStateObserver* listener) const;
15194ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
1520d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TraceLogStatus GetStatus() const;
1530d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool BufferIsFull() const;
1540d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1550d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Computes an estimate of the size of the TraceLog including all the retained
1560d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // objects.
1570d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead);
1580d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1590d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void SetArgumentFilterPredicate(
1600d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const ArgumentFilterPredicate& argument_filter_predicate);
1610d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1620d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Flush all collected events to the given output callback. The callback will
1630d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // be called one or more times either synchronously or asynchronously from
1640d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // the current thread with IPC-bite-size chunks. The string format is
1650d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // undefined. Use TraceResultBuffer to convert one or more trace strings to
1660d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // JSON. The callback can be null if the caller doesn't want any data.
1670d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Due to the implementation of thread-local buffers, flush can't be
1680d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // done when tracing is enabled. If called when tracing is enabled, the
1690d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // callback will be called directly with (empty_string, false) to indicate
1700d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // the end of this unsuccessful flush. Flush does the serialization
1710d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // on the same thread if the caller doesn't set use_worker_thread explicitly.
1720d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&,
1730d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                              bool has_more_events)> OutputCallback;
1740d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void Flush(const OutputCallback& cb, bool use_worker_thread = false);
1750d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1760d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Cancels tracing and discards collected data.
1770d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void CancelTracing(const OutputCallback& cb);
1780d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1790d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Called by TRACE_EVENT* macros, don't call this directly.
1800d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // The name parameter is a category group for example:
1810d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent")
1820d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  static const unsigned char* GetCategoryGroupEnabled(const char* name);
1830d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  static const char* GetCategoryGroupName(
1840d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const unsigned char* category_group_enabled);
1850d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1860d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Called by TRACE_EVENT* macros, don't call this directly.
1870d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied
1880d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above.
1890d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TraceEventHandle AddTraceEvent(
1900d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      char phase,
1910d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const unsigned char* category_group_enabled,
1920d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const char* name,
19345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko      const char* scope,
1940d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      unsigned long long id,
1950d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      int num_args,
1960d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const char** arg_names,
1970d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const unsigned char* arg_types,
1980d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const unsigned long long* arg_values,
19994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez      std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
2000d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      unsigned int flags);
2010d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TraceEventHandle AddTraceEventWithBindId(
2020d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      char phase,
2030d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const unsigned char* category_group_enabled,
2040d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const char* name,
20545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko      const char* scope,
2060d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      unsigned long long id,
2070d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      unsigned long long bind_id,
2080d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      int num_args,
2090d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const char** arg_names,
2100d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const unsigned char* arg_types,
2110d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const unsigned long long* arg_values,
21294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez      std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
2130d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      unsigned int flags);
2140d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TraceEventHandle AddTraceEventWithProcessId(
2150d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      char phase,
2160d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const unsigned char* category_group_enabled,
2170d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const char* name,
21845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko      const char* scope,
2190d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      unsigned long long id,
2200d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      int process_id,
2210d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      int num_args,
2220d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const char** arg_names,
2230d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const unsigned char* arg_types,
2240d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const unsigned long long* arg_values,
22594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez      std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
2260d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      unsigned int flags);
2270d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TraceEventHandle AddTraceEventWithThreadIdAndTimestamp(
2280d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      char phase,
2290d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const unsigned char* category_group_enabled,
2300d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const char* name,
23145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko      const char* scope,
2320d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      unsigned long long id,
2330d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      int thread_id,
2340d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const TimeTicks& timestamp,
2350d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      int num_args,
2360d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const char** arg_names,
2370d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const unsigned char* arg_types,
2380d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const unsigned long long* arg_values,
23994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez      std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
2400d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      unsigned int flags);
2410d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TraceEventHandle AddTraceEventWithThreadIdAndTimestamp(
2420d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      char phase,
2430d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const unsigned char* category_group_enabled,
2440d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const char* name,
24545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko      const char* scope,
2460d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      unsigned long long id,
2470d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      unsigned long long bind_id,
2480d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      int thread_id,
2490d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const TimeTicks& timestamp,
2500d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      int num_args,
2510d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const char** arg_names,
2520d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const unsigned char* arg_types,
2530d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const unsigned long long* arg_values,
25494ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez      std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
2550d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      unsigned int flags);
2560d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2570d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Adds a metadata event that will be written when the trace log is flushed.
2580d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void AddMetadataEvent(
25945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko      const unsigned char* category_group_enabled,
2600d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const char* name,
2610d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      int num_args,
2620d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const char** arg_names,
2630d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const unsigned char* arg_types,
2640d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const unsigned long long* arg_values,
26594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez      std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
2660d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      unsigned int flags);
2670d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2680d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void UpdateTraceEventDuration(const unsigned char* category_group_enabled,
2690d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                                const char* name,
2700d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                                TraceEventHandle handle);
2710d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2723a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  void EndFilteredEvent(const unsigned char* category_group_enabled,
2733a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli                        const char* name,
2743a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli                        TraceEventHandle handle);
2750d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2760d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  int process_id() const { return process_id_; }
2770d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2780d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  uint64_t MangleEventId(uint64_t id);
2790d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2800d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Exposed for unittesting:
2810d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2823a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // Testing factory for TraceEventFilter.
2833a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  typedef std::unique_ptr<TraceEventFilter> (*FilterFactoryForTesting)(
2843a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli      const std::string& /* predicate_name */);
2853a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  void SetFilterFactoryForTesting(FilterFactoryForTesting factory) {
2863a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli    filter_factory_for_testing_ = factory;
2873a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  }
2880d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2890d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Allows deleting our singleton instance.
2900d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  static void DeleteForTesting();
2910d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2920d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Allow tests to inspect TraceEvents.
2930d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TraceEvent* GetEventByHandle(TraceEventHandle handle);
2940d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2950d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void SetProcessID(int process_id);
2960d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2970d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Process sort indices, if set, override the order of a process will appear
2980d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // relative to other processes in the trace viewer. Processes are sorted first
2990d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // on their sort index, ascending, then by their name, and then tid.
3000d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void SetProcessSortIndex(int sort_index);
3010d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3023a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // Sets the name of the process. |process_name| should be a string literal
3033a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // since it is a whitelisted argument for background field trials.
3043a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  void SetProcessName(const char* process_name);
3050d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3060d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Processes can have labels in addition to their names. Use labels, for
3070d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // instance, to list out the web page titles that a process is handling.
3080d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void UpdateProcessLabel(int label_id, const std::string& current_label);
3090d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void RemoveProcessLabel(int label_id);
3100d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3110d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Thread sort indices, if set, override the order of a thread will appear
3120d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // within its process in the trace viewer. Threads are sorted first on their
3130d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // sort index, ascending, then by their name, and then tid.
3140d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void SetThreadSortIndex(PlatformThreadId thread_id, int sort_index);
3150d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3160d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Allow setting an offset between the current TimeTicks time and the time
3170d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // that should be reported.
3180d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void SetTimeOffset(TimeDelta offset);
3190d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3200d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  size_t GetObserverCountForTest() const;
3210d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3220d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Call this method if the current thread may block the message loop to
3230d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // prevent the thread from using the thread-local buffer because the thread
3240d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // may not handle the flush request in time causing lost of unflushed events.
3250d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void SetCurrentThreadBlocksMessageLoop();
3260d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3270d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#if defined(OS_WIN)
3280d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // This function is called by the ETW exporting module whenever the ETW
3290d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // keyword (flags) changes. This keyword indicates which categories should be
3300d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // exported, so whenever it changes, we adjust accordingly.
3310d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void UpdateETWCategoryGroupEnabledFlags();
3320d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#endif
3330d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3340d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko private:
3350d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  typedef unsigned int InternalTraceOptions;
3360d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3370d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
3380d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                           TraceBufferRingBufferGetReturnChunk);
3390d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
3400d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                           TraceBufferRingBufferHalfIteration);
3410d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
3420d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                           TraceBufferRingBufferFullIteration);
3430d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, TraceBufferVectorReportFull);
3440d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
3450d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                           ConvertTraceConfigToInternalOptions);
3460d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
3470d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                           TraceRecordAsMuchAsPossibleMode);
3480d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3490d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // This allows constructor and destructor to be private and usable only
3500d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // by the Singleton class.
3510d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  friend struct DefaultSingletonTraits<TraceLog>;
3520d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3530d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // MemoryDumpProvider implementation.
3540d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool OnMemoryDump(const MemoryDumpArgs& args,
3550d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                    ProcessMemoryDump* pmd) override;
3560d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3570d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Enable/disable each category group based on the current mode_,
3583a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // category_filter_ and event_filters_enabled_.
3593a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // Enable the category group in the recording mode if category_filter_ matches
3603a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // the category group, is not null. Enable category for filtering if any
3613a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  // filter in event_filters_enabled_ enables it.
3623a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  void UpdateCategoryRegistry();
3633a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  void UpdateCategoryState(TraceCategory* category);
3643a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli
3653a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  void CreateFiltersForTraceConfig();
3660d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3670d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Configure synthetic delays based on the values set in the current
3680d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // trace config.
3690d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void UpdateSyntheticDelaysFromTraceConfig();
3700d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3710d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  InternalTraceOptions GetInternalOptionsFromTraceConfig(
3720d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const TraceConfig& config);
3730d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3740d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  class ThreadLocalEventBuffer;
3750d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  class OptionalAutoLock;
37694ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  struct RegisteredAsyncObserver;
3770d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3780d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TraceLog();
3790d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  ~TraceLog() override;
3800d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void AddMetadataEventsWhileLocked();
3810d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3820d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  InternalTraceOptions trace_options() const {
3830d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    return static_cast<InternalTraceOptions>(
3840d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        subtle::NoBarrier_Load(&trace_options_));
3850d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
3860d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3870d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TraceBuffer* trace_buffer() const { return logged_events_.get(); }
3880d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TraceBuffer* CreateTraceBuffer();
3890d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3900d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  std::string EventToConsoleMessage(unsigned char phase,
3910d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                                    const TimeTicks& timestamp,
3920d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                                    TraceEvent* trace_event);
3930d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3940d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TraceEvent* AddEventToThreadSharedChunkWhileLocked(TraceEventHandle* handle,
3950d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                                                     bool check_buffer_is_full);
3960d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void CheckIfBufferIsFullWhileLocked();
3973a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  void SetDisabledWhileLocked(uint8_t modes);
3980d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3990d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TraceEvent* GetEventByHandleInternal(TraceEventHandle handle,
4000d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                                       OptionalAutoLock* lock);
4010d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4020d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void FlushInternal(const OutputCallback& cb,
4030d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                     bool use_worker_thread,
4040d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                     bool discard_events);
4050d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4060d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // |generation| is used in the following callbacks to check if the callback
4070d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // is called for the flush of the current |logged_events_|.
4080d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void FlushCurrentThread(int generation, bool discard_events);
4090d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Usually it runs on a different thread.
4100d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  static void ConvertTraceEventsToTraceFormat(
41194ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez      std::unique_ptr<TraceBuffer> logged_events,
4120d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const TraceLog::OutputCallback& flush_output_callback,
4130d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const ArgumentFilterPredicate& argument_filter_predicate);
4140d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void FinishFlush(int generation, bool discard_events);
4150d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void OnFlushTimeout(int generation, bool discard_events);
4160d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4170d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  int generation() const {
4180d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    return static_cast<int>(subtle::NoBarrier_Load(&generation_));
4190d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
4200d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool CheckGeneration(int generation) const {
4210d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    return generation == this->generation();
4220d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
4230d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void UseNextTraceBuffer();
4240d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4250d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TimeTicks OffsetNow() const { return OffsetTimestamp(TimeTicks::Now()); }
4260d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TimeTicks OffsetTimestamp(const TimeTicks& timestamp) const {
4270d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    return timestamp - time_offset_;
4280d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
4290d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4300d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Internal representation of trace options since we store the currently used
4310d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // trace option as an AtomicWord.
4320d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  static const InternalTraceOptions kInternalNone;
4330d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  static const InternalTraceOptions kInternalRecordUntilFull;
4340d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  static const InternalTraceOptions kInternalRecordContinuously;
4350d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  static const InternalTraceOptions kInternalEchoToConsole;
4360d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  static const InternalTraceOptions kInternalRecordAsMuchAsPossible;
4370d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  static const InternalTraceOptions kInternalEnableArgumentFilter;
4380d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4390d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // This lock protects TraceLog member accesses (except for members protected
4400d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // by thread_info_lock_) from arbitrary threads.
4410d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  mutable Lock lock_;
4420d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // This lock protects accesses to thread_names_, thread_event_start_times_
4430d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // and thread_colors_.
4440d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  Lock thread_info_lock_;
4453a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  uint8_t enabled_modes_;  // See TraceLog::Mode.
4460d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  int num_traces_recorded_;
44794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::unique_ptr<TraceBuffer> logged_events_;
44894ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::vector<std::unique_ptr<TraceEvent>> metadata_events_;
4490d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool dispatching_to_observer_list_;
4500d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  std::vector<EnabledStateObserver*> enabled_state_observer_list_;
45194ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::map<AsyncEnabledStateObserver*, RegisteredAsyncObserver>
45294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez      async_observers_;
4530d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4540d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  std::string process_name_;
4550d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  base::hash_map<int, std::string> process_labels_;
4560d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  int process_sort_index_;
4570d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  base::hash_map<int, int> thread_sort_indices_;
4580d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  base::hash_map<int, std::string> thread_names_;
4590d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4600d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // The following two maps are used only when ECHO_TO_CONSOLE.
4610d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  base::hash_map<int, std::stack<TimeTicks>> thread_event_start_times_;
4620d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  base::hash_map<std::string, int> thread_colors_;
4630d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4640d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TimeTicks buffer_limit_reached_timestamp_;
4650d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4660d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // XORed with TraceID to make it unlikely to collide with other processes.
4670d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  unsigned long long process_id_hash_;
4680d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4690d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  int process_id_;
4700d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4710d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TimeDelta time_offset_;
4720d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4730d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  subtle::AtomicWord /* Options */ trace_options_;
4740d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4750d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  TraceConfig trace_config_;
4763a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  TraceConfig::EventFilters enabled_event_filters_;
4770d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4780d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  ThreadLocalPointer<ThreadLocalEventBuffer> thread_local_event_buffer_;
4790d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  ThreadLocalBoolean thread_blocks_message_loop_;
4800d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  ThreadLocalBoolean thread_is_in_trace_event_;
4810d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4820d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Contains the message loops of threads that have had at least one event
4830d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // added into the local event buffer. Not using SingleThreadTaskRunner
4840d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // because we need to know the life time of the message loops.
4850d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  hash_set<MessageLoop*> thread_message_loops_;
4860d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4870d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // For events which can't be added into the thread local buffer, e.g. events
4880d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // from threads without a message loop.
48994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::unique_ptr<TraceBufferChunk> thread_shared_chunk_;
4900d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  size_t thread_shared_chunk_index_;
4910d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4920d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Set when asynchronous Flush is in progress.
4930d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  OutputCallback flush_output_callback_;
4940d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  scoped_refptr<SingleThreadTaskRunner> flush_task_runner_;
4950d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  ArgumentFilterPredicate argument_filter_predicate_;
4960d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  subtle::AtomicWord generation_;
4970d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool use_worker_thread_;
4980d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4993a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli  FilterFactoryForTesting filter_factory_for_testing_;
5003a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli
5010d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(TraceLog);
5020d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko};
5030d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
5040d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko}  // namespace trace_event
5050d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko}  // namespace base
5060d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
5070d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#endif  // BASE_TRACE_EVENT_TRACE_LOG_H_
508