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> |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 | 345 |
346 StringList included_; | 346 StringList included_; |
347 StringList disabled_; | 347 StringList disabled_; |
348 StringList excluded_; | 348 StringList excluded_; |
349 }; | 349 }; |
350 | 350 |
351 class TraceSamplingThread; | 351 class TraceSamplingThread; |
352 | 352 |
353 class BASE_EXPORT TraceLog { | 353 class BASE_EXPORT TraceLog { |
354 public: | 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 |
355 // Options determines how the trace buffer stores data. | 365 // Options determines how the trace buffer stores data. |
356 enum Options { | 366 enum Options { |
357 // Record until the trace buffer is full. | 367 // Record until the trace buffer is full. |
358 RECORD_UNTIL_FULL = 1 << 0, | 368 RECORD_UNTIL_FULL = 1 << 0, |
359 | 369 |
360 // Record until the user ends the trace. The trace buffer is a fixed size | 370 // Record until the user ends the trace. The trace buffer is a fixed size |
361 // and we use it as a ring buffer during recording. | 371 // and we use it as a ring buffer during recording. |
362 RECORD_CONTINUOUSLY = 1 << 1, | 372 RECORD_CONTINUOUSLY = 1 << 1, |
363 | 373 |
364 // Enable the sampling profiler in the recording mode. | 374 // Enable the sampling profiler in the recording mode. |
(...skipping 11 matching lines...) Expand all Loading... |
376 // The TRACE_EVENT macros should only use the value as a bool. | 386 // The TRACE_EVENT macros should only use the value as a bool. |
377 enum CategoryGroupEnabledFlags { | 387 enum CategoryGroupEnabledFlags { |
378 // Normal enabled flag for category groups enabled by SetEnabled(). | 388 // Normal enabled flag for category groups enabled by SetEnabled(). |
379 ENABLED_FOR_RECORDING = 1 << 0, | 389 ENABLED_FOR_RECORDING = 1 << 0, |
380 // Category group enabled by SetEventCallbackEnabled(). | 390 // Category group enabled by SetEventCallbackEnabled(). |
381 ENABLED_FOR_EVENT_CALLBACK = 1 << 1, | 391 ENABLED_FOR_EVENT_CALLBACK = 1 << 1, |
382 }; | 392 }; |
383 | 393 |
384 static TraceLog* GetInstance(); | 394 static TraceLog* GetInstance(); |
385 | 395 |
| 396 // Convert the given string to trace options. Defaults to RECORD_UNTIL_FULL if |
| 397 // the string does not provide valid options. |
| 398 static Options TraceOptionsFromString(const std::string& str); |
| 399 |
386 // Get set of known category groups. This can change as new code paths are | 400 // Get set of known category groups. This can change as new code paths are |
387 // reached. The known category groups are inserted into |category_groups|. | 401 // reached. The known category groups are inserted into |category_groups|. |
388 void GetKnownCategoryGroups(std::vector<std::string>* category_groups); | 402 void GetKnownCategoryGroups(std::vector<std::string>* category_groups); |
389 | 403 |
390 // Retrieves a copy (for thread-safety) of the current CategoryFilter. | 404 // Retrieves a copy (for thread-safety) of the current CategoryFilter. |
391 CategoryFilter GetCurrentCategoryFilter(); | 405 CategoryFilter GetCurrentCategoryFilter(); |
392 | 406 |
393 Options trace_options() const { | 407 Options trace_options() const { |
394 return static_cast<Options>(subtle::NoBarrier_Load(&trace_options_)); | 408 return static_cast<Options>(subtle::NoBarrier_Load(&trace_options_)); |
395 } | 409 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 | 443 |
430 // Called just after the tracing system disables, outside of the |lock_|. | 444 // Called just after the tracing system disables, outside of the |lock_|. |
431 // TraceLog::IsEnabled() is false at this point. | 445 // TraceLog::IsEnabled() is false at this point. |
432 virtual void OnTraceLogDisabled() = 0; | 446 virtual void OnTraceLogDisabled() = 0; |
433 }; | 447 }; |
434 void AddEnabledStateObserver(EnabledStateObserver* listener); | 448 void AddEnabledStateObserver(EnabledStateObserver* listener); |
435 void RemoveEnabledStateObserver(EnabledStateObserver* listener); | 449 void RemoveEnabledStateObserver(EnabledStateObserver* listener); |
436 bool HasEnabledStateObserver(EnabledStateObserver* listener) const; | 450 bool HasEnabledStateObserver(EnabledStateObserver* listener) const; |
437 | 451 |
438 float GetBufferPercentFull() const; | 452 float GetBufferPercentFull() const; |
439 bool BufferIsFull() const; | 453 |
| 454 // Set the thread-safe notification callback. The callback can occur at any |
| 455 // time and from any thread. WARNING: It is possible for the previously set |
| 456 // callback to be called during OR AFTER a call to SetNotificationCallback. |
| 457 // Therefore, the target of the callback must either be a global function, |
| 458 // ref-counted object or a LazyInstance with Leaky traits (or equivalent). |
| 459 typedef base::Callback<void(int)> NotificationCallback; |
| 460 void SetNotificationCallback(const NotificationCallback& cb); |
440 | 461 |
441 // Not using base::Callback because of its limited by 7 parameters. | 462 // Not using base::Callback because of its limited by 7 parameters. |
442 // Also, using primitive type allows directly passing callback from WebCore. | 463 // Also, using primitive type allows directly passing callback from WebCore. |
443 // WARNING: It is possible for the previously set callback to be called | 464 // WARNING: It is possible for the previously set callback to be called |
444 // after a call to SetEventCallbackEnabled() that replaces or a call to | 465 // after a call to SetEventCallbackEnabled() that replaces or a call to |
445 // SetEventCallbackDisabled() that disables the callback. | 466 // SetEventCallbackDisabled() that disables the callback. |
446 // This callback may be invoked on any thread. | 467 // This callback may be invoked on any thread. |
447 // For TRACE_EVENT_PHASE_COMPLETE events, the client will still receive pairs | 468 // For TRACE_EVENT_PHASE_COMPLETE events, the client will still receive pairs |
448 // of TRACE_EVENT_PHASE_BEGIN and TRACE_EVENT_PHASE_END events to keep the | 469 // of TRACE_EVENT_PHASE_BEGIN and TRACE_EVENT_PHASE_END events to keep the |
449 // interface simple. | 470 // interface simple. |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 const char* extra); | 538 const char* extra); |
518 static void AddTraceEventEtw(char phase, | 539 static void AddTraceEventEtw(char phase, |
519 const char* category_group, | 540 const char* category_group, |
520 const void* id, | 541 const void* id, |
521 const std::string& extra); | 542 const std::string& extra); |
522 | 543 |
523 void UpdateTraceEventDuration(const unsigned char* category_group_enabled, | 544 void UpdateTraceEventDuration(const unsigned char* category_group_enabled, |
524 const char* name, | 545 const char* name, |
525 TraceEventHandle handle); | 546 TraceEventHandle handle); |
526 | 547 |
527 // For every matching event, the callback will be called. | 548 // For every matching event, a notification will be fired. NOTE: the |
528 typedef base::Callback<void()> WatchEventCallback; | 549 // notification will fire for each matching event that has already occurred |
| 550 // since tracing was started (including before tracing if the process was |
| 551 // started with tracing turned on). |
529 void SetWatchEvent(const std::string& category_name, | 552 void SetWatchEvent(const std::string& category_name, |
530 const std::string& event_name, | 553 const std::string& event_name); |
531 const WatchEventCallback& callback); | |
532 // Cancel the watch event. If tracing is enabled, this may race with the | 554 // Cancel the watch event. If tracing is enabled, this may race with the |
533 // watch event notification firing. | 555 // watch event notification firing. |
534 void CancelWatchEvent(); | 556 void CancelWatchEvent(); |
535 | 557 |
536 int process_id() const { return process_id_; } | 558 int process_id() const { return process_id_; } |
537 | 559 |
538 // Exposed for unittesting: | 560 // Exposed for unittesting: |
539 | 561 |
540 void WaitSamplingEventForTesting(); | 562 void WaitSamplingEventForTesting(); |
541 | 563 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 friend struct DefaultSingletonTraits<TraceLog>; | 612 friend struct DefaultSingletonTraits<TraceLog>; |
591 | 613 |
592 // Enable/disable each category group based on the current enabled_, | 614 // Enable/disable each category group based on the current enabled_, |
593 // category_filter_, event_callback_ and event_callback_category_filter_. | 615 // category_filter_, event_callback_ and event_callback_category_filter_. |
594 // Enable the category group if enabled_ is true and category_filter_ matches | 616 // Enable the category group if enabled_ is true and category_filter_ matches |
595 // the category group, or event_callback_ is not null and | 617 // the category group, or event_callback_ is not null and |
596 // event_callback_category_filter_ matches the category group. | 618 // event_callback_category_filter_ matches the category group. |
597 void UpdateCategoryGroupEnabledFlags(); | 619 void UpdateCategoryGroupEnabledFlags(); |
598 void UpdateCategoryGroupEnabledFlag(int category_index); | 620 void UpdateCategoryGroupEnabledFlag(int category_index); |
599 | 621 |
| 622 // Helper class for managing notification_thread_count_ and running |
| 623 // notification callbacks. This is very similar to a reader-writer lock, but |
| 624 // shares the lock with TraceLog and manages the notification flags. |
| 625 class NotificationHelper { |
| 626 public: |
| 627 inline explicit NotificationHelper(TraceLog* trace_log); |
| 628 inline ~NotificationHelper(); |
| 629 |
| 630 // Called only while TraceLog::lock_ is held. This ORs the given |
| 631 // notification with any existing notifications. |
| 632 inline void AddNotificationWhileLocked(int notification); |
| 633 |
| 634 // Called only while TraceLog::lock_ is NOT held. If there are any pending |
| 635 // notifications from previous calls to AddNotificationWhileLocked, this |
| 636 // will call the NotificationCallback. |
| 637 inline void SendNotificationIfAny(); |
| 638 |
| 639 private: |
| 640 TraceLog* trace_log_; |
| 641 NotificationCallback callback_copy_; |
| 642 int notification_; |
| 643 }; |
| 644 |
600 class ThreadLocalEventBuffer; | 645 class ThreadLocalEventBuffer; |
601 class OptionalAutoLock; | 646 class OptionalAutoLock; |
602 | 647 |
603 TraceLog(); | 648 TraceLog(); |
604 ~TraceLog(); | 649 ~TraceLog(); |
605 const unsigned char* GetCategoryGroupEnabledInternal(const char* name); | 650 const unsigned char* GetCategoryGroupEnabledInternal(const char* name); |
606 void AddMetadataEventsWhileLocked(); | 651 void AddMetadataEventsWhileLocked(); |
607 | 652 |
608 TraceBuffer* trace_buffer() const { return logged_events_.get(); } | 653 TraceBuffer* trace_buffer() const { return logged_events_.get(); } |
609 TraceBuffer* CreateTraceBuffer(); | 654 TraceBuffer* CreateTraceBuffer(); |
610 | 655 |
611 void OutputEventToConsoleWhileLocked(unsigned char phase, | 656 void OutputEventToConsoleWhileLocked(unsigned char phase, |
612 const TimeTicks& timestamp, | 657 const TimeTicks& timestamp, |
613 TraceEvent* trace_event); | 658 TraceEvent* trace_event); |
614 | 659 |
615 TraceEvent* AddEventToThreadSharedChunkWhileLocked(TraceEventHandle* handle, | 660 TraceEvent* AddEventToThreadSharedChunkWhileLocked( |
616 bool check_buffer_is_full); | 661 NotificationHelper* notifier, TraceEventHandle* handle); |
617 void CheckIfBufferIsFullWhileLocked(); | 662 void CheckIfBufferIsFullWhileLocked(NotificationHelper* notifier); |
618 void SetDisabledWhileLocked(); | |
619 | 663 |
620 TraceEvent* GetEventByHandleInternal(TraceEventHandle handle, | 664 TraceEvent* GetEventByHandleInternal(TraceEventHandle handle, |
621 OptionalAutoLock* lock); | 665 OptionalAutoLock* lock); |
622 | 666 |
623 // |generation| is used in the following callbacks to check if the callback | 667 // |generation| is used in the following callbacks to check if the callback |
624 // is called for the flush of the current |logged_events_|. | 668 // is called for the flush of the current |logged_events_|. |
625 void FlushCurrentThread(int generation); | 669 void FlushCurrentThread(int generation); |
626 void ConvertTraceEventsToTraceFormat(scoped_ptr<TraceBuffer> logged_events, | 670 void ConvertTraceEventsToTraceFormat(scoped_ptr<TraceBuffer> logged_events, |
627 const TraceLog::OutputCallback& flush_output_callback); | 671 const TraceLog::OutputCallback& flush_output_callback); |
628 void FinishFlush(int generation); | 672 void FinishFlush(int generation); |
(...skipping 10 matching lines...) Expand all Loading... |
639 } | 683 } |
640 | 684 |
641 TimeTicks OffsetNow() const { | 685 TimeTicks OffsetNow() const { |
642 return OffsetTimestamp(TimeTicks::NowFromSystemTraceTime()); | 686 return OffsetTimestamp(TimeTicks::NowFromSystemTraceTime()); |
643 } | 687 } |
644 TimeTicks OffsetTimestamp(const TimeTicks& timestamp) const { | 688 TimeTicks OffsetTimestamp(const TimeTicks& timestamp) const { |
645 return timestamp - time_offset_; | 689 return timestamp - time_offset_; |
646 } | 690 } |
647 | 691 |
648 // This lock protects TraceLog member accesses from arbitrary threads. | 692 // This lock protects TraceLog member accesses from arbitrary threads. |
649 mutable Lock lock_; | 693 Lock lock_; |
650 int locked_line_; | 694 int locked_line_; |
651 bool enabled_; | 695 bool enabled_; |
652 int num_traces_recorded_; | 696 int num_traces_recorded_; |
| 697 subtle::AtomicWord /* bool */ buffer_is_full_; |
| 698 NotificationCallback notification_callback_; |
653 scoped_ptr<TraceBuffer> logged_events_; | 699 scoped_ptr<TraceBuffer> logged_events_; |
654 subtle::AtomicWord /* EventCallback */ event_callback_; | 700 subtle::AtomicWord /* EventCallback */ event_callback_; |
655 bool dispatching_to_observer_list_; | 701 bool dispatching_to_observer_list_; |
656 std::vector<EnabledStateObserver*> enabled_state_observer_list_; | 702 std::vector<EnabledStateObserver*> enabled_state_observer_list_; |
657 | 703 |
658 std::string process_name_; | 704 std::string process_name_; |
659 base::hash_map<int, std::string> process_labels_; | 705 base::hash_map<int, std::string> process_labels_; |
660 int process_sort_index_; | 706 int process_sort_index_; |
661 base::hash_map<int, int> thread_sort_indices_; | 707 base::hash_map<int, int> thread_sort_indices_; |
662 base::hash_map<int, std::string> thread_names_; | 708 base::hash_map<int, std::string> thread_names_; |
663 | 709 |
664 // The following two maps are used only when ECHO_TO_CONSOLE. | 710 // The following two maps are used only when ECHO_TO_CONSOLE. |
665 base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_; | 711 base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_; |
666 base::hash_map<std::string, int> thread_colors_; | 712 base::hash_map<std::string, int> thread_colors_; |
667 | 713 |
668 // XORed with TraceID to make it unlikely to collide with other processes. | 714 // XORed with TraceID to make it unlikely to collide with other processes. |
669 unsigned long long process_id_hash_; | 715 unsigned long long process_id_hash_; |
670 | 716 |
671 int process_id_; | 717 int process_id_; |
672 | 718 |
673 TimeDelta time_offset_; | 719 TimeDelta time_offset_; |
674 | 720 |
675 // Allow tests to wake up when certain events occur. | 721 // Allow tests to wake up when certain events occur. |
676 WatchEventCallback watch_event_callback_; | |
677 subtle::AtomicWord /* const unsigned char* */ watch_category_; | 722 subtle::AtomicWord /* const unsigned char* */ watch_category_; |
678 std::string watch_event_name_; | 723 std::string watch_event_name_; |
679 | 724 |
680 subtle::AtomicWord /* Options */ trace_options_; | 725 subtle::AtomicWord /* Options */ trace_options_; |
681 | 726 |
682 // Sampling thread handles. | 727 // Sampling thread handles. |
683 scoped_ptr<TraceSamplingThread> sampling_thread_; | 728 scoped_ptr<TraceSamplingThread> sampling_thread_; |
684 PlatformThreadHandle sampling_thread_handle_; | 729 PlatformThreadHandle sampling_thread_handle_; |
685 | 730 |
686 CategoryFilter category_filter_; | 731 CategoryFilter category_filter_; |
(...skipping 17 matching lines...) Expand all Loading... |
704 scoped_refptr<MessageLoopProxy> flush_message_loop_proxy_; | 749 scoped_refptr<MessageLoopProxy> flush_message_loop_proxy_; |
705 subtle::AtomicWord generation_; | 750 subtle::AtomicWord generation_; |
706 | 751 |
707 DISALLOW_COPY_AND_ASSIGN(TraceLog); | 752 DISALLOW_COPY_AND_ASSIGN(TraceLog); |
708 }; | 753 }; |
709 | 754 |
710 } // namespace debug | 755 } // namespace debug |
711 } // namespace base | 756 } // namespace base |
712 | 757 |
713 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ | 758 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ |
OLD | NEW |