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