- add sources.
[platform/framework/web/crosswalk.git] / src / base / debug / trace_event_impl.h
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);
126
127   // Serialize event data to JSON
128   static void AppendEventsAsJSON(const std::vector<TraceEvent>& events,
129                                  size_t start,
130                                  size_t count,
131                                  std::string* out);
132   void AppendAsJSON(std::string* out) const;
133   void AppendPrettyPrinted(std::ostringstream* out) const;
134
135   static void AppendValueAsJSON(unsigned char type,
136                                 TraceValue value,
137                                 std::string* out);
138
139   TimeTicks timestamp() const { return timestamp_; }
140   TimeTicks thread_timestamp() const { return thread_timestamp_; }
141   char phase() const { return phase_; }
142   int thread_id() const { return thread_id_; }
143   TimeDelta duration() const { return duration_; }
144   unsigned long long id() const { return id_; }
145   unsigned char flags() const { return flags_; }
146
147   // Exposed for unittesting:
148
149   const base::RefCountedString* parameter_copy_storage() const {
150     return parameter_copy_storage_.get();
151   }
152
153   const unsigned char* category_group_enabled() const {
154     return category_group_enabled_;
155   }
156
157   const char* name() const { return name_; }
158
159 #if defined(OS_ANDROID)
160   void SendToATrace();
161 #endif
162
163  private:
164   // Note: these are ordered by size (largest first) for optimal packing.
165   TimeTicks timestamp_;
166   TimeTicks thread_timestamp_;
167   TimeDelta duration_;
168   // id_ can be used to store phase-specific data.
169   unsigned long long id_;
170   TraceValue arg_values_[kTraceMaxNumArgs];
171   const char* arg_names_[kTraceMaxNumArgs];
172   scoped_refptr<ConvertableToTraceFormat> convertable_values_[kTraceMaxNumArgs];
173   const unsigned char* category_group_enabled_;
174   const char* name_;
175   scoped_refptr<base::RefCountedString> parameter_copy_storage_;
176   int thread_id_;
177   char phase_;
178   unsigned char flags_;
179   unsigned char arg_types_[kTraceMaxNumArgs];
180
181   DISALLOW_COPY_AND_ASSIGN(TraceEvent);
182 };
183
184 // TraceBufferChunk is the basic unit of TraceBuffer.
185 class BASE_EXPORT TraceBufferChunk {
186  public:
187   TraceBufferChunk(uint32 seq)
188       : next_free_(0),
189         seq_(seq) {
190   }
191
192   void Reset(uint32 new_seq);
193   TraceEvent* AddTraceEvent(size_t* event_index);
194   bool IsFull() const { return next_free_ == kTraceBufferChunkSize; }
195
196   uint32 seq() const { return seq_; }
197   size_t capacity() const { return kTraceBufferChunkSize; }
198   size_t size() const { return next_free_; }
199
200   TraceEvent* GetEventAt(size_t index) {
201     DCHECK(index < size());
202     return &chunk_[index];
203   }
204   const TraceEvent* GetEventAt(size_t index) const {
205     DCHECK(index < size());
206     return &chunk_[index];
207   }
208
209   scoped_ptr<TraceBufferChunk> Clone() const;
210
211   static const size_t kTraceBufferChunkSize = 64;
212
213  private:
214   size_t next_free_;
215   TraceEvent chunk_[kTraceBufferChunkSize];
216   uint32 seq_;
217 };
218
219 // TraceBuffer holds the events as they are collected.
220 class BASE_EXPORT TraceBuffer {
221  public:
222   virtual ~TraceBuffer() {}
223
224   virtual scoped_ptr<TraceBufferChunk> GetChunk(size_t *index) = 0;
225   virtual void ReturnChunk(size_t index,
226                            scoped_ptr<TraceBufferChunk> chunk) = 0;
227
228   virtual bool IsFull() const = 0;
229   virtual size_t Size() const = 0;
230   virtual size_t Capacity() const = 0;
231   virtual TraceEvent* GetEventByHandle(TraceEventHandle handle) = 0;
232
233   // For iteration. Each TraceBuffer can only be iterated once.
234   virtual const TraceBufferChunk* NextChunk() = 0;
235
236   virtual scoped_ptr<TraceBuffer> CloneForIteration() const = 0;
237 };
238
239 // TraceResultBuffer collects and converts trace fragments returned by TraceLog
240 // to JSON output.
241 class BASE_EXPORT TraceResultBuffer {
242  public:
243   typedef base::Callback<void(const std::string&)> OutputCallback;
244
245   // If you don't need to stream JSON chunks out efficiently, and just want to
246   // get a complete JSON string after calling Finish, use this struct to collect
247   // JSON trace output.
248   struct BASE_EXPORT SimpleOutput {
249     OutputCallback GetCallback();
250     void Append(const std::string& json_string);
251
252     // Do what you want with the json_output_ string after calling
253     // TraceResultBuffer::Finish.
254     std::string json_output;
255   };
256
257   TraceResultBuffer();
258   ~TraceResultBuffer();
259
260   // Set callback. The callback will be called during Start with the initial
261   // JSON output and during AddFragment and Finish with following JSON output
262   // chunks. The callback target must live past the last calls to
263   // TraceResultBuffer::Start/AddFragment/Finish.
264   void SetOutputCallback(const OutputCallback& json_chunk_callback);
265
266   // Start JSON output. This resets all internal state, so you can reuse
267   // the TraceResultBuffer by calling Start.
268   void Start();
269
270   // Call AddFragment 0 or more times to add trace fragments from TraceLog.
271   void AddFragment(const std::string& trace_fragment);
272
273   // When all fragments have been added, call Finish to complete the JSON
274   // formatted output.
275   void Finish();
276
277  private:
278   OutputCallback output_callback_;
279   bool append_comma_;
280 };
281
282 class BASE_EXPORT CategoryFilter {
283  public:
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   explicit CategoryFilter(const std::string& filter_string);
300
301   CategoryFilter(const CategoryFilter& cf);
302
303   ~CategoryFilter();
304
305   CategoryFilter& operator=(const CategoryFilter& rhs);
306
307   // Writes the string representation of the CategoryFilter. This is a comma
308   // separated string, similar in nature to the one used to determine
309   // enabled/disabled category patterns, except here there is an arbitrary
310   // order, included categories go first, then excluded categories. Excluded
311   // categories are distinguished from included categories by the prefix '-'.
312   std::string ToString() const;
313
314   // Determines whether category group would be enabled or
315   // disabled by this category filter.
316   bool IsCategoryGroupEnabled(const char* category_group) const;
317
318   // Merges nested_filter with the current CategoryFilter
319   void Merge(const CategoryFilter& nested_filter);
320
321   // Clears both included/excluded pattern lists. This would be equivalent to
322   // creating a CategoryFilter with an empty string, through the constructor.
323   // i.e: CategoryFilter("").
324   //
325   // When using an empty filter, all categories are considered included as we
326   // are not excluding anything.
327   void Clear();
328
329  private:
330   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, CategoryFilter);
331
332   static bool IsEmptyOrContainsLeadingOrTrailingWhitespace(
333       const std::string& str);
334
335   typedef std::vector<std::string> StringList;
336
337   void Initialize(const std::string& filter_string);
338   void WriteString(const StringList& values,
339                    std::string* out,
340                    bool included) const;
341   bool HasIncludedPatterns() const;
342
343   bool DoesCategoryGroupContainCategory(const char* category_group,
344                                         const char* category) const;
345
346   StringList included_;
347   StringList disabled_;
348   StringList excluded_;
349 };
350
351 class TraceSamplingThread;
352
353 class BASE_EXPORT TraceLog {
354  public:
355   // Notification is a mask of one or more of the following events.
356   enum Notification {
357     // The trace buffer does not flush dynamically, so when it fills up,
358     // subsequent trace events will be dropped. This callback is generated when
359     // the trace buffer is full. The callback must be thread safe.
360     TRACE_BUFFER_FULL = 1 << 0,
361     // A subscribed trace-event occurred.
362     EVENT_WATCH_NOTIFICATION = 1 << 1
363   };
364
365   // Options determines how the trace buffer stores data.
366   enum Options {
367     // Record until the trace buffer is full.
368     RECORD_UNTIL_FULL = 1 << 0,
369
370     // Record until the user ends the trace. The trace buffer is a fixed size
371     // and we use it as a ring buffer during recording.
372     RECORD_CONTINUOUSLY = 1 << 1,
373
374     // Enable the sampling profiler in the recording mode.
375     ENABLE_SAMPLING = 1 << 2,
376
377     // Enable the sampling profiler in the monitoring mode.
378     MONITOR_SAMPLING = 1 << 3,
379
380     // Echo to console. Events are discarded.
381     ECHO_TO_CONSOLE = 1 << 4,
382   };
383
384   static TraceLog* GetInstance();
385
386   // Convert the given string to trace options. Defaults to RECORD_UNTIL_FULL if
387   // the string does not provide valid options.
388   static Options TraceOptionsFromString(const std::string& str);
389
390   // Get set of known category groups. This can change as new code paths are
391   // reached. The known category groups are inserted into |category_groups|.
392   void GetKnownCategoryGroups(std::vector<std::string>* category_groups);
393
394   // Retrieves the current CategoryFilter.
395   const CategoryFilter& GetCurrentCategoryFilter();
396
397   Options trace_options() const {
398     return static_cast<Options>(subtle::NoBarrier_Load(&trace_options_));
399   }
400
401   // Enables tracing. See CategoryFilter comments for details
402   // on how to control what categories will be traced.
403   void SetEnabled(const CategoryFilter& category_filter, Options options);
404
405   // Disables tracing for all categories.
406   void SetDisabled();
407   bool IsEnabled() { return !!enable_count_; }
408
409   // The number of times we have begun recording traces. If tracing is off,
410   // returns -1. If tracing is on, then it returns the number of times we have
411   // recorded a trace. By watching for this number to increment, you can
412   // passively discover when a new trace has begun. This is then used to
413   // implement the TRACE_EVENT_IS_NEW_TRACE() primitive.
414   int GetNumTracesRecorded();
415
416 #if defined(OS_ANDROID)
417   void StartATrace();
418   void StopATrace();
419   void AddClockSyncMetadataEvent();
420 #endif
421
422   // Enabled state listeners give a callback when tracing is enabled or
423   // disabled. This can be used to tie into other library's tracing systems
424   // on-demand.
425   class EnabledStateObserver {
426    public:
427     // Called just after the tracing system becomes enabled, outside of the
428     // |lock_|.  TraceLog::IsEnabled() is true at this point.
429     virtual void OnTraceLogEnabled() = 0;
430
431     // Called just after the tracing system disables, outside of the |lock_|.
432     // TraceLog::IsEnabled() is false at this point.
433     virtual void OnTraceLogDisabled() = 0;
434   };
435   void AddEnabledStateObserver(EnabledStateObserver* listener);
436   void RemoveEnabledStateObserver(EnabledStateObserver* listener);
437   bool HasEnabledStateObserver(EnabledStateObserver* listener) const;
438
439   float GetBufferPercentFull() const;
440
441   // Set the thread-safe notification callback. The callback can occur at any
442   // time and from any thread. WARNING: It is possible for the previously set
443   // callback to be called during OR AFTER a call to SetNotificationCallback.
444   // Therefore, the target of the callback must either be a global function,
445   // ref-counted object or a LazyInstance with Leaky traits (or equivalent).
446   typedef base::Callback<void(int)> NotificationCallback;
447   void SetNotificationCallback(const NotificationCallback& cb);
448
449   // Not using base::Callback because of its limited by 7 parameters.
450   // Also, using primitive type allows directly passing callback from WebCore.
451   // WARNING: It is possible for the previously set callback to be called
452   // after a call to SetEventCallback() that replaces or clears the callback.
453   // This callback may be invoked on any thread.
454   // TODO(wangxianzhu): For now for TRACE_EVENT_PHASE_COMPLETE events, the
455   // client will still receive pairs of TRACE_EVENT_PHASE_BEGIN and
456   // TRACE_EVENT_PHASE_END events. Should send TRACE_EVENT_PHASE_COMPLETE
457   // directly to clients if it is beneficial and feasible.
458   typedef void (*EventCallback)(TimeTicks timestamp,
459                                 char phase,
460                                 const unsigned char* category_group_enabled,
461                                 const char* name,
462                                 unsigned long long id,
463                                 int num_args,
464                                 const char* const arg_names[],
465                                 const unsigned char arg_types[],
466                                 const unsigned long long arg_values[],
467                                 unsigned char flags);
468   void SetEventCallback(EventCallback cb);
469
470   // Flush all collected events to the given output callback. The callback will
471   // be called one or more times either synchronously or asynchronously from
472   // the current thread with IPC-bite-size chunks. The string format is
473   // undefined. Use TraceResultBuffer to convert one or more trace strings to
474   // JSON. The callback can be null if the caller doesn't want any data.
475   // Due to the implementation of thread-local buffers, flush can't be
476   // done when tracing is enabled. If called when tracing is enabled, the
477   // callback will be called directly with (empty_string, false) to indicate
478   // the end of this unsuccessful flush.
479   typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&,
480                               bool has_more_events)> OutputCallback;
481   void Flush(const OutputCallback& cb);
482   void FlushButLeaveBufferIntact(const OutputCallback& flush_output_callback);
483
484   // Called by TRACE_EVENT* macros, don't call this directly.
485   // The name parameter is a category group for example:
486   // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent")
487   static const unsigned char* GetCategoryGroupEnabled(const char* name);
488   static const char* GetCategoryGroupName(
489       const unsigned char* category_group_enabled);
490
491   // Called by TRACE_EVENT* macros, don't call this directly.
492   // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied
493   // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above.
494   TraceEventHandle AddTraceEvent(
495       char phase,
496       const unsigned char* category_group_enabled,
497       const char* name,
498       unsigned long long id,
499       int num_args,
500       const char** arg_names,
501       const unsigned char* arg_types,
502       const unsigned long long* arg_values,
503       const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
504       unsigned char flags);
505   TraceEventHandle AddTraceEventWithThreadIdAndTimestamp(
506       char phase,
507       const unsigned char* category_group_enabled,
508       const char* name,
509       unsigned long long id,
510       int thread_id,
511       const TimeTicks& timestamp,
512       int num_args,
513       const char** arg_names,
514       const unsigned char* arg_types,
515       const unsigned long long* arg_values,
516       const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
517       unsigned char flags);
518   static void AddTraceEventEtw(char phase,
519                                const char* category_group,
520                                const void* id,
521                                const char* extra);
522   static void AddTraceEventEtw(char phase,
523                                const char* category_group,
524                                const void* id,
525                                const std::string& extra);
526
527   void UpdateTraceEventDuration(TraceEventHandle handle);
528
529   // For every matching event, a notification will be fired. NOTE: the
530   // notification will fire for each matching event that has already occurred
531   // since tracing was started (including before tracing if the process was
532   // started with tracing turned on).
533   void SetWatchEvent(const std::string& category_name,
534                      const std::string& event_name);
535   // Cancel the watch event. If tracing is enabled, this may race with the
536   // watch event notification firing.
537   void CancelWatchEvent();
538
539   int process_id() const { return process_id_; }
540
541   // Exposed for unittesting:
542
543   void InstallWaitableEventForSamplingTesting(WaitableEvent* waitable_event);
544
545   // Allows deleting our singleton instance.
546   static void DeleteForTesting();
547
548   // Allow tests to inspect TraceEvents.
549   size_t GetEventsSize() const { return logged_events_->Size(); }
550   TraceEvent* GetEventByHandle(TraceEventHandle handle);
551
552   void SetProcessID(int process_id);
553
554   // Process sort indices, if set, override the order of a process will appear
555   // relative to other processes in the trace viewer. Processes are sorted first
556   // on their sort index, ascending, then by their name, and then tid.
557   void SetProcessSortIndex(int sort_index);
558
559   // Sets the name of the process.
560   void SetProcessName(const std::string& process_name);
561
562   // Processes can have labels in addition to their names. Use labels, for
563   // instance, to list out the web page titles that a process is handling.
564   void UpdateProcessLabel(int label_id, const std::string& current_label);
565   void RemoveProcessLabel(int label_id);
566
567   // Thread sort indices, if set, override the order of a thread will appear
568   // within its process in the trace viewer. Threads are sorted first on their
569   // sort index, ascending, then by their name, and then tid.
570   void SetThreadSortIndex(PlatformThreadId , int sort_index);
571
572   // Allow setting an offset between the current TimeTicks time and the time
573   // that should be reported.
574   void SetTimeOffset(TimeDelta offset);
575
576   size_t GetObserverCountForTest() const;
577
578   // Call this method if the current thread may block the message loop to
579   // prevent the thread from using the thread-local buffer because the thread
580   // may not handle the flush request in time causing lost of unflushed events.
581   void SetCurrentThreadBlocksMessageLoop();
582
583  private:
584   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
585                            TraceBufferRingBufferGetReturnChunk);
586   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
587                            TraceBufferRingBufferHalfIteration);
588   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
589                            TraceBufferRingBufferFullIteration);
590
591   // This allows constructor and destructor to be private and usable only
592   // by the Singleton class.
593   friend struct DefaultSingletonTraits<TraceLog>;
594
595   // Enable/disable each category group based on the current enable_count_
596   // and category_filter_. Disable the category group if enabled_count_ is 0, or
597   // if the category group contains a category that matches an included category
598   // pattern, that category group will be enabled.
599   // On Android, ATRACE_ENABLED flag will be applied if atrace is started.
600   void UpdateCategoryGroupEnabledFlags();
601   void UpdateCategoryGroupEnabledFlag(int category_index);
602
603   // Helper class for managing notification_thread_count_ and running
604   // notification callbacks. This is very similar to a reader-writer lock, but
605   // shares the lock with TraceLog and manages the notification flags.
606   class NotificationHelper {
607    public:
608     inline explicit NotificationHelper(TraceLog* trace_log);
609     inline ~NotificationHelper();
610
611     // Called only while TraceLog::lock_ is held. This ORs the given
612     // notification with any existing notifications.
613     inline void AddNotificationWhileLocked(int notification);
614
615     // Called only while TraceLog::lock_ is NOT held. If there are any pending
616     // notifications from previous calls to AddNotificationWhileLocked, this
617     // will call the NotificationCallback.
618     inline void SendNotificationIfAny();
619
620    private:
621     TraceLog* trace_log_;
622     NotificationCallback callback_copy_;
623     int notification_;
624   };
625
626   class ThreadLocalEventBuffer;
627   class OptionalAutoLock;
628
629   TraceLog();
630   ~TraceLog();
631   const unsigned char* GetCategoryGroupEnabledInternal(const char* name);
632   void AddMetadataEventsWhileLocked();
633
634   TraceBuffer* trace_buffer() const { return logged_events_.get(); }
635   TraceBuffer* CreateTraceBuffer();
636
637   void OutputEventToConsoleWhileLocked(unsigned char phase,
638                                        const TimeTicks& timestamp,
639                                        TraceEvent* trace_event);
640
641   TraceEvent* AddEventToThreadSharedChunkWhileLocked(
642       NotificationHelper* notifier, TraceEventHandle* handle);
643   void CheckIfBufferIsFullWhileLocked(NotificationHelper* notifier);
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   int NextGeneration() {
663     return static_cast<int>(subtle::NoBarrier_AtomicIncrement(&generation_, 1));
664   }
665
666   TimeTicks OffsetNow() const {
667     return OffsetTimestamp(TimeTicks::NowFromSystemTraceTime());
668   }
669   TimeTicks OffsetTimestamp(const TimeTicks& timestamp) const {
670     return timestamp - time_offset_;
671   }
672
673   // This lock protects TraceLog member accesses from arbitrary threads.
674   Lock lock_;
675   int locked_line_;
676   int enable_count_;
677   int num_traces_recorded_;
678   subtle::AtomicWord /* bool */ buffer_is_full_;
679   NotificationCallback notification_callback_;
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   subtle::AtomicWord /* const unsigned char* */ watch_category_;
704   std::string watch_event_name_;
705
706   subtle::AtomicWord /* Options */ trace_options_;
707
708   // Sampling thread handles.
709   scoped_ptr<TraceSamplingThread> sampling_thread_;
710   PlatformThreadHandle sampling_thread_handle_;
711
712   CategoryFilter category_filter_;
713
714   ThreadLocalPointer<ThreadLocalEventBuffer> thread_local_event_buffer_;
715   ThreadLocalBoolean thread_blocks_message_loop_;
716
717   // Contains the message loops of threads that have had at least one event
718   // added into the local event buffer. Not using MessageLoopProxy because we
719   // need to know the life time of the message loops.
720   hash_set<MessageLoop*> thread_message_loops_;
721
722   // For events which can't be added into the thread local buffer, e.g. events
723   // from threads without a message loop.
724   scoped_ptr<TraceBufferChunk> thread_shared_chunk_;
725   size_t thread_shared_chunk_index_;
726
727   // Set when asynchronous Flush is in progress.
728   OutputCallback flush_output_callback_;
729   scoped_refptr<MessageLoopProxy> flush_message_loop_proxy_;
730   subtle::AtomicWord generation_;
731
732   DISALLOW_COPY_AND_ASSIGN(TraceLog);
733 };
734
735 }  // namespace debug
736 }  // namespace base
737
738 #endif  // BASE_DEBUG_TRACE_EVENT_IMPL_H_