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