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. |
375 ENABLE_SAMPLING = 1 << 2, | 365 ENABLE_SAMPLING = 1 << 2, |
376 | 366 |
377 // Enable the sampling profiler in the monitoring mode. | 367 // Enable the sampling profiler in the monitoring mode. |
378 MONITOR_SAMPLING = 1 << 3, | 368 MONITOR_SAMPLING = 1 << 3, |
379 | 369 |
380 // Echo to console. Events are discarded. | 370 // Echo to console. Events are discarded. |
381 ECHO_TO_CONSOLE = 1 << 4, | 371 ECHO_TO_CONSOLE = 1 << 4, |
382 }; | 372 }; |
383 | 373 |
384 static TraceLog* GetInstance(); | 374 static TraceLog* GetInstance(); |
385 | 375 |
386 // Convert the given string to trace options. Defaults to RECORD_UNTIL_FULL if | |
387 // the string does not provide valid options. | |
388 static Options TraceOptionsFromString(const std::string& str); | |
389 | |
390 // Get set of known category groups. This can change as new code paths are | 376 // Get set of known category groups. This can change as new code paths are |
391 // reached. The known category groups are inserted into |category_groups|. | 377 // reached. The known category groups are inserted into |category_groups|. |
392 void GetKnownCategoryGroups(std::vector<std::string>* category_groups); | 378 void GetKnownCategoryGroups(std::vector<std::string>* category_groups); |
393 | 379 |
394 // Retrieves the current CategoryFilter. | 380 // Retrieves the current CategoryFilter. |
395 const CategoryFilter& GetCurrentCategoryFilter(); | 381 const CategoryFilter& GetCurrentCategoryFilter(); |
396 | 382 |
397 Options trace_options() const { | 383 Options trace_options() const { |
398 return static_cast<Options>(subtle::NoBarrier_Load(&trace_options_)); | 384 return static_cast<Options>(subtle::NoBarrier_Load(&trace_options_)); |
399 } | 385 } |
(...skipping 30 matching lines...) Expand all Loading... |
430 | 416 |
431 // Called just after the tracing system disables, outside of the |lock_|. | 417 // Called just after the tracing system disables, outside of the |lock_|. |
432 // TraceLog::IsEnabled() is false at this point. | 418 // TraceLog::IsEnabled() is false at this point. |
433 virtual void OnTraceLogDisabled() = 0; | 419 virtual void OnTraceLogDisabled() = 0; |
434 }; | 420 }; |
435 void AddEnabledStateObserver(EnabledStateObserver* listener); | 421 void AddEnabledStateObserver(EnabledStateObserver* listener); |
436 void RemoveEnabledStateObserver(EnabledStateObserver* listener); | 422 void RemoveEnabledStateObserver(EnabledStateObserver* listener); |
437 bool HasEnabledStateObserver(EnabledStateObserver* listener) const; | 423 bool HasEnabledStateObserver(EnabledStateObserver* listener) const; |
438 | 424 |
439 float GetBufferPercentFull() const; | 425 float GetBufferPercentFull() const; |
440 | 426 bool BufferIsFull() const; |
441 // Set the thread-safe notification callback. The callback can occur at any | |
442 // time and from any thread. WARNING: It is possible for the previously set | |
443 // callback to be called during OR AFTER a call to SetNotificationCallback. | |
444 // Therefore, the target of the callback must either be a global function, | |
445 // ref-counted object or a LazyInstance with Leaky traits (or equivalent). | |
446 typedef base::Callback<void(int)> NotificationCallback; | |
447 void SetNotificationCallback(const NotificationCallback& cb); | |
448 | 427 |
449 // Not using base::Callback because of its limited by 7 parameters. | 428 // Not using base::Callback because of its limited by 7 parameters. |
450 // Also, using primitive type allows directly passing callback from WebCore. | 429 // Also, using primitive type allows directly passing callback from WebCore. |
451 // WARNING: It is possible for the previously set callback to be called | 430 // WARNING: It is possible for the previously set callback to be called |
452 // after a call to SetEventCallback() that replaces or clears the callback. | 431 // after a call to SetEventCallback() that replaces or clears the callback. |
453 // This callback may be invoked on any thread. | 432 // This callback may be invoked on any thread. |
454 // TODO(wangxianzhu): For now for TRACE_EVENT_PHASE_COMPLETE events, the | 433 // TODO(wangxianzhu): For now for TRACE_EVENT_PHASE_COMPLETE events, the |
455 // client will still receive pairs of TRACE_EVENT_PHASE_BEGIN and | 434 // client will still receive pairs of TRACE_EVENT_PHASE_BEGIN and |
456 // TRACE_EVENT_PHASE_END events. Should send TRACE_EVENT_PHASE_COMPLETE | 435 // TRACE_EVENT_PHASE_END events. Should send TRACE_EVENT_PHASE_COMPLETE |
457 // directly to clients if it is beneficial and feasible. | 436 // directly to clients if it is beneficial and feasible. |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 const char* category_group, | 498 const char* category_group, |
520 const void* id, | 499 const void* id, |
521 const char* extra); | 500 const char* extra); |
522 static void AddTraceEventEtw(char phase, | 501 static void AddTraceEventEtw(char phase, |
523 const char* category_group, | 502 const char* category_group, |
524 const void* id, | 503 const void* id, |
525 const std::string& extra); | 504 const std::string& extra); |
526 | 505 |
527 void UpdateTraceEventDuration(TraceEventHandle handle); | 506 void UpdateTraceEventDuration(TraceEventHandle handle); |
528 | 507 |
529 // For every matching event, a notification will be fired. NOTE: the | 508 // For every matching event, the callback will be called. |
530 // notification will fire for each matching event that has already occurred | 509 typedef base::Callback<void()> WatchEventCallback; |
531 // since tracing was started (including before tracing if the process was | |
532 // started with tracing turned on). | |
533 void SetWatchEvent(const std::string& category_name, | 510 void SetWatchEvent(const std::string& category_name, |
534 const std::string& event_name); | 511 const std::string& event_name, |
| 512 const WatchEventCallback& callback); |
535 // Cancel the watch event. If tracing is enabled, this may race with the | 513 // Cancel the watch event. If tracing is enabled, this may race with the |
536 // watch event notification firing. | 514 // watch event notification firing. |
537 void CancelWatchEvent(); | 515 void CancelWatchEvent(); |
538 | 516 |
539 int process_id() const { return process_id_; } | 517 int process_id() const { return process_id_; } |
540 | 518 |
541 // Exposed for unittesting: | 519 // Exposed for unittesting: |
542 | 520 |
543 void WaitSamplingEventForTesting(); | 521 void WaitSamplingEventForTesting(); |
544 | 522 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 friend struct DefaultSingletonTraits<TraceLog>; | 571 friend struct DefaultSingletonTraits<TraceLog>; |
594 | 572 |
595 // Enable/disable each category group based on the current enable_count_ | 573 // Enable/disable each category group based on the current enable_count_ |
596 // and category_filter_. Disable the category group if enabled_count_ is 0, or | 574 // and category_filter_. Disable the category group if enabled_count_ is 0, or |
597 // if the category group contains a category that matches an included category | 575 // if the category group contains a category that matches an included category |
598 // pattern, that category group will be enabled. | 576 // pattern, that category group will be enabled. |
599 // On Android, ATRACE_ENABLED flag will be applied if atrace is started. | 577 // On Android, ATRACE_ENABLED flag will be applied if atrace is started. |
600 void UpdateCategoryGroupEnabledFlags(); | 578 void UpdateCategoryGroupEnabledFlags(); |
601 void UpdateCategoryGroupEnabledFlag(int category_index); | 579 void UpdateCategoryGroupEnabledFlag(int category_index); |
602 | 580 |
603 // Helper class for managing notification_thread_count_ and running | |
604 // notification callbacks. This is very similar to a reader-writer lock, but | |
605 // shares the lock with TraceLog and manages the notification flags. | |
606 class NotificationHelper { | |
607 public: | |
608 inline explicit NotificationHelper(TraceLog* trace_log); | |
609 inline ~NotificationHelper(); | |
610 | |
611 // Called only while TraceLog::lock_ is held. This ORs the given | |
612 // notification with any existing notifications. | |
613 inline void AddNotificationWhileLocked(int notification); | |
614 | |
615 // Called only while TraceLog::lock_ is NOT held. If there are any pending | |
616 // notifications from previous calls to AddNotificationWhileLocked, this | |
617 // will call the NotificationCallback. | |
618 inline void SendNotificationIfAny(); | |
619 | |
620 private: | |
621 TraceLog* trace_log_; | |
622 NotificationCallback callback_copy_; | |
623 int notification_; | |
624 }; | |
625 | |
626 class ThreadLocalEventBuffer; | 581 class ThreadLocalEventBuffer; |
627 class OptionalAutoLock; | 582 class OptionalAutoLock; |
628 | 583 |
629 TraceLog(); | 584 TraceLog(); |
630 ~TraceLog(); | 585 ~TraceLog(); |
631 const unsigned char* GetCategoryGroupEnabledInternal(const char* name); | 586 const unsigned char* GetCategoryGroupEnabledInternal(const char* name); |
632 void AddMetadataEventsWhileLocked(); | 587 void AddMetadataEventsWhileLocked(); |
633 | 588 |
634 TraceBuffer* trace_buffer() const { return logged_events_.get(); } | 589 TraceBuffer* trace_buffer() const { return logged_events_.get(); } |
635 TraceBuffer* CreateTraceBuffer(); | 590 TraceBuffer* CreateTraceBuffer(); |
636 | 591 |
637 void OutputEventToConsoleWhileLocked(unsigned char phase, | 592 void OutputEventToConsoleWhileLocked(unsigned char phase, |
638 const TimeTicks& timestamp, | 593 const TimeTicks& timestamp, |
639 TraceEvent* trace_event); | 594 TraceEvent* trace_event); |
640 | 595 |
641 TraceEvent* AddEventToThreadSharedChunkWhileLocked( | 596 TraceEvent* AddEventToThreadSharedChunkWhileLocked(TraceEventHandle* handle); |
642 NotificationHelper* notifier, TraceEventHandle* handle); | 597 void CheckIfBufferIsFullWhileLocked(); |
643 void CheckIfBufferIsFullWhileLocked(NotificationHelper* notifier); | |
644 | 598 |
645 TraceEvent* GetEventByHandleInternal(TraceEventHandle handle, | 599 TraceEvent* GetEventByHandleInternal(TraceEventHandle handle, |
646 OptionalAutoLock* lock); | 600 OptionalAutoLock* lock); |
647 | 601 |
648 // |generation| is used in the following callbacks to check if the callback | 602 // |generation| is used in the following callbacks to check if the callback |
649 // is called for the flush of the current |logged_events_|. | 603 // is called for the flush of the current |logged_events_|. |
650 void FlushCurrentThread(int generation); | 604 void FlushCurrentThread(int generation); |
651 void ConvertTraceEventsToTraceFormat(scoped_ptr<TraceBuffer> logged_events, | 605 void ConvertTraceEventsToTraceFormat(scoped_ptr<TraceBuffer> logged_events, |
652 const TraceLog::OutputCallback& flush_output_callback); | 606 const TraceLog::OutputCallback& flush_output_callback); |
653 void FinishFlush(int generation); | 607 void FinishFlush(int generation); |
(...skipping 10 matching lines...) Expand all Loading... |
664 } | 618 } |
665 | 619 |
666 TimeTicks OffsetNow() const { | 620 TimeTicks OffsetNow() const { |
667 return OffsetTimestamp(TimeTicks::NowFromSystemTraceTime()); | 621 return OffsetTimestamp(TimeTicks::NowFromSystemTraceTime()); |
668 } | 622 } |
669 TimeTicks OffsetTimestamp(const TimeTicks& timestamp) const { | 623 TimeTicks OffsetTimestamp(const TimeTicks& timestamp) const { |
670 return timestamp - time_offset_; | 624 return timestamp - time_offset_; |
671 } | 625 } |
672 | 626 |
673 // This lock protects TraceLog member accesses from arbitrary threads. | 627 // This lock protects TraceLog member accesses from arbitrary threads. |
674 Lock lock_; | 628 mutable Lock lock_; |
675 int locked_line_; | 629 int locked_line_; |
676 int enable_count_; | 630 int enable_count_; |
677 int num_traces_recorded_; | 631 int num_traces_recorded_; |
678 subtle::AtomicWord /* bool */ buffer_is_full_; | |
679 NotificationCallback notification_callback_; | |
680 scoped_ptr<TraceBuffer> logged_events_; | 632 scoped_ptr<TraceBuffer> logged_events_; |
681 subtle::AtomicWord /* EventCallback */ event_callback_; | 633 subtle::AtomicWord /* EventCallback */ event_callback_; |
682 bool dispatching_to_observer_list_; | 634 bool dispatching_to_observer_list_; |
683 std::vector<EnabledStateObserver*> enabled_state_observer_list_; | 635 std::vector<EnabledStateObserver*> enabled_state_observer_list_; |
684 | 636 |
685 std::string process_name_; | 637 std::string process_name_; |
686 base::hash_map<int, std::string> process_labels_; | 638 base::hash_map<int, std::string> process_labels_; |
687 int process_sort_index_; | 639 int process_sort_index_; |
688 base::hash_map<int, int> thread_sort_indices_; | 640 base::hash_map<int, int> thread_sort_indices_; |
689 base::hash_map<int, std::string> thread_names_; | 641 base::hash_map<int, std::string> thread_names_; |
690 | 642 |
691 // The following two maps are used only when ECHO_TO_CONSOLE. | 643 // The following two maps are used only when ECHO_TO_CONSOLE. |
692 base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_; | 644 base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_; |
693 base::hash_map<std::string, int> thread_colors_; | 645 base::hash_map<std::string, int> thread_colors_; |
694 | 646 |
695 // XORed with TraceID to make it unlikely to collide with other processes. | 647 // XORed with TraceID to make it unlikely to collide with other processes. |
696 unsigned long long process_id_hash_; | 648 unsigned long long process_id_hash_; |
697 | 649 |
698 int process_id_; | 650 int process_id_; |
699 | 651 |
700 TimeDelta time_offset_; | 652 TimeDelta time_offset_; |
701 | 653 |
702 // Allow tests to wake up when certain events occur. | 654 // Allow tests to wake up when certain events occur. |
| 655 WatchEventCallback watch_event_callback_; |
703 subtle::AtomicWord /* const unsigned char* */ watch_category_; | 656 subtle::AtomicWord /* const unsigned char* */ watch_category_; |
704 std::string watch_event_name_; | 657 std::string watch_event_name_; |
705 | 658 |
706 subtle::AtomicWord /* Options */ trace_options_; | 659 subtle::AtomicWord /* Options */ trace_options_; |
707 | 660 |
708 // Sampling thread handles. | 661 // Sampling thread handles. |
709 scoped_ptr<TraceSamplingThread> sampling_thread_; | 662 scoped_ptr<TraceSamplingThread> sampling_thread_; |
710 PlatformThreadHandle sampling_thread_handle_; | 663 PlatformThreadHandle sampling_thread_handle_; |
711 | 664 |
712 CategoryFilter category_filter_; | 665 CategoryFilter category_filter_; |
(...skipping 16 matching lines...) Expand all Loading... |
729 scoped_refptr<MessageLoopProxy> flush_message_loop_proxy_; | 682 scoped_refptr<MessageLoopProxy> flush_message_loop_proxy_; |
730 subtle::AtomicWord generation_; | 683 subtle::AtomicWord generation_; |
731 | 684 |
732 DISALLOW_COPY_AND_ASSIGN(TraceLog); | 685 DISALLOW_COPY_AND_ASSIGN(TraceLog); |
733 }; | 686 }; |
734 | 687 |
735 } // namespace debug | 688 } // namespace debug |
736 } // namespace base | 689 } // namespace base |
737 | 690 |
738 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ | 691 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ |
OLD | NEW |