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