• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 
6 #ifndef BASE_DEBUG_TRACE_EVENT_IMPL_H_
7 #define BASE_DEBUG_TRACE_EVENT_IMPL_H_
8 
9 #include <stack>
10 #include <string>
11 #include <vector>
12 
13 #include "base/atomicops.h"
14 #include "base/callback.h"
15 #include "base/containers/hash_tables.h"
16 #include "base/gtest_prod_util.h"
17 #include "base/memory/ref_counted_memory.h"
18 #include "base/memory/scoped_vector.h"
19 #include "base/observer_list.h"
20 #include "base/strings/string_util.h"
21 #include "base/synchronization/condition_variable.h"
22 #include "base/synchronization/lock.h"
23 #include "base/threading/thread.h"
24 #include "base/threading/thread_local.h"
25 #include "base/timer/timer.h"
26 
27 // Older style trace macros with explicit id and extra data
28 // Only these macros result in publishing data to ETW as currently implemented.
29 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \
30     base::debug::TraceLog::AddTraceEventEtw( \
31         TRACE_EVENT_PHASE_BEGIN, \
32         name, reinterpret_cast<const void*>(id), extra)
33 
34 #define TRACE_EVENT_END_ETW(name, id, extra) \
35     base::debug::TraceLog::AddTraceEventEtw( \
36         TRACE_EVENT_PHASE_END, \
37         name, reinterpret_cast<const void*>(id), extra)
38 
39 #define TRACE_EVENT_INSTANT_ETW(name, id, extra) \
40     base::debug::TraceLog::AddTraceEventEtw( \
41         TRACE_EVENT_PHASE_INSTANT, \
42         name, reinterpret_cast<const void*>(id), extra)
43 
44 template <typename Type>
45 struct DefaultSingletonTraits;
46 
47 #if defined(COMPILER_GCC)
48 namespace BASE_HASH_NAMESPACE {
49 template <>
50 struct hash<base::MessageLoop*> {
51   std::size_t operator()(base::MessageLoop* value) const {
52     return reinterpret_cast<std::size_t>(value);
53   }
54 };
55 }  // BASE_HASH_NAMESPACE
56 #endif
57 
58 namespace base {
59 
60 class WaitableEvent;
61 class MessageLoop;
62 
63 namespace debug {
64 
65 // For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided
66 // class must implement this interface.
67 class ConvertableToTraceFormat : public RefCounted<ConvertableToTraceFormat> {
68  public:
69   // Append the class info to the provided |out| string. The appended
70   // data must be a valid JSON object. Strings must be properly quoted, and
71   // escaped. There is no processing applied to the content after it is
72   // appended.
73   virtual void AppendAsTraceFormat(std::string* out) const = 0;
74 
75  protected:
76   virtual ~ConvertableToTraceFormat() {}
77 
78  private:
79   friend class RefCounted<ConvertableToTraceFormat>;
80 };
81 
82 struct TraceEventHandle {
83   uint32 chunk_seq;
84   uint16 chunk_index;
85   uint16 event_index;
86 };
87 
88 const int kTraceMaxNumArgs = 2;
89 
90 class BASE_EXPORT TraceEvent {
91  public:
92   union TraceValue {
93     bool as_bool;
94     unsigned long long as_uint;
95     long long as_int;
96     double as_double;
97     const void* as_pointer;
98     const char* as_string;
99   };
100 
101   TraceEvent();
102   ~TraceEvent();
103 
104   // We don't need to copy TraceEvent except when TraceEventBuffer is cloned.
105   // Use explicit copy method to avoid accidentally misuse of copy.
106   void CopyFrom(const TraceEvent& other);
107 
108   void Initialize(
109       int thread_id,
110       TimeTicks timestamp,
111       TimeTicks thread_timestamp,
112       char phase,
113       const unsigned char* category_group_enabled,
114       const char* name,
115       unsigned long long id,
116       int num_args,
117       const char** arg_names,
118       const unsigned char* arg_types,
119       const unsigned long long* arg_values,
120       const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
121       unsigned char flags);
122 
123   void Reset();
124 
125   void UpdateDuration(const TimeTicks& now, const TimeTicks& thread_now);
126 
127   // Serialize event data to JSON
128   void AppendAsJSON(std::string* out) const;
129   void AppendPrettyPrinted(std::ostringstream* out) const;
130 
131   static void AppendValueAsJSON(unsigned char type,
132                                 TraceValue value,
133                                 std::string* out);
134 
135   TimeTicks timestamp() const { return timestamp_; }
136   TimeTicks thread_timestamp() const { return thread_timestamp_; }
137   char phase() const { return phase_; }
138   int thread_id() const { return thread_id_; }
139   TimeDelta duration() const { return duration_; }
140   TimeDelta thread_duration() const { return thread_duration_; }
141   unsigned long long id() const { return id_; }
142   unsigned char flags() const { return flags_; }
143 
144   // Exposed for unittesting:
145 
146   const base::RefCountedString* parameter_copy_storage() const {
147     return parameter_copy_storage_.get();
148   }
149 
150   const unsigned char* category_group_enabled() const {
151     return category_group_enabled_;
152   }
153 
154   const char* name() const { return name_; }
155 
156 #if defined(OS_ANDROID)
157   void SendToATrace();
158 #endif
159 
160  private:
161   // Note: these are ordered by size (largest first) for optimal packing.
162   TimeTicks timestamp_;
163   TimeTicks thread_timestamp_;
164   TimeDelta duration_;
165   TimeDelta thread_duration_;
166   // id_ can be used to store phase-specific data.
167   unsigned long long id_;
168   TraceValue arg_values_[kTraceMaxNumArgs];
169   const char* arg_names_[kTraceMaxNumArgs];
170   scoped_refptr<ConvertableToTraceFormat> convertable_values_[kTraceMaxNumArgs];
171   const unsigned char* category_group_enabled_;
172   const char* name_;
173   scoped_refptr<base::RefCountedString> parameter_copy_storage_;
174   int thread_id_;
175   char phase_;
176   unsigned char flags_;
177   unsigned char arg_types_[kTraceMaxNumArgs];
178 
179   DISALLOW_COPY_AND_ASSIGN(TraceEvent);
180 };
181 
182 // TraceBufferChunk is the basic unit of TraceBuffer.
183 class BASE_EXPORT TraceBufferChunk {
184  public:
185   TraceBufferChunk(uint32 seq)
186       : next_free_(0),
187         seq_(seq) {
188   }
189 
190   void Reset(uint32 new_seq);
191   TraceEvent* AddTraceEvent(size_t* event_index);
192   bool IsFull() const { return next_free_ == kTraceBufferChunkSize; }
193 
194   uint32 seq() const { return seq_; }
195   size_t capacity() const { return kTraceBufferChunkSize; }
196   size_t size() const { return next_free_; }
197 
198   TraceEvent* GetEventAt(size_t index) {
199     DCHECK(index < size());
200     return &chunk_[index];
201   }
202   const TraceEvent* GetEventAt(size_t index) const {
203     DCHECK(index < size());
204     return &chunk_[index];
205   }
206 
207   scoped_ptr<TraceBufferChunk> Clone() const;
208 
209   static const size_t kTraceBufferChunkSize = 64;
210 
211  private:
212   size_t next_free_;
213   TraceEvent chunk_[kTraceBufferChunkSize];
214   uint32 seq_;
215 };
216 
217 // TraceBuffer holds the events as they are collected.
218 class BASE_EXPORT TraceBuffer {
219  public:
220   virtual ~TraceBuffer() {}
221 
222   virtual scoped_ptr<TraceBufferChunk> GetChunk(size_t *index) = 0;
223   virtual void ReturnChunk(size_t index,
224                            scoped_ptr<TraceBufferChunk> chunk) = 0;
225 
226   virtual bool IsFull() const = 0;
227   virtual size_t Size() const = 0;
228   virtual size_t Capacity() const = 0;
229   virtual TraceEvent* GetEventByHandle(TraceEventHandle handle) = 0;
230 
231   // For iteration. Each TraceBuffer can only be iterated once.
232   virtual const TraceBufferChunk* NextChunk() = 0;
233 
234   virtual scoped_ptr<TraceBuffer> CloneForIteration() const = 0;
235 };
236 
237 // TraceResultBuffer collects and converts trace fragments returned by TraceLog
238 // to JSON output.
239 class BASE_EXPORT TraceResultBuffer {
240  public:
241   typedef base::Callback<void(const std::string&)> OutputCallback;
242 
243   // If you don't need to stream JSON chunks out efficiently, and just want to
244   // get a complete JSON string after calling Finish, use this struct to collect
245   // JSON trace output.
246   struct BASE_EXPORT SimpleOutput {
247     OutputCallback GetCallback();
248     void Append(const std::string& json_string);
249 
250     // Do what you want with the json_output_ string after calling
251     // TraceResultBuffer::Finish.
252     std::string json_output;
253   };
254 
255   TraceResultBuffer();
256   ~TraceResultBuffer();
257 
258   // Set callback. The callback will be called during Start with the initial
259   // JSON output and during AddFragment and Finish with following JSON output
260   // chunks. The callback target must live past the last calls to
261   // TraceResultBuffer::Start/AddFragment/Finish.
262   void SetOutputCallback(const OutputCallback& json_chunk_callback);
263 
264   // Start JSON output. This resets all internal state, so you can reuse
265   // the TraceResultBuffer by calling Start.
266   void Start();
267 
268   // Call AddFragment 0 or more times to add trace fragments from TraceLog.
269   void AddFragment(const std::string& trace_fragment);
270 
271   // When all fragments have been added, call Finish to complete the JSON
272   // formatted output.
273   void Finish();
274 
275  private:
276   OutputCallback output_callback_;
277   bool append_comma_;
278 };
279 
280 class BASE_EXPORT CategoryFilter {
281  public:
282   typedef std::vector<std::string> StringList;
283 
284   // The default category filter, used when none is provided.
285   // Allows all categories through, except if they end in the suffix 'Debug' or
286   // 'Test'.
287   static const char* kDefaultCategoryFilterString;
288 
289   // |filter_string| is a comma-delimited list of category wildcards.
290   // A category can have an optional '-' prefix to make it an excluded category.
291   // All the same rules apply above, so for example, having both included and
292   // excluded categories in the same list would not be supported.
293   //
294   // Example: CategoryFilter"test_MyTest*");
295   // Example: CategoryFilter("test_MyTest*,test_OtherStuff");
296   // Example: CategoryFilter("-excluded_category1,-excluded_category2");
297   // Example: CategoryFilter("-*,webkit"); would disable everything but webkit.
298   // Example: CategoryFilter("-webkit"); would enable everything but webkit.
299   //
300   // Category filters can also be used to configure synthetic delays.
301   //
302   // Example: CategoryFilter("DELAY(gpu.PresentingFrame;16)"); would make swap
303   //          buffers always take at least 16 ms.
304   // Example: CategoryFilter("DELAY(gpu.PresentingFrame;16;oneshot)"); would
305   //          make swap buffers take at least 16 ms the first time it is
306   //          called.
307   // Example: CategoryFilter("DELAY(gpu.PresentingFrame;16;alternating)");
308   //          would make swap buffers take at least 16 ms every other time it
309   //          is called.
310   explicit CategoryFilter(const std::string& filter_string);
311 
312   CategoryFilter(const CategoryFilter& cf);
313 
314   ~CategoryFilter();
315 
316   CategoryFilter& operator=(const CategoryFilter& rhs);
317 
318   // Writes the string representation of the CategoryFilter. This is a comma
319   // separated string, similar in nature to the one used to determine
320   // enabled/disabled category patterns, except here there is an arbitrary
321   // order, included categories go first, then excluded categories. Excluded
322   // categories are distinguished from included categories by the prefix '-'.
323   std::string ToString() const;
324 
325   // Determines whether category group would be enabled or
326   // disabled by this category filter.
327   bool IsCategoryGroupEnabled(const char* category_group) const;
328 
329   // Return a list of the synthetic delays specified in this category filter.
330   const StringList& GetSyntheticDelayValues() const;
331 
332   // Merges nested_filter with the current CategoryFilter
333   void Merge(const CategoryFilter& nested_filter);
334 
335   // Clears both included/excluded pattern lists. This would be equivalent to
336   // creating a CategoryFilter with an empty string, through the constructor.
337   // i.e: CategoryFilter("").
338   //
339   // When using an empty filter, all categories are considered included as we
340   // are not excluding anything.
341   void Clear();
342 
343  private:
344   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, CategoryFilter);
345 
346   static bool IsEmptyOrContainsLeadingOrTrailingWhitespace(
347       const std::string& str);
348 
349   void Initialize(const std::string& filter_string);
350   void WriteString(const StringList& values,
351                    std::string* out,
352                    bool included) const;
353   void WriteString(const StringList& delays, std::string* out) const;
354   bool HasIncludedPatterns() const;
355 
356   bool DoesCategoryGroupContainCategory(const char* category_group,
357                                         const char* category) const;
358 
359   StringList included_;
360   StringList disabled_;
361   StringList excluded_;
362   StringList delays_;
363 };
364 
365 class TraceSamplingThread;
366 
367 class BASE_EXPORT TraceLog {
368  public:
369   enum Mode {
370     DISABLED = 0,
371     RECORDING_MODE,
372     MONITORING_MODE,
373   };
374 
375   // Options determines how the trace buffer stores data.
376   enum Options {
377     // Record until the trace buffer is full.
378     RECORD_UNTIL_FULL = 1 << 0,
379 
380     // Record until the user ends the trace. The trace buffer is a fixed size
381     // and we use it as a ring buffer during recording.
382     RECORD_CONTINUOUSLY = 1 << 1,
383 
384     // Enable the sampling profiler in the recording mode.
385     ENABLE_SAMPLING = 1 << 2,
386 
387     // Echo to console. Events are discarded.
388     ECHO_TO_CONSOLE = 1 << 3,
389   };
390 
391   // The pointer returned from GetCategoryGroupEnabledInternal() points to a
392   // value with zero or more of the following bits. Used in this class only.
393   // The TRACE_EVENT macros should only use the value as a bool.
394   // These values must be in sync with macro values in TraceEvent.h in Blink.
395   enum CategoryGroupEnabledFlags {
396     // Category group enabled for the recording mode.
397     ENABLED_FOR_RECORDING = 1 << 0,
398     // Category group enabled for the monitoring mode.
399     ENABLED_FOR_MONITORING = 1 << 1,
400     // Category group enabled by SetEventCallbackEnabled().
401     ENABLED_FOR_EVENT_CALLBACK = 1 << 2,
402   };
403 
404   static TraceLog* GetInstance();
405 
406   // Get set of known category groups. This can change as new code paths are
407   // reached. The known category groups are inserted into |category_groups|.
408   void GetKnownCategoryGroups(std::vector<std::string>* category_groups);
409 
410   // Retrieves a copy (for thread-safety) of the current CategoryFilter.
411   CategoryFilter GetCurrentCategoryFilter();
412 
413   Options trace_options() const {
414     return static_cast<Options>(subtle::NoBarrier_Load(&trace_options_));
415   }
416 
417   // Enables normal tracing (recording trace events in the trace buffer).
418   // See CategoryFilter comments for details on how to control what categories
419   // will be traced. If tracing has already been enabled, |category_filter| will
420   // be merged into the current category filter.
421   void SetEnabled(const CategoryFilter& category_filter,
422                   Mode mode, Options options);
423 
424   // Disables normal tracing for all categories.
425   void SetDisabled();
426 
427   bool IsEnabled() { return mode_ != DISABLED; }
428 
429   // The number of times we have begun recording traces. If tracing is off,
430   // returns -1. If tracing is on, then it returns the number of times we have
431   // recorded a trace. By watching for this number to increment, you can
432   // passively discover when a new trace has begun. This is then used to
433   // implement the TRACE_EVENT_IS_NEW_TRACE() primitive.
434   int GetNumTracesRecorded();
435 
436 #if defined(OS_ANDROID)
437   void StartATrace();
438   void StopATrace();
439   void AddClockSyncMetadataEvent();
440 #endif
441 
442   // Enabled state listeners give a callback when tracing is enabled or
443   // disabled. This can be used to tie into other library's tracing systems
444   // on-demand.
445   class EnabledStateObserver {
446    public:
447     // Called just after the tracing system becomes enabled, outside of the
448     // |lock_|. TraceLog::IsEnabled() is true at this point.
449     virtual void OnTraceLogEnabled() = 0;
450 
451     // Called just after the tracing system disables, outside of the |lock_|.
452     // TraceLog::IsEnabled() is false at this point.
453     virtual void OnTraceLogDisabled() = 0;
454   };
455   void AddEnabledStateObserver(EnabledStateObserver* listener);
456   void RemoveEnabledStateObserver(EnabledStateObserver* listener);
457   bool HasEnabledStateObserver(EnabledStateObserver* listener) const;
458 
459   float GetBufferPercentFull() const;
460   bool BufferIsFull() const;
461 
462   // Not using base::Callback because of its limited by 7 parameters.
463   // Also, using primitive type allows directly passing callback from WebCore.
464   // WARNING: It is possible for the previously set callback to be called
465   // after a call to SetEventCallbackEnabled() that replaces or a call to
466   // SetEventCallbackDisabled() that disables the callback.
467   // This callback may be invoked on any thread.
468   // For TRACE_EVENT_PHASE_COMPLETE events, the client will still receive pairs
469   // of TRACE_EVENT_PHASE_BEGIN and TRACE_EVENT_PHASE_END events to keep the
470   // interface simple.
471   typedef void (*EventCallback)(TimeTicks timestamp,
472                                 char phase,
473                                 const unsigned char* category_group_enabled,
474                                 const char* name,
475                                 unsigned long long id,
476                                 int num_args,
477                                 const char* const arg_names[],
478                                 const unsigned char arg_types[],
479                                 const unsigned long long arg_values[],
480                                 unsigned char flags);
481 
482   // Enable tracing for EventCallback.
483   void SetEventCallbackEnabled(const CategoryFilter& category_filter,
484                                EventCallback cb);
485   void SetEventCallbackDisabled();
486 
487   // Flush all collected events to the given output callback. The callback will
488   // be called one or more times either synchronously or asynchronously from
489   // the current thread with IPC-bite-size chunks. The string format is
490   // undefined. Use TraceResultBuffer to convert one or more trace strings to
491   // JSON. The callback can be null if the caller doesn't want any data.
492   // Due to the implementation of thread-local buffers, flush can't be
493   // done when tracing is enabled. If called when tracing is enabled, the
494   // callback will be called directly with (empty_string, false) to indicate
495   // the end of this unsuccessful flush.
496   typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&,
497                               bool has_more_events)> OutputCallback;
498   void Flush(const OutputCallback& cb);
499   void FlushButLeaveBufferIntact(const OutputCallback& flush_output_callback);
500 
501   // Called by TRACE_EVENT* macros, don't call this directly.
502   // The name parameter is a category group for example:
503   // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent")
504   static const unsigned char* GetCategoryGroupEnabled(const char* name);
505   static const char* GetCategoryGroupName(
506       const unsigned char* category_group_enabled);
507 
508   // Called by TRACE_EVENT* macros, don't call this directly.
509   // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied
510   // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above.
511   TraceEventHandle AddTraceEvent(
512       char phase,
513       const unsigned char* category_group_enabled,
514       const char* name,
515       unsigned long long id,
516       int num_args,
517       const char** arg_names,
518       const unsigned char* arg_types,
519       const unsigned long long* arg_values,
520       const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
521       unsigned char flags);
522   TraceEventHandle AddTraceEventWithThreadIdAndTimestamp(
523       char phase,
524       const unsigned char* category_group_enabled,
525       const char* name,
526       unsigned long long id,
527       int thread_id,
528       const TimeTicks& timestamp,
529       int num_args,
530       const char** arg_names,
531       const unsigned char* arg_types,
532       const unsigned long long* arg_values,
533       const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
534       unsigned char flags);
535   static void AddTraceEventEtw(char phase,
536                                const char* category_group,
537                                const void* id,
538                                const char* extra);
539   static void AddTraceEventEtw(char phase,
540                                const char* category_group,
541                                const void* id,
542                                const std::string& extra);
543 
544   void UpdateTraceEventDuration(const unsigned char* category_group_enabled,
545                                 const char* name,
546                                 TraceEventHandle handle);
547 
548   // For every matching event, the callback will be called.
549   typedef base::Callback<void()> WatchEventCallback;
550   void SetWatchEvent(const std::string& category_name,
551                      const std::string& event_name,
552                      const WatchEventCallback& callback);
553   // Cancel the watch event. If tracing is enabled, this may race with the
554   // watch event notification firing.
555   void CancelWatchEvent();
556 
557   int process_id() const { return process_id_; }
558 
559   // Exposed for unittesting:
560 
561   void WaitSamplingEventForTesting();
562 
563   // Allows deleting our singleton instance.
564   static void DeleteForTesting();
565 
566   // Allow tests to inspect TraceEvents.
567   size_t GetEventsSize() const { return logged_events_->Size(); }
568   TraceEvent* GetEventByHandle(TraceEventHandle handle);
569 
570   void SetProcessID(int process_id);
571 
572   // Process sort indices, if set, override the order of a process will appear
573   // relative to other processes in the trace viewer. Processes are sorted first
574   // on their sort index, ascending, then by their name, and then tid.
575   void SetProcessSortIndex(int sort_index);
576 
577   // Sets the name of the process.
578   void SetProcessName(const std::string& process_name);
579 
580   // Processes can have labels in addition to their names. Use labels, for
581   // instance, to list out the web page titles that a process is handling.
582   void UpdateProcessLabel(int label_id, const std::string& current_label);
583   void RemoveProcessLabel(int label_id);
584 
585   // Thread sort indices, if set, override the order of a thread will appear
586   // within its process in the trace viewer. Threads are sorted first on their
587   // sort index, ascending, then by their name, and then tid.
588   void SetThreadSortIndex(PlatformThreadId , int sort_index);
589 
590   // Allow setting an offset between the current TimeTicks time and the time
591   // that should be reported.
592   void SetTimeOffset(TimeDelta offset);
593 
594   size_t GetObserverCountForTest() const;
595 
596   // Call this method if the current thread may block the message loop to
597   // prevent the thread from using the thread-local buffer because the thread
598   // may not handle the flush request in time causing lost of unflushed events.
599   void SetCurrentThreadBlocksMessageLoop();
600 
601  private:
602   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
603                            TraceBufferRingBufferGetReturnChunk);
604   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
605                            TraceBufferRingBufferHalfIteration);
606   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
607                            TraceBufferRingBufferFullIteration);
608 
609   // This allows constructor and destructor to be private and usable only
610   // by the Singleton class.
611   friend struct DefaultSingletonTraits<TraceLog>;
612 
613   // Enable/disable each category group based on the current mode_,
614   // category_filter_, event_callback_ and event_callback_category_filter_.
615   // Enable the category group in the enabled mode if category_filter_ matches
616   // the category group, or event_callback_ is not null and
617   // event_callback_category_filter_ matches the category group.
618   void UpdateCategoryGroupEnabledFlags();
619   void UpdateCategoryGroupEnabledFlag(int category_index);
620 
621   // Configure synthetic delays based on the values set in the current
622   // category filter.
623   void UpdateSyntheticDelaysFromCategoryFilter();
624 
625   class ThreadLocalEventBuffer;
626   class OptionalAutoLock;
627 
628   TraceLog();
629   ~TraceLog();
630   const unsigned char* GetCategoryGroupEnabledInternal(const char* name);
631   void AddMetadataEventsWhileLocked();
632 
633   TraceBuffer* trace_buffer() const { return logged_events_.get(); }
634   TraceBuffer* CreateTraceBuffer();
635 
636   std::string EventToConsoleMessage(unsigned char phase,
637                                     const TimeTicks& timestamp,
638                                     TraceEvent* trace_event);
639 
640   TraceEvent* AddEventToThreadSharedChunkWhileLocked(TraceEventHandle* handle,
641                                                      bool check_buffer_is_full);
642   void CheckIfBufferIsFullWhileLocked();
643   void SetDisabledWhileLocked();
644 
645   TraceEvent* GetEventByHandleInternal(TraceEventHandle handle,
646                                        OptionalAutoLock* lock);
647 
648   // |generation| is used in the following callbacks to check if the callback
649   // is called for the flush of the current |logged_events_|.
650   void FlushCurrentThread(int generation);
651   void ConvertTraceEventsToTraceFormat(scoped_ptr<TraceBuffer> logged_events,
652       const TraceLog::OutputCallback& flush_output_callback);
653   void FinishFlush(int generation);
654   void OnFlushTimeout(int generation);
655 
656   int generation() const {
657     return static_cast<int>(subtle::NoBarrier_Load(&generation_));
658   }
659   bool CheckGeneration(int generation) const {
660     return generation == this->generation();
661   }
662   void UseNextTraceBuffer();
663 
664   TimeTicks OffsetNow() const {
665     return OffsetTimestamp(TimeTicks::NowFromSystemTraceTime());
666   }
667   TimeTicks OffsetTimestamp(const TimeTicks& timestamp) const {
668     return timestamp - time_offset_;
669   }
670 
671   // This lock protects TraceLog member accesses (except for members protected
672   // by thread_info_lock_) from arbitrary threads.
673   mutable Lock lock_;
674   // This lock protects accesses to thread_names_, thread_event_start_times_
675   // and thread_colors_.
676   Lock thread_info_lock_;
677   int locked_line_;
678   Mode mode_;
679   int num_traces_recorded_;
680   scoped_ptr<TraceBuffer> logged_events_;
681   subtle::AtomicWord /* EventCallback */ event_callback_;
682   bool dispatching_to_observer_list_;
683   std::vector<EnabledStateObserver*> enabled_state_observer_list_;
684 
685   std::string process_name_;
686   base::hash_map<int, std::string> process_labels_;
687   int process_sort_index_;
688   base::hash_map<int, int> thread_sort_indices_;
689   base::hash_map<int, std::string> thread_names_;
690 
691   // The following two maps are used only when ECHO_TO_CONSOLE.
692   base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_;
693   base::hash_map<std::string, int> thread_colors_;
694 
695   // XORed with TraceID to make it unlikely to collide with other processes.
696   unsigned long long process_id_hash_;
697 
698   int process_id_;
699 
700   TimeDelta time_offset_;
701 
702   // Allow tests to wake up when certain events occur.
703   WatchEventCallback watch_event_callback_;
704   subtle::AtomicWord /* const unsigned char* */ watch_category_;
705   std::string watch_event_name_;
706 
707   subtle::AtomicWord /* Options */ trace_options_;
708 
709   // Sampling thread handles.
710   scoped_ptr<TraceSamplingThread> sampling_thread_;
711   PlatformThreadHandle sampling_thread_handle_;
712 
713   CategoryFilter category_filter_;
714   CategoryFilter event_callback_category_filter_;
715 
716   ThreadLocalPointer<ThreadLocalEventBuffer> thread_local_event_buffer_;
717   ThreadLocalBoolean thread_blocks_message_loop_;
718   ThreadLocalBoolean thread_is_in_trace_event_;
719 
720   // Contains the message loops of threads that have had at least one event
721   // added into the local event buffer. Not using MessageLoopProxy because we
722   // need to know the life time of the message loops.
723   hash_set<MessageLoop*> thread_message_loops_;
724 
725   // For events which can't be added into the thread local buffer, e.g. events
726   // from threads without a message loop.
727   scoped_ptr<TraceBufferChunk> thread_shared_chunk_;
728   size_t thread_shared_chunk_index_;
729 
730   // Set when asynchronous Flush is in progress.
731   OutputCallback flush_output_callback_;
732   scoped_refptr<MessageLoopProxy> flush_message_loop_proxy_;
733   subtle::AtomicWord generation_;
734 
735   DISALLOW_COPY_AND_ASSIGN(TraceLog);
736 };
737 
738 }  // namespace debug
739 }  // namespace base
740 
741 #endif  // BASE_DEBUG_TRACE_EVENT_IMPL_H_
742