Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(111)

Side by Side Diff: base/debug/trace_event_impl.cc

Issue 11366109: Adding raw tracing to trace framework. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #include "base/debug/trace_event_impl.h" 5 #include "base/debug/trace_event_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/debug/leak_annotations.h" 10 #include "base/debug/leak_annotations.h"
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 scoped_refptr<RefCountedString> json_events_str_ptr = 602 scoped_refptr<RefCountedString> json_events_str_ptr =
603 new RefCountedString(); 603 new RefCountedString();
604 TraceEvent::AppendEventsAsJSON(previous_logged_events, 604 TraceEvent::AppendEventsAsJSON(previous_logged_events,
605 i, 605 i,
606 kTraceEventBatchSize, 606 kTraceEventBatchSize,
607 &(json_events_str_ptr->data())); 607 &(json_events_str_ptr->data()));
608 cb.Run(json_events_str_ptr); 608 cb.Run(json_events_str_ptr);
609 } 609 }
610 } 610 }
611 611
612 int TraceLog::AddTraceEventExplicit(char phase,
613 const unsigned char* category_enabled,
614 const char* name,
615 int64 timestamp,
616 unsigned long long id,
617 int num_args,
618 const char** arg_names,
619 const unsigned char* arg_types,
620 const unsigned long long* arg_values,
621 int threshold_begin_id,
622 long long threshold,
623 unsigned char flags) {
624 DCHECK(name);
625 TimeTicks now = TimeTicks::FromInternalValue(timestamp);
626 NotificationHelper notifier(this);
627
628 int ret_begin_id = AddTraceEventInternal(notifier, now, phase,
629 category_enabled, name,
630 id, num_args, arg_names, arg_types,
631 arg_values, threshold_begin_id,
632 threshold, flags);
633
634 notifier.SendNotificationIfAny();
635
636 return ret_begin_id;
637 }
638
612 int TraceLog::AddTraceEvent(char phase, 639 int TraceLog::AddTraceEvent(char phase,
613 const unsigned char* category_enabled, 640 const unsigned char* category_enabled,
614 const char* name, 641 const char* name,
615 unsigned long long id, 642 unsigned long long id,
616 int num_args, 643 int num_args,
617 const char** arg_names, 644 const char** arg_names,
618 const unsigned char* arg_types, 645 const unsigned char* arg_types,
619 const unsigned long long* arg_values, 646 const unsigned long long* arg_values,
620 int threshold_begin_id, 647 int threshold_begin_id,
621 long long threshold, 648 long long threshold,
622 unsigned char flags) { 649 unsigned char flags) {
623 DCHECK(name); 650 DCHECK(name);
624 651
625 #if defined(OS_ANDROID) 652 #if defined(OS_ANDROID)
626 SendToATrace(phase, GetCategoryName(category_enabled), name, 653 SendToATrace(phase, GetCategoryName(category_enabled), name,
627 num_args, arg_names, arg_types, arg_values); 654 num_args, arg_names, arg_types, arg_values);
628 #endif 655 #endif
629 656
630 TimeTicks now = TimeTicks::NowFromSystemTraceTime(); 657 TimeTicks now = TimeTicks::NowFromSystemTraceTime();
631 NotificationHelper notifier(this); 658 NotificationHelper notifier(this);
632 int ret_begin_id = -1;
633 {
634 AutoLock lock(lock_);
635 if (*category_enabled != CATEGORY_ENABLED)
636 return -1;
637 if (logged_events_.size() >= kTraceEventBufferSize)
638 return -1;
639 659
640 int thread_id = static_cast<int>(PlatformThread::CurrentId()); 660 int ret_begin_id = AddTraceEventInternal(notifier, now, phase,
641 661 category_enabled, name,
642 const char* new_name = PlatformThread::GetName(); 662 id, num_args, arg_names, arg_types,
643 // Check if the thread name has been set or changed since the previous 663 arg_values, threshold_begin_id,
644 // call (if any), but don't bother if the new name is empty. Note this will 664 threshold, flags);
645 // not detect a thread name change within the same char* buffer address: we
646 // favor common case performance over corner case correctness.
647 if (new_name != g_current_thread_name.Get().Get() &&
648 new_name && *new_name) {
649 g_current_thread_name.Get().Set(new_name);
650 base::hash_map<int, std::string>::iterator existing_name =
651 thread_names_.find(thread_id);
652 if (existing_name == thread_names_.end()) {
653 // This is a new thread id, and a new name.
654 thread_names_[thread_id] = new_name;
655 } else {
656 // This is a thread id that we've seen before, but potentially with a
657 // new name.
658 std::vector<base::StringPiece> existing_names;
659 Tokenize(existing_name->second, ",", &existing_names);
660 bool found = std::find(existing_names.begin(),
661 existing_names.end(),
662 new_name) != existing_names.end();
663 if (!found) {
664 existing_name->second.push_back(',');
665 existing_name->second.append(new_name);
666 }
667 }
668 }
669
670 if (threshold_begin_id > -1) {
671 DCHECK(phase == TRACE_EVENT_PHASE_END);
672 size_t begin_i = static_cast<size_t>(threshold_begin_id);
673 // Return now if there has been a flush since the begin event was posted.
674 if (begin_i >= logged_events_.size())
675 return -1;
676 // Determine whether to drop the begin/end pair.
677 TimeDelta elapsed = now - logged_events_[begin_i].timestamp();
678 if (elapsed < TimeDelta::FromMicroseconds(threshold)) {
679 // Remove begin event and do not add end event.
680 // This will be expensive if there have been other events in the
681 // mean time (should be rare).
682 logged_events_.erase(logged_events_.begin() + begin_i);
683 return -1;
684 }
685 }
686
687 if (flags & TRACE_EVENT_FLAG_MANGLE_ID)
688 id ^= process_id_hash_;
689
690 ret_begin_id = static_cast<int>(logged_events_.size());
691 logged_events_.push_back(
692 TraceEvent(thread_id,
693 now, phase, category_enabled, name, id,
694 num_args, arg_names, arg_types, arg_values,
695 flags));
696
697 if (logged_events_.size() == kTraceEventBufferSize)
698 notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL);
699
700 if (watch_category_ == category_enabled && watch_event_name_ == name)
701 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION);
702 } // release lock
703 665
704 notifier.SendNotificationIfAny(); 666 notifier.SendNotificationIfAny();
705 667
706 return ret_begin_id; 668 return ret_begin_id;
707 } 669 }
670
671 int TraceLog::AddTraceEventInternal(NotificationHelper& notifier,
672 TimeTicks timestamp,
673 char phase,
674 const unsigned char* category_enabled,
675 const char* name,
676 unsigned long long id,
677 int num_args,
678 const char** arg_names,
679 const unsigned char* arg_types,
680 const unsigned long long* arg_values,
681 int threshold_begin_id,
682 long long threshold,
683 unsigned char flags) {
684 AutoLock lock(lock_);
685 if (*category_enabled != CATEGORY_ENABLED)
686 return -1;
687 if (logged_events_.size() >= kTraceEventBufferSize)
688 return -1;
689
690 int thread_id = static_cast<int>(PlatformThread::CurrentId());
691 const char* new_name = PlatformThread::GetName();
692 // Check if the thread name has been set or changed since the previous
693 // call (if any), but don't bother if the new name is empty. Note this will
694 // not detect a thread name change within the same char* buffer address: we
695 // favor common case performance over corner case correctness.
696 if (new_name != g_current_thread_name.Get().Get() &&
697 new_name && *new_name) {
698 g_current_thread_name.Get().Set(new_name);
699 base::hash_map<int, std::string>::iterator existing_name =
700 thread_names_.find(thread_id);
701 if (existing_name == thread_names_.end()) {
702 // This is a new thread id, and a new name.
703 thread_names_[thread_id] = new_name;
704 } else {
705 // This is a thread id that we've seen before, but potentially with a
706 // new name.
707 std::vector<base::StringPiece> existing_names;
708 Tokenize(existing_name->second, ",", &existing_names);
709 bool found = std::find(existing_names.begin(),
710 existing_names.end(),
711 new_name) != existing_names.end();
712 if (!found) {
713 existing_name->second.push_back(',');
714 existing_name->second.append(new_name);
715 }
716 }
717 }
718
719 if (threshold_begin_id > -1) {
720 DCHECK(phase == TRACE_EVENT_PHASE_END);
721 size_t begin_i = static_cast<size_t>(threshold_begin_id);
722 // Return now if there has been a flush since the begin event was posted.
723 if (begin_i >= logged_events_.size())
724 return -1;
725 // Determine whether to drop the begin/end pair.
726 TimeDelta elapsed = timestamp - logged_events_[begin_i].timestamp();
727 if (elapsed < TimeDelta::FromMicroseconds(threshold)) {
728 // Remove begin event and do not add end event.
729 // This will be expensive if there have been other events in the
730 // mean time (should be rare).
731 logged_events_.erase(logged_events_.begin() + begin_i);
732 return -1;
733 }
734 }
735
736 if (flags & TRACE_EVENT_FLAG_MANGLE_ID)
737 id ^= process_id_hash_;
738
739 int ret_begin_id = static_cast<int>(logged_events_.size());
740 logged_events_.push_back(
741 TraceEvent(thread_id,
742 timestamp, phase, category_enabled, name, id,
743 num_args, arg_names, arg_types, arg_values,
744 flags));
745
746 if (logged_events_.size() == kTraceEventBufferSize)
747 notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL);
748
749 if (watch_category_ == category_enabled && watch_event_name_ == name)
750 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION);
751
752 return ret_begin_id;
753 }
708 754
709 void TraceLog::AddTraceEventEtw(char phase, 755 void TraceLog::AddTraceEventEtw(char phase,
710 const char* name, 756 const char* name,
711 const void* id, 757 const void* id,
712 const char* extra) { 758 const char* extra) {
713 #if defined(OS_WIN) 759 #if defined(OS_WIN)
714 TraceEventETWProvider::Trace(name, phase, id, extra); 760 TraceEventETWProvider::Trace(name, phase, id, extra);
715 #endif 761 #endif
716 INTERNAL_TRACE_EVENT_ADD(phase, "ETW Trace Event", name, 762 INTERNAL_TRACE_EVENT_ADD(phase, "ETW Trace Event", name,
717 TRACE_EVENT_FLAG_COPY, "id", id, "extra", extra); 763 TRACE_EVENT_FLAG_COPY, "id", id, "extra", extra);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 // Create a FNV hash from the process ID for XORing. 845 // Create a FNV hash from the process ID for XORing.
800 // See http://isthe.com/chongo/tech/comp/fnv/ for algorithm details. 846 // See http://isthe.com/chongo/tech/comp/fnv/ for algorithm details.
801 unsigned long long offset_basis = 14695981039346656037ull; 847 unsigned long long offset_basis = 14695981039346656037ull;
802 unsigned long long fnv_prime = 1099511628211ull; 848 unsigned long long fnv_prime = 1099511628211ull;
803 unsigned long long pid = static_cast<unsigned long long>(process_id_); 849 unsigned long long pid = static_cast<unsigned long long>(process_id_);
804 process_id_hash_ = (offset_basis ^ pid) * fnv_prime; 850 process_id_hash_ = (offset_basis ^ pid) * fnv_prime;
805 } 851 }
806 852
807 } // namespace debug 853 } // namespace debug
808 } // namespace base 854 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698