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 } // BASE_HASH_NAMESPACE |
| 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. The callback can be null if the caller doesn't want any data. |
384 typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)> | 403 // Due to the implementation of thread-local buffers, flush can't be |
385 OutputCallback; | 404 // done when tracing is enabled. If called when tracing is enabled, the |
| 405 // callback will be called directly with (empty_string, false) to indicate |
| 406 // the end of this unsuccessful flush. |
| 407 typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&, |
| 408 bool has_more_events)> OutputCallback; |
386 void Flush(const OutputCallback& cb); | 409 void Flush(const OutputCallback& cb); |
387 | 410 |
388 // Called by TRACE_EVENT* macros, don't call this directly. | 411 // Called by TRACE_EVENT* macros, don't call this directly. |
389 // The name parameter is a category group for example: | 412 // The name parameter is a category group for example: |
390 // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent") | 413 // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent") |
391 static const unsigned char* GetCategoryGroupEnabled(const char* name); | 414 static const unsigned char* GetCategoryGroupEnabled(const char* name); |
392 static const char* GetCategoryGroupName( | 415 static const char* GetCategoryGroupName( |
393 const unsigned char* category_group_enabled); | 416 const unsigned char* category_group_enabled); |
394 | 417 |
395 // Called by TRACE_EVENT* macros, don't call this directly. | 418 // 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 | 545 // notifications from previous calls to AddNotificationWhileLocked, this |
523 // will call the NotificationCallback. | 546 // will call the NotificationCallback. |
524 inline void SendNotificationIfAny(); | 547 inline void SendNotificationIfAny(); |
525 | 548 |
526 private: | 549 private: |
527 TraceLog* trace_log_; | 550 TraceLog* trace_log_; |
528 NotificationCallback callback_copy_; | 551 NotificationCallback callback_copy_; |
529 int notification_; | 552 int notification_; |
530 }; | 553 }; |
531 | 554 |
| 555 class ThreadLocalEventBuffer; |
| 556 |
532 TraceLog(); | 557 TraceLog(); |
533 ~TraceLog(); | 558 ~TraceLog(); |
534 const unsigned char* GetCategoryGroupEnabledInternal(const char* name); | 559 const unsigned char* GetCategoryGroupEnabledInternal(const char* name); |
535 void AddMetadataEvents(); | 560 void AddMetadataEvents(); |
536 | 561 |
537 #if defined(OS_ANDROID) | 562 #if defined(OS_ANDROID) |
538 void SendToATrace(char phase, | 563 void SendToATrace(char phase, |
539 const char* category_group, | 564 const char* category_group, |
540 const char* name, | 565 const char* name, |
541 unsigned long long id, | 566 unsigned long long id, |
542 int num_args, | 567 int num_args, |
543 const char** arg_names, | 568 const char** arg_names, |
544 const unsigned char* arg_types, | 569 const unsigned char* arg_types, |
545 const unsigned long long* arg_values, | 570 const unsigned long long* arg_values, |
546 scoped_ptr<ConvertableToTraceFormat> convertable_values[], | 571 scoped_ptr<ConvertableToTraceFormat> convertable_values[], |
547 unsigned char flags); | 572 unsigned char flags); |
548 static void ApplyATraceEnabledFlag(unsigned char* category_group_enabled); | 573 static void ApplyATraceEnabledFlag(unsigned char* category_group_enabled); |
549 #endif | 574 #endif |
550 | 575 |
551 TraceBuffer* GetTraceBuffer(); | 576 TraceBuffer* GetTraceBuffer(); |
552 | 577 |
553 // TODO(nduca): switch to per-thread trace buffers to reduce thread | 578 void AddEventToMainBufferWhileLocked(const TraceEvent& trace_event); |
554 // synchronization. | 579 void CheckIfBufferIsFullWhileLocked(NotificationHelper* notifier); |
| 580 // |flush_count| is used in the following callbacks to check if the callback |
| 581 // is called for the current flush. |
| 582 void FlushCurrentThread(int flush_count); |
| 583 void FinishFlush(int flush_count); |
| 584 void OnFlushTimeout(int flush_count); |
| 585 |
555 // This lock protects TraceLog member accesses from arbitrary threads. | 586 // This lock protects TraceLog member accesses from arbitrary threads. |
556 Lock lock_; | 587 Lock lock_; |
| 588 int locked_line_; |
557 int enable_count_; | 589 int enable_count_; |
558 int num_traces_recorded_; | 590 int num_traces_recorded_; |
| 591 subtle::AtomicWord /* bool */ buffer_is_full_; |
559 NotificationCallback notification_callback_; | 592 NotificationCallback notification_callback_; |
560 scoped_ptr<TraceBuffer> logged_events_; | 593 scoped_ptr<TraceBuffer> logged_events_; |
561 EventCallback event_callback_; | 594 subtle::AtomicWord /* EventCallback */ event_callback_; |
562 bool dispatching_to_observer_list_; | 595 bool dispatching_to_observer_list_; |
563 std::vector<EnabledStateObserver*> enabled_state_observer_list_; | 596 std::vector<EnabledStateObserver*> enabled_state_observer_list_; |
564 | 597 |
565 std::string process_name_; | 598 std::string process_name_; |
566 base::hash_map<int, std::string> process_labels_; | 599 base::hash_map<int, std::string> process_labels_; |
567 int process_sort_index_; | 600 int process_sort_index_; |
568 base::hash_map<int, int> thread_sort_indices_; | 601 base::hash_map<int, int> thread_sort_indices_; |
| 602 base::hash_map<int, std::string> thread_names_; |
569 | 603 |
570 base::hash_map<int, std::string> thread_names_; | 604 // The following two maps are used only when ECHO_TO_CONSOLE. |
571 base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_; | 605 base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_; |
572 base::hash_map<std::string, int> thread_colors_; | 606 base::hash_map<std::string, int> thread_colors_; |
573 | 607 |
574 // XORed with TraceID to make it unlikely to collide with other processes. | 608 // XORed with TraceID to make it unlikely to collide with other processes. |
575 unsigned long long process_id_hash_; | 609 unsigned long long process_id_hash_; |
576 | 610 |
577 int process_id_; | 611 int process_id_; |
578 | 612 |
579 TimeDelta time_offset_; | 613 TimeDelta time_offset_; |
580 | 614 |
581 // Allow tests to wake up when certain events occur. | 615 // Allow tests to wake up when certain events occur. |
582 const unsigned char* watch_category_; | 616 subtle::AtomicWord /* const unsigned char* */ watch_category_; |
583 std::string watch_event_name_; | 617 std::string watch_event_name_; |
584 | 618 |
585 Options trace_options_; | 619 subtle::AtomicWord /* Options */ trace_options_; |
586 | 620 |
587 // Sampling thread handles. | 621 // Sampling thread handles. |
588 scoped_ptr<TraceSamplingThread> sampling_thread_; | 622 scoped_ptr<TraceSamplingThread> sampling_thread_; |
589 PlatformThreadHandle sampling_thread_handle_; | 623 PlatformThreadHandle sampling_thread_handle_; |
590 | 624 |
591 CategoryFilter category_filter_; | 625 CategoryFilter category_filter_; |
592 | 626 |
| 627 ThreadLocalPointer<ThreadLocalEventBuffer> thread_local_event_buffer_; |
| 628 |
| 629 // Contains the message loops of threads that have had at least one event |
| 630 // added into the local event buffer. Not using MessageLoopProxy because we |
| 631 // need to know the life time of the message loops. |
| 632 base::hash_set<MessageLoop*> thread_message_loops_; |
| 633 |
| 634 // Set when asynchronous Flush is in progress. |
| 635 OutputCallback flush_output_callback_; |
| 636 scoped_refptr<MessageLoopProxy> flush_message_loop_proxy_; |
| 637 int flush_count_; |
| 638 |
593 DISALLOW_COPY_AND_ASSIGN(TraceLog); | 639 DISALLOW_COPY_AND_ASSIGN(TraceLog); |
594 }; | 640 }; |
595 | 641 |
596 } // namespace debug | 642 } // namespace debug |
597 } // namespace base | 643 } // namespace base |
598 | 644 |
599 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ | 645 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ |
OLD | NEW |