OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 | 5 |
6 #ifndef BASE_DEBUG_TRACE_EVENT_IMPL_H_ | 6 #ifndef BASE_DEBUG_TRACE_EVENT_IMPL_H_ |
7 #define BASE_DEBUG_TRACE_EVENT_IMPL_H_ | 7 #define BASE_DEBUG_TRACE_EVENT_IMPL_H_ |
8 | 8 |
9 #include <stack> | 9 #include <stack> |
10 #include <string> | 10 #include <string> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/atomicops.h" | |
13 #include "base/callback.h" | 14 #include "base/callback.h" |
14 #include "base/containers/hash_tables.h" | 15 #include "base/containers/hash_tables.h" |
15 #include "base/gtest_prod_util.h" | 16 #include "base/gtest_prod_util.h" |
16 #include "base/memory/ref_counted_memory.h" | 17 #include "base/memory/ref_counted_memory.h" |
17 #include "base/memory/scoped_vector.h" | 18 #include "base/memory/scoped_vector.h" |
18 #include "base/observer_list.h" | 19 #include "base/observer_list.h" |
19 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
20 #include "base/synchronization/condition_variable.h" | 21 #include "base/synchronization/condition_variable.h" |
21 #include "base/synchronization/lock.h" | 22 #include "base/synchronization/lock.h" |
22 #include "base/threading/thread.h" | 23 #include "base/threading/thread.h" |
24 #include "base/threading/thread_local.h" | |
23 #include "base/timer/timer.h" | 25 #include "base/timer/timer.h" |
24 | 26 |
25 // Older style trace macros with explicit id and extra data | 27 // Older style trace macros with explicit id and extra data |
26 // Only these macros result in publishing data to ETW as currently implemented. | 28 // Only these macros result in publishing data to ETW as currently implemented. |
27 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ | 29 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ |
28 base::debug::TraceLog::AddTraceEventEtw( \ | 30 base::debug::TraceLog::AddTraceEventEtw( \ |
29 TRACE_EVENT_PHASE_BEGIN, \ | 31 TRACE_EVENT_PHASE_BEGIN, \ |
30 name, reinterpret_cast<const void*>(id), extra) | 32 name, reinterpret_cast<const void*>(id), extra) |
31 | 33 |
32 #define TRACE_EVENT_END_ETW(name, id, extra) \ | 34 #define TRACE_EVENT_END_ETW(name, id, extra) \ |
33 base::debug::TraceLog::AddTraceEventEtw( \ | 35 base::debug::TraceLog::AddTraceEventEtw( \ |
34 TRACE_EVENT_PHASE_END, \ | 36 TRACE_EVENT_PHASE_END, \ |
35 name, reinterpret_cast<const void*>(id), extra) | 37 name, reinterpret_cast<const void*>(id), extra) |
36 | 38 |
37 #define TRACE_EVENT_INSTANT_ETW(name, id, extra) \ | 39 #define TRACE_EVENT_INSTANT_ETW(name, id, extra) \ |
38 base::debug::TraceLog::AddTraceEventEtw( \ | 40 base::debug::TraceLog::AddTraceEventEtw( \ |
39 TRACE_EVENT_PHASE_INSTANT, \ | 41 TRACE_EVENT_PHASE_INSTANT, \ |
40 name, reinterpret_cast<const void*>(id), extra) | 42 name, reinterpret_cast<const void*>(id), extra) |
41 | 43 |
42 template <typename Type> | 44 template <typename Type> |
43 struct DefaultSingletonTraits; | 45 struct DefaultSingletonTraits; |
44 | 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 } | |
dsinclair
2013/08/29 14:24:32
nit: // namespace BASE_HASH_NAMESPACE
Xianzhu
2013/08/29 17:42:12
Done.
| |
56 #endif | |
57 | |
45 namespace base { | 58 namespace base { |
46 | 59 |
47 class WaitableEvent; | 60 class WaitableEvent; |
61 class MessageLoop; | |
48 | 62 |
49 namespace debug { | 63 namespace debug { |
50 | 64 |
51 // For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided | 65 // For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided |
52 // class must implement this interface. | 66 // class must implement this interface. |
53 class ConvertableToTraceFormat { | 67 class ConvertableToTraceFormat { |
54 public: | 68 public: |
55 virtual ~ConvertableToTraceFormat() {} | 69 virtual ~ConvertableToTraceFormat() {} |
56 | 70 |
57 // Append the class info to the provided |out| string. The appended | 71 // Append the class info to the provided |out| string. The appended |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
103 std::string* out); | 117 std::string* out); |
104 void AppendAsJSON(std::string* out) const; | 118 void AppendAsJSON(std::string* out) const; |
105 void AppendPrettyPrinted(std::ostringstream* out) const; | 119 void AppendPrettyPrinted(std::ostringstream* out) const; |
106 | 120 |
107 static void AppendValueAsJSON(unsigned char type, | 121 static void AppendValueAsJSON(unsigned char type, |
108 TraceValue value, | 122 TraceValue value, |
109 std::string* out); | 123 std::string* out); |
110 | 124 |
111 TimeTicks timestamp() const { return timestamp_; } | 125 TimeTicks timestamp() const { return timestamp_; } |
112 TimeTicks thread_timestamp() const { return thread_timestamp_; } | 126 TimeTicks thread_timestamp() const { return thread_timestamp_; } |
127 char phase() const { return phase_; } | |
128 int thread_id() const { return thread_id_; } | |
113 | 129 |
114 // Exposed for unittesting: | 130 // Exposed for unittesting: |
115 | 131 |
116 const base::RefCountedString* parameter_copy_storage() const { | 132 const base::RefCountedString* parameter_copy_storage() const { |
117 return parameter_copy_storage_.get(); | 133 return parameter_copy_storage_.get(); |
118 } | 134 } |
119 | 135 |
120 const unsigned char* category_group_enabled() const { | 136 const unsigned char* category_group_enabled() const { |
121 return category_group_enabled_; | 137 return category_group_enabled_; |
122 } | 138 } |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
289 RECORD_UNTIL_FULL = 1 << 0, | 305 RECORD_UNTIL_FULL = 1 << 0, |
290 | 306 |
291 // Record until the user ends the trace. The trace buffer is a fixed size | 307 // Record until the user ends the trace. The trace buffer is a fixed size |
292 // and we use it as a ring buffer during recording. | 308 // and we use it as a ring buffer during recording. |
293 RECORD_CONTINUOUSLY = 1 << 1, | 309 RECORD_CONTINUOUSLY = 1 << 1, |
294 | 310 |
295 // Enable the sampling profiler. | 311 // Enable the sampling profiler. |
296 ENABLE_SAMPLING = 1 << 2, | 312 ENABLE_SAMPLING = 1 << 2, |
297 | 313 |
298 // Echo to console. Events are discarded. | 314 // Echo to console. Events are discarded. |
299 ECHO_TO_CONSOLE = 1 << 3 | 315 ECHO_TO_CONSOLE = 1 << 3, |
300 }; | 316 }; |
301 | 317 |
302 static TraceLog* GetInstance(); | 318 static TraceLog* GetInstance(); |
303 | 319 |
304 // Convert the given string to trace options. Defaults to RECORD_UNTIL_FULL if | 320 // Convert the given string to trace options. Defaults to RECORD_UNTIL_FULL if |
305 // the string does not provide valid options. | 321 // the string does not provide valid options. |
306 static Options TraceOptionsFromString(const std::string& str); | 322 static Options TraceOptionsFromString(const std::string& str); |
307 | 323 |
308 // Get set of known category groups. This can change as new code paths are | 324 // Get set of known category groups. This can change as new code paths are |
309 // reached. The known category groups are inserted into |category_groups|. | 325 // reached. The known category groups are inserted into |category_groups|. |
310 void GetKnownCategoryGroups(std::vector<std::string>* category_groups); | 326 void GetKnownCategoryGroups(std::vector<std::string>* category_groups); |
311 | 327 |
312 // Retrieves the current CategoryFilter. | 328 // Retrieves the current CategoryFilter. |
313 const CategoryFilter& GetCurrentCategoryFilter(); | 329 const CategoryFilter& GetCurrentCategoryFilter(); |
314 | 330 |
315 Options trace_options() const { return trace_options_; } | 331 Options trace_options() const { |
332 return static_cast<Options>(subtle::NoBarrier_Load(&trace_options_)); | |
333 } | |
316 | 334 |
317 // Enables tracing. See CategoryFilter comments for details | 335 // Enables tracing. See CategoryFilter comments for details |
318 // on how to control what categories will be traced. | 336 // on how to control what categories will be traced. |
319 void SetEnabled(const CategoryFilter& category_filter, Options options); | 337 void SetEnabled(const CategoryFilter& category_filter, Options options); |
320 | 338 |
321 // Disable tracing for all categories. | 339 // Disable tracing for all categories. |
322 void SetDisabled(); | 340 void SetDisabled(); |
323 bool IsEnabled() { return !!enable_count_; } | 341 bool IsEnabled() { return !!enable_count_; } |
324 | 342 |
325 // The number of times we have begun recording traces. If tracing is off, | 343 // The number of times we have begun recording traces. If tracing is off, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
371 const char* name, | 389 const char* name, |
372 unsigned long long id, | 390 unsigned long long id, |
373 int num_args, | 391 int num_args, |
374 const char* const arg_names[], | 392 const char* const arg_names[], |
375 const unsigned char arg_types[], | 393 const unsigned char arg_types[], |
376 const unsigned long long arg_values[], | 394 const unsigned long long arg_values[], |
377 unsigned char flags); | 395 unsigned char flags); |
378 void SetEventCallback(EventCallback cb); | 396 void SetEventCallback(EventCallback cb); |
379 | 397 |
380 // Flush all collected events to the given output callback. The callback will | 398 // Flush all collected events to the given output callback. The callback will |
381 // be called one or more times with IPC-bite-size chunks. The string format is | 399 // be called one or more times either synchronously or asynchronously from |
400 // the current thread with IPC-bite-size chunks. The string format is | |
382 // undefined. Use TraceResultBuffer to convert one or more trace strings to | 401 // undefined. Use TraceResultBuffer to convert one or more trace strings to |
383 // JSON. | 402 // JSON. Note: If called when tracing is enabled, the callback will be called |
384 typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)> | 403 // directly with (empty_string, false). |
dsinclair
2013/08/29 14:24:32
Confused about the false. So, if we call when trac
Xianzhu
2013/08/29 17:42:12
Added comments:
Due to the implementation of threa
| |
385 OutputCallback; | 404 typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&, |
405 bool has_more_events)> OutputCallback; | |
386 void Flush(const OutputCallback& cb); | 406 void Flush(const OutputCallback& cb); |
387 | 407 |
388 // Called by TRACE_EVENT* macros, don't call this directly. | 408 // Called by TRACE_EVENT* macros, don't call this directly. |
389 // The name parameter is a category group for example: | 409 // The name parameter is a category group for example: |
390 // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent") | 410 // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent") |
391 static const unsigned char* GetCategoryGroupEnabled(const char* name); | 411 static const unsigned char* GetCategoryGroupEnabled(const char* name); |
392 static const char* GetCategoryGroupName( | 412 static const char* GetCategoryGroupName( |
393 const unsigned char* category_group_enabled); | 413 const unsigned char* category_group_enabled); |
394 | 414 |
395 // Called by TRACE_EVENT* macros, don't call this directly. | 415 // Called by TRACE_EVENT* macros, don't call this directly. |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
522 // notifications from previous calls to AddNotificationWhileLocked, this | 542 // notifications from previous calls to AddNotificationWhileLocked, this |
523 // will call the NotificationCallback. | 543 // will call the NotificationCallback. |
524 inline void SendNotificationIfAny(); | 544 inline void SendNotificationIfAny(); |
525 | 545 |
526 private: | 546 private: |
527 TraceLog* trace_log_; | 547 TraceLog* trace_log_; |
528 NotificationCallback callback_copy_; | 548 NotificationCallback callback_copy_; |
529 int notification_; | 549 int notification_; |
530 }; | 550 }; |
531 | 551 |
552 class ThreadLocalEventBuffer; | |
553 | |
532 TraceLog(); | 554 TraceLog(); |
533 ~TraceLog(); | 555 ~TraceLog(); |
534 const unsigned char* GetCategoryGroupEnabledInternal(const char* name); | 556 const unsigned char* GetCategoryGroupEnabledInternal(const char* name); |
535 void AddMetadataEvents(); | 557 void AddMetadataEvents(); |
536 | 558 |
537 #if defined(OS_ANDROID) | 559 #if defined(OS_ANDROID) |
538 void SendToATrace(char phase, | 560 void SendToATrace(char phase, |
539 const char* category_group, | 561 const char* category_group, |
540 const char* name, | 562 const char* name, |
541 unsigned long long id, | 563 unsigned long long id, |
542 int num_args, | 564 int num_args, |
543 const char** arg_names, | 565 const char** arg_names, |
544 const unsigned char* arg_types, | 566 const unsigned char* arg_types, |
545 const unsigned long long* arg_values, | 567 const unsigned long long* arg_values, |
546 scoped_ptr<ConvertableToTraceFormat> convertable_values[], | 568 scoped_ptr<ConvertableToTraceFormat> convertable_values[], |
547 unsigned char flags); | 569 unsigned char flags); |
548 static void ApplyATraceEnabledFlag(unsigned char* category_group_enabled); | 570 static void ApplyATraceEnabledFlag(unsigned char* category_group_enabled); |
549 #endif | 571 #endif |
550 | 572 |
551 TraceBuffer* GetTraceBuffer(); | 573 TraceBuffer* GetTraceBuffer(); |
552 | 574 |
553 // TODO(nduca): switch to per-thread trace buffers to reduce thread | 575 void AddEventToMainBufferWhileLocked(const TraceEvent& trace_event); |
554 // synchronization. | 576 void CheckIfBufferIsFullWhileLocked(NotificationHelper* notifier); |
577 void FlushNextThreadOrFinish(); | |
578 void FlushCurrentThreadAndContinue(); | |
579 | |
555 // This lock protects TraceLog member accesses from arbitrary threads. | 580 // This lock protects TraceLog member accesses from arbitrary threads. |
556 Lock lock_; | 581 Lock lock_; |
582 int locked_line_; | |
557 int enable_count_; | 583 int enable_count_; |
558 int num_traces_recorded_; | 584 int num_traces_recorded_; |
585 subtle::AtomicWord /* bool */ buffer_is_full_; | |
559 NotificationCallback notification_callback_; | 586 NotificationCallback notification_callback_; |
560 scoped_ptr<TraceBuffer> logged_events_; | 587 scoped_ptr<TraceBuffer> logged_events_; |
561 EventCallback event_callback_; | 588 subtle::AtomicWord /* EventCallback */ event_callback_; |
562 bool dispatching_to_observer_list_; | 589 bool dispatching_to_observer_list_; |
563 std::vector<EnabledStateObserver*> enabled_state_observer_list_; | 590 std::vector<EnabledStateObserver*> enabled_state_observer_list_; |
564 | 591 |
565 std::string process_name_; | 592 std::string process_name_; |
566 base::hash_map<int, std::string> process_labels_; | 593 base::hash_map<int, std::string> process_labels_; |
567 int process_sort_index_; | 594 int process_sort_index_; |
568 base::hash_map<int, int> thread_sort_indices_; | 595 base::hash_map<int, int> thread_sort_indices_; |
596 base::hash_map<int, std::string> thread_names_; | |
569 | 597 |
570 base::hash_map<int, std::string> thread_names_; | 598 // The following two maps are used only when ECHO_TO_CONSOLE. |
571 base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_; | 599 base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_; |
572 base::hash_map<std::string, int> thread_colors_; | 600 base::hash_map<std::string, int> thread_colors_; |
573 | 601 |
574 // XORed with TraceID to make it unlikely to collide with other processes. | 602 // XORed with TraceID to make it unlikely to collide with other processes. |
575 unsigned long long process_id_hash_; | 603 unsigned long long process_id_hash_; |
576 | 604 |
577 int process_id_; | 605 int process_id_; |
578 | 606 |
579 TimeDelta time_offset_; | 607 TimeDelta time_offset_; |
580 | 608 |
581 // Allow tests to wake up when certain events occur. | 609 // Allow tests to wake up when certain events occur. |
582 const unsigned char* watch_category_; | 610 subtle::AtomicWord /* const unsigned char* */ watch_category_; |
583 std::string watch_event_name_; | 611 std::string watch_event_name_; |
584 | 612 |
585 Options trace_options_; | 613 subtle::AtomicWord /* Options */ trace_options_; |
586 | 614 |
587 // Sampling thread handles. | 615 // Sampling thread handles. |
588 scoped_ptr<TraceSamplingThread> sampling_thread_; | 616 scoped_ptr<TraceSamplingThread> sampling_thread_; |
589 PlatformThreadHandle sampling_thread_handle_; | 617 PlatformThreadHandle sampling_thread_handle_; |
590 | 618 |
591 CategoryFilter category_filter_; | 619 CategoryFilter category_filter_; |
592 | 620 |
621 ThreadLocalPointer<ThreadLocalEventBuffer> thread_local_event_buffer_; | |
622 | |
623 // Contains the message loops of threads that have had at least one event | |
624 // added into the local event buffer. Not using MessageLoopProxy because we | |
625 // need to know the life time of the message loops. | |
626 base::hash_set<MessageLoop*> thread_message_loops_; | |
627 | |
628 // Set when asynchronous Flush is in progress. | |
629 OutputCallback flush_output_callback_; | |
630 scoped_refptr<MessageLoopProxy> flush_message_loop_proxy_; | |
631 | |
593 DISALLOW_COPY_AND_ASSIGN(TraceLog); | 632 DISALLOW_COPY_AND_ASSIGN(TraceLog); |
594 }; | 633 }; |
595 | 634 |
596 } // namespace debug | 635 } // namespace debug |
597 } // namespace base | 636 } // namespace base |
598 | 637 |
599 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ | 638 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ |
OLD | NEW |