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

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, 1 month 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
« base/debug/trace_event.h ('K') | « base/debug/trace_event_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 } 341 }
342 342
343 // static 343 // static
344 TraceLog* TraceLog::GetInstance() { 344 TraceLog* TraceLog::GetInstance() {
345 return Singleton<TraceLog, StaticMemorySingletonTraits<TraceLog> >::get(); 345 return Singleton<TraceLog, StaticMemorySingletonTraits<TraceLog> >::get();
346 } 346 }
347 347
348 TraceLog::TraceLog() 348 TraceLog::TraceLog()
349 : enabled_(false), 349 : enabled_(false),
350 dispatching_to_observer_list_(false), 350 dispatching_to_observer_list_(false),
351 next_fake_thread_id_(-1),
351 watch_category_(NULL) { 352 watch_category_(NULL) {
352 // Trace is enabled or disabled on one thread while other threads are 353 // Trace is enabled or disabled on one thread while other threads are
353 // accessing the enabled flag. We don't care whether edge-case events are 354 // accessing the enabled flag. We don't care whether edge-case events are
354 // traced or not, so we allow races on the enabled flag to keep the trace 355 // traced or not, so we allow races on the enabled flag to keep the trace
355 // macros fast. 356 // macros fast.
356 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: 357 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots:
357 // ANNOTATE_BENIGN_RACE_SIZED(g_category_enabled, sizeof(g_category_enabled), 358 // ANNOTATE_BENIGN_RACE_SIZED(g_category_enabled, sizeof(g_category_enabled),
358 // "trace_event category enabled"); 359 // "trace_event category enabled");
359 for (int i = 0; i < TRACE_EVENT_MAX_CATEGORIES; ++i) { 360 for (int i = 0; i < TRACE_EVENT_MAX_CATEGORIES; ++i) {
360 ANNOTATE_BENIGN_RACE(&g_category_enabled[i], 361 ANNOTATE_BENIGN_RACE(&g_category_enabled[i],
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 scoped_refptr<RefCountedString> json_events_str_ptr = 588 scoped_refptr<RefCountedString> json_events_str_ptr =
588 new RefCountedString(); 589 new RefCountedString();
589 TraceEvent::AppendEventsAsJSON(previous_logged_events, 590 TraceEvent::AppendEventsAsJSON(previous_logged_events,
590 i, 591 i,
591 kTraceEventBatchSize, 592 kTraceEventBatchSize,
592 &(json_events_str_ptr->data())); 593 &(json_events_str_ptr->data()));
593 cb.Run(json_events_str_ptr); 594 cb.Run(json_events_str_ptr);
594 } 595 }
595 } 596 }
596 597
598 int TraceLog::AddTraceRawEvent(char phase,
599 const unsigned char* category_enabled,
600 const char* thread_name,
601 const char* name,
602 int64 timestamp,
603 unsigned long long id,
604 int num_args,
605 const char** arg_names,
606 const unsigned char* arg_types,
607 const unsigned long long* arg_values,
608 int threshold_begin_id,
609 long long threshold,
610 unsigned char flags) {
611 DCHECK(thread_name);
612 DCHECK(name);
613 TimeTicks now = TimeTicks::FromInternalValue(timestamp);
614 NotificationHelper notifier(this);
615 int ret_begin_id = -1;
616 {
617 AutoLock lock(lock_);
618 if (!*category_enabled)
619 return -1;
620 if (logged_events_.size() >= kTraceEventBufferSize)
621 return -1;
622
623 int thread_id;
624 base::hash_map<std::string, int>::iterator existing_id =
625 fake_thread_names_.find(thread_name);
626 if (existing_id == fake_thread_names_.end()) {
627 // This is a new thread name, add a new id.
628 thread_id = next_fake_thread_id_;
629 next_fake_thread_id_--;
630
631 fake_thread_names_[thread_name] = thread_id;
632 thread_names_[thread_id] = thread_name;
633 } else {
634 thread_id = existing_id->second;
635 }
636
637 ret_begin_id = AddTraceEventInternal(notifier, now, phase, category_enabled,
638 thread_id, name, id, num_args,
639 arg_names, arg_types, arg_values,
640 threshold_begin_id, threshold, flags);
641 } // release lock
642
643 notifier.SendNotificationIfAny();
644
645 return ret_begin_id;
646 }
647
597 int TraceLog::AddTraceEvent(char phase, 648 int TraceLog::AddTraceEvent(char phase,
598 const unsigned char* category_enabled, 649 const unsigned char* category_enabled,
599 const char* name, 650 const char* name,
600 unsigned long long id, 651 unsigned long long id,
601 int num_args, 652 int num_args,
602 const char** arg_names, 653 const char** arg_names,
603 const unsigned char* arg_types, 654 const unsigned char* arg_types,
604 const unsigned long long* arg_values, 655 const unsigned long long* arg_values,
605 int threshold_begin_id, 656 int threshold_begin_id,
606 long long threshold, 657 long long threshold,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 bool found = std::find(existing_names.begin(), 696 bool found = std::find(existing_names.begin(),
646 existing_names.end(), 697 existing_names.end(),
647 new_name) != existing_names.end(); 698 new_name) != existing_names.end();
648 if (!found) { 699 if (!found) {
649 existing_name->second.push_back(','); 700 existing_name->second.push_back(',');
650 existing_name->second.append(new_name); 701 existing_name->second.append(new_name);
651 } 702 }
652 } 703 }
653 } 704 }
654 705
655 if (threshold_begin_id > -1) { 706 ret_begin_id = AddTraceEventInternal(notifier, now, phase, category_enabled,
656 DCHECK(phase == TRACE_EVENT_PHASE_END); 707 thread_id, name, id, num_args,
657 size_t begin_i = static_cast<size_t>(threshold_begin_id); 708 arg_names, arg_types, arg_values,
658 // Return now if there has been a flush since the begin event was posted. 709 threshold_begin_id, threshold, flags);
659 if (begin_i >= logged_events_.size())
660 return -1;
661 // Determine whether to drop the begin/end pair.
662 TimeDelta elapsed = now - logged_events_[begin_i].timestamp();
663 if (elapsed < TimeDelta::FromMicroseconds(threshold)) {
664 // Remove begin event and do not add end event.
665 // This will be expensive if there have been other events in the
666 // mean time (should be rare).
667 logged_events_.erase(logged_events_.begin() + begin_i);
668 return -1;
669 }
670 }
671
672 if (flags & TRACE_EVENT_FLAG_MANGLE_ID)
673 id ^= process_id_hash_;
674
675 ret_begin_id = static_cast<int>(logged_events_.size());
676 logged_events_.push_back(
677 TraceEvent(thread_id,
678 now, phase, category_enabled, name, id,
679 num_args, arg_names, arg_types, arg_values,
680 flags));
681
682 if (logged_events_.size() == kTraceEventBufferSize)
683 notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL);
684
685 if (watch_category_ == category_enabled && watch_event_name_ == name)
686 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION);
687 } // release lock 710 } // release lock
688 711
689 notifier.SendNotificationIfAny(); 712 notifier.SendNotificationIfAny();
690 713
691 return ret_begin_id; 714 return ret_begin_id;
692 } 715 }
716
717 int TraceLog::AddTraceEventInternal(NotificationHelper& notifier,
718 TimeTicks timestamp,
719 char phase,
720 const unsigned char* category_enabled,
721 int thread_id,
722 const char* name,
723 unsigned long long id,
724 int num_args,
725 const char** arg_names,
726 const unsigned char* arg_types,
727 const unsigned long long* arg_values,
728 int threshold_begin_id,
729 long long threshold,
730 unsigned char flags) {
731 if (threshold_begin_id > -1) {
732 DCHECK(phase == TRACE_EVENT_PHASE_END);
733 size_t begin_i = static_cast<size_t>(threshold_begin_id);
734 // Return now if there has been a flush since the begin event was posted.
735 if (begin_i >= logged_events_.size())
736 return -1;
737 // Determine whether to drop the begin/end pair.
738 TimeDelta elapsed = timestamp - logged_events_[begin_i].timestamp();
739 if (elapsed < TimeDelta::FromMicroseconds(threshold)) {
740 // Remove begin event and do not add end event.
741 // This will be expensive if there have been other events in the
742 // mean time (should be rare).
743 logged_events_.erase(logged_events_.begin() + begin_i);
744 return -1;
745 }
746 }
747
748 if (flags & TRACE_EVENT_FLAG_MANGLE_ID)
749 id ^= process_id_hash_;
750
751 int ret_begin_id = static_cast<int>(logged_events_.size());
752 logged_events_.push_back(
753 TraceEvent(thread_id,
754 timestamp, phase, category_enabled, name, id,
755 num_args, arg_names, arg_types, arg_values,
756 flags));
757
758 if (logged_events_.size() == kTraceEventBufferSize)
759 notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL);
760
761 if (watch_category_ == category_enabled && watch_event_name_ == name)
762 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION);
763
764 return ret_begin_id;
765 }
693 766
694 void TraceLog::AddTraceEventEtw(char phase, 767 void TraceLog::AddTraceEventEtw(char phase,
695 const char* name, 768 const char* name,
696 const void* id, 769 const void* id,
697 const char* extra) { 770 const char* extra) {
698 #if defined(OS_WIN) 771 #if defined(OS_WIN)
699 TraceEventETWProvider::Trace(name, phase, id, extra); 772 TraceEventETWProvider::Trace(name, phase, id, extra);
700 #endif 773 #endif
701 INTERNAL_TRACE_EVENT_ADD(phase, "ETW Trace Event", name, 774 INTERNAL_TRACE_EVENT_ADD(phase, "ETW Trace Event", name,
702 TRACE_EVENT_FLAG_COPY, "id", id, "extra", extra); 775 TRACE_EVENT_FLAG_COPY, "id", id, "extra", extra);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 // Create a FNV hash from the process ID for XORing. 857 // Create a FNV hash from the process ID for XORing.
785 // See http://isthe.com/chongo/tech/comp/fnv/ for algorithm details. 858 // See http://isthe.com/chongo/tech/comp/fnv/ for algorithm details.
786 unsigned long long offset_basis = 14695981039346656037ull; 859 unsigned long long offset_basis = 14695981039346656037ull;
787 unsigned long long fnv_prime = 1099511628211ull; 860 unsigned long long fnv_prime = 1099511628211ull;
788 unsigned long long pid = static_cast<unsigned long long>(process_id_); 861 unsigned long long pid = static_cast<unsigned long long>(process_id_);
789 process_id_hash_ = (offset_basis ^ pid) * fnv_prime; 862 process_id_hash_ = (offset_basis ^ pid) * fnv_prime;
790 } 863 }
791 864
792 } // namespace debug 865 } // namespace debug
793 } // namespace base 866 } // namespace base
OLDNEW
« base/debug/trace_event.h ('K') | « base/debug/trace_event_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698