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

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

Issue 12150004: Category group support/Renamings. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Rebased, fixed last nit. Created 7 years, 9 months 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
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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 47
48 namespace base { 48 namespace base {
49 namespace debug { 49 namespace debug {
50 50
51 // Controls the number of trace events we will buffer in-memory 51 // Controls the number of trace events we will buffer in-memory
52 // before throwing them away. 52 // before throwing them away.
53 const size_t kTraceEventBufferSize = 500000; 53 const size_t kTraceEventBufferSize = 500000;
54 const size_t kTraceEventBatchSize = 1000; 54 const size_t kTraceEventBatchSize = 1000;
55 const size_t kTraceEventInitialBufferSize = 1024; 55 const size_t kTraceEventInitialBufferSize = 1024;
56 56
57 #define TRACE_EVENT_MAX_CATEGORIES 100 57 #define MAX_CATEGORY_GROUPS 100
58 58
59 namespace { 59 namespace {
60 60
61 // Parallel arrays g_categories and g_category_enabled are separate so that 61 // Parallel arrays g_category_groups and g_category_group_enabled are separate
62 // a pointer to a member of g_category_enabled can be easily converted to an 62 // so that a pointer to a member of g_category_group_enabled can be easily
63 // index into g_categories. This allows macros to deal only with char enabled 63 // converted to an index into g_category_groups. This allows macros to deal
64 // pointers from g_category_enabled, and we can convert internally to determine 64 // only with char enabled pointers from g_category_group_enabled, and we can
65 // the category name from the char enabled pointer. 65 // convert internally to determine the category name from the char enabled
66 const char* g_categories[TRACE_EVENT_MAX_CATEGORIES] = { 66 // pointer.
67 const char* g_category_groups[MAX_CATEGORY_GROUPS] = {
67 "tracing already shutdown", 68 "tracing already shutdown",
68 "tracing categories exhausted; must increase TRACE_EVENT_MAX_CATEGORIES", 69 "tracing categories exhausted; must increase MAX_CATEGORY_GROUPS",
69 "__metadata", 70 "__metadata",
70 }; 71 };
71 72
72 // The enabled flag is char instead of bool so that the API can be used from C. 73 // The enabled flag is char instead of bool so that the API can be used from C.
73 unsigned char g_category_enabled[TRACE_EVENT_MAX_CATEGORIES] = { 0 }; 74 unsigned char g_category_group_enabled[MAX_CATEGORY_GROUPS] = { 0 };
74 const int g_category_already_shutdown = 0; 75 const int g_category_already_shutdown = 0;
75 const int g_category_categories_exhausted = 1; 76 const int g_category_categories_exhausted = 1;
76 const int g_category_metadata = 2; 77 const int g_category_metadata = 2;
77 int g_category_index = 3; // skip initial 3 categories 78 int g_category_index = 3; // skip initial 3 categories
78 79
79 // The name of the current thread. This is used to decide if the current 80 // The name of the current thread. This is used to decide if the current
80 // thread name has changed. We combine all the seen thread names into the 81 // thread name has changed. We combine all the seen thread names into the
81 // output name for the thread. 82 // output name for the thread.
82 LazyInstance<ThreadLocalPointer<const char> >::Leaky 83 LazyInstance<ThreadLocalPointer<const char> >::Leaky
83 g_current_thread_name = LAZY_INSTANCE_INITIALIZER; 84 g_current_thread_name = LAZY_INSTANCE_INITIALIZER;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 bool IsFull() const OVERRIDE { 132 bool IsFull() const OVERRIDE {
132 return false; 133 return false;
133 } 134 }
134 135
135 size_t CountEnabledByName(const unsigned char* category, 136 size_t CountEnabledByName(const unsigned char* category,
136 const std::string& event_name) const OVERRIDE { 137 const std::string& event_name) const OVERRIDE {
137 size_t notify_count = 0; 138 size_t notify_count = 0;
138 size_t index = oldest_event_index_; 139 size_t index = oldest_event_index_;
139 while (index != unused_event_index_) { 140 while (index != unused_event_index_) {
140 const TraceEvent& event = GetEventAt(index); 141 const TraceEvent& event = GetEventAt(index);
141 if (category == event.category_enabled() && 142 if (category == event.category_group_enabled() &&
142 strcmp(event_name.c_str(), event.name()) == 0) { 143 strcmp(event_name.c_str(), event.name()) == 0) {
143 ++notify_count; 144 ++notify_count;
144 } 145 }
145 index = NextIndex(index); 146 index = NextIndex(index);
146 } 147 }
147 return notify_count; 148 return notify_count;
148 } 149 }
149 150
150 const TraceEvent& GetEventAt(size_t index) const OVERRIDE { 151 const TraceEvent& GetEventAt(size_t index) const OVERRIDE {
151 DCHECK(index < logged_events_.size()); 152 DCHECK(index < logged_events_.size());
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 194
194 bool IsFull() const OVERRIDE { 195 bool IsFull() const OVERRIDE {
195 return Size() >= kTraceEventBufferSize; 196 return Size() >= kTraceEventBufferSize;
196 } 197 }
197 198
198 size_t CountEnabledByName(const unsigned char* category, 199 size_t CountEnabledByName(const unsigned char* category,
199 const std::string& event_name) const OVERRIDE { 200 const std::string& event_name) const OVERRIDE {
200 size_t notify_count = 0; 201 size_t notify_count = 0;
201 for (size_t i = 0; i < Size(); i++) { 202 for (size_t i = 0; i < Size(); i++) {
202 const TraceEvent& event = GetEventAt(i); 203 const TraceEvent& event = GetEventAt(i);
203 if (category == event.category_enabled() && 204 if (category == event.category_group_enabled() &&
204 strcmp(event_name.c_str(), event.name()) == 0) { 205 strcmp(event_name.c_str(), event.name()) == 0) {
205 ++notify_count; 206 ++notify_count;
206 } 207 }
207 } 208 }
208 return notify_count; 209 return notify_count;
209 } 210 }
210 211
211 const TraceEvent& GetEventAt(size_t index) const OVERRIDE { 212 const TraceEvent& GetEventAt(size_t index) const OVERRIDE {
212 DCHECK(index < logged_events_.size()); 213 DCHECK(index < logged_events_.size());
213 return logged_events_[index]; 214 return logged_events_[index];
(...skipping 30 matching lines...) Expand all
244 DCHECK_LE(static_cast<int>(written), end - *buffer); 245 DCHECK_LE(static_cast<int>(written), end - *buffer);
245 *member = *buffer; 246 *member = *buffer;
246 *buffer += written; 247 *buffer += written;
247 } 248 }
248 } 249 }
249 250
250 } // namespace 251 } // namespace
251 252
252 TraceEvent::TraceEvent() 253 TraceEvent::TraceEvent()
253 : id_(0u), 254 : id_(0u),
254 category_enabled_(NULL), 255 category_group_enabled_(NULL),
255 name_(NULL), 256 name_(NULL),
256 thread_id_(0), 257 thread_id_(0),
257 phase_(TRACE_EVENT_PHASE_BEGIN), 258 phase_(TRACE_EVENT_PHASE_BEGIN),
258 flags_(0) { 259 flags_(0) {
259 arg_names_[0] = NULL; 260 arg_names_[0] = NULL;
260 arg_names_[1] = NULL; 261 arg_names_[1] = NULL;
261 memset(arg_values_, 0, sizeof(arg_values_)); 262 memset(arg_values_, 0, sizeof(arg_values_));
262 } 263 }
263 264
264 TraceEvent::TraceEvent(int thread_id, 265 TraceEvent::TraceEvent(int thread_id,
265 TimeTicks timestamp, 266 TimeTicks timestamp,
266 char phase, 267 char phase,
267 const unsigned char* category_enabled, 268 const unsigned char* category_group_enabled,
268 const char* name, 269 const char* name,
269 unsigned long long id, 270 unsigned long long id,
270 int num_args, 271 int num_args,
271 const char** arg_names, 272 const char** arg_names,
272 const unsigned char* arg_types, 273 const unsigned char* arg_types,
273 const unsigned long long* arg_values, 274 const unsigned long long* arg_values,
274 unsigned char flags) 275 unsigned char flags)
275 : timestamp_(timestamp), 276 : timestamp_(timestamp),
276 id_(id), 277 id_(id),
277 category_enabled_(category_enabled), 278 category_group_enabled_(category_group_enabled),
278 name_(name), 279 name_(name),
279 thread_id_(thread_id), 280 thread_id_(thread_id),
280 phase_(phase), 281 phase_(phase),
281 flags_(flags) { 282 flags_(flags) {
282 // Clamp num_args since it may have been set by a third_party library. 283 // Clamp num_args since it may have been set by a third_party library.
283 num_args = (num_args > kTraceMaxNumArgs) ? kTraceMaxNumArgs : num_args; 284 num_args = (num_args > kTraceMaxNumArgs) ? kTraceMaxNumArgs : num_args;
284 int i = 0; 285 int i = 0;
285 for (; i < num_args; ++i) { 286 for (; i < num_args; ++i) {
286 arg_names_[i] = arg_names[i]; 287 arg_names_[i] = arg_names[i];
287 arg_values_[i].as_uint = arg_values[i]; 288 arg_values_[i].as_uint = arg_values[i];
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 break; 375 break;
375 default: 376 default:
376 NOTREACHED() << "Don't know how to print this value"; 377 NOTREACHED() << "Don't know how to print this value";
377 break; 378 break;
378 } 379 }
379 } 380 }
380 381
381 void TraceEvent::AppendAsJSON(std::string* out) const { 382 void TraceEvent::AppendAsJSON(std::string* out) const {
382 int64 time_int64 = timestamp_.ToInternalValue(); 383 int64 time_int64 = timestamp_.ToInternalValue();
383 int process_id = TraceLog::GetInstance()->process_id(); 384 int process_id = TraceLog::GetInstance()->process_id();
384 // Category name checked at category creation time. 385 // Category group checked at category creation time.
385 DCHECK(!strchr(name_, '"')); 386 DCHECK(!strchr(name_, '"'));
386 StringAppendF(out, 387 StringAppendF(out,
387 "{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 "," 388 "{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 ","
388 "\"ph\":\"%c\",\"name\":\"%s\",\"args\":{", 389 "\"ph\":\"%c\",\"name\":\"%s\",\"args\":{",
389 TraceLog::GetCategoryName(category_enabled_), 390 TraceLog::GetCategoryGroupName(category_group_enabled_),
390 process_id, 391 process_id,
391 thread_id_, 392 thread_id_,
392 time_int64, 393 time_int64,
393 phase_, 394 phase_,
394 name_); 395 name_);
395 396
396 // Output argument names and values, stop at first NULL argument name. 397 // Output argument names and values, stop at first NULL argument name.
397 for (int i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) { 398 for (int i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) {
398 if (i > 0) 399 if (i > 0)
399 *out += ","; 400 *out += ",";
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 } 531 }
531 532
532 // static 533 // static
533 void TraceSamplingThread::DefaultSampleCallback(TraceBucketData* bucket_data) { 534 void TraceSamplingThread::DefaultSampleCallback(TraceBucketData* bucket_data) {
534 TRACE_EVENT_API_ATOMIC_WORD category_and_name = 535 TRACE_EVENT_API_ATOMIC_WORD category_and_name =
535 TRACE_EVENT_API_ATOMIC_LOAD(*bucket_data->bucket); 536 TRACE_EVENT_API_ATOMIC_LOAD(*bucket_data->bucket);
536 if (!category_and_name) 537 if (!category_and_name)
537 return; 538 return;
538 const char* const combined = 539 const char* const combined =
539 reinterpret_cast<const char* const>(category_and_name); 540 reinterpret_cast<const char* const>(category_and_name);
540 const char* category; 541 const char* category_group;
541 const char* name; 542 const char* name;
542 ExtractCategoryAndName(combined, &category, &name); 543 ExtractCategoryAndName(combined, &category_group, &name);
543 TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_SAMPLE, 544 TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_SAMPLE,
544 TraceLog::GetCategoryEnabled(category), 545 TraceLog::GetCategoryGroupEnabled(
546 category_group),
545 name, 547 name,
546 0, 548 0,
547 0, 549 0,
548 NULL, 550 NULL,
549 NULL, 551 NULL,
550 NULL, 552 NULL,
551 0); 553 0);
552 } 554 }
553 555
554 void TraceSamplingThread::GetSamples() { 556 void TraceSamplingThread::GetSamples() {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 653
652 return static_cast<Options>(ret); 654 return static_cast<Options>(ret);
653 } 655 }
654 656
655 TraceLog::TraceLog() 657 TraceLog::TraceLog()
656 : enable_count_(0), 658 : enable_count_(0),
657 logged_events_(NULL), 659 logged_events_(NULL),
658 dispatching_to_observer_list_(false), 660 dispatching_to_observer_list_(false),
659 watch_category_(NULL), 661 watch_category_(NULL),
660 trace_options_(RECORD_UNTIL_FULL), 662 trace_options_(RECORD_UNTIL_FULL),
661 sampling_thread_handle_(0) { 663 sampling_thread_handle_(0),
664 category_filter_(CategoryFilter::kDefaultCategoryFilterString) {
662 // Trace is enabled or disabled on one thread while other threads are 665 // Trace is enabled or disabled on one thread while other threads are
663 // accessing the enabled flag. We don't care whether edge-case events are 666 // accessing the enabled flag. We don't care whether edge-case events are
664 // traced or not, so we allow races on the enabled flag to keep the trace 667 // traced or not, so we allow races on the enabled flag to keep the trace
665 // macros fast. 668 // macros fast.
666 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: 669 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots:
667 // ANNOTATE_BENIGN_RACE_SIZED(g_category_enabled, sizeof(g_category_enabled), 670 // ANNOTATE_BENIGN_RACE_SIZED(g_category_group_enabled,
668 // "trace_event category enabled"); 671 // sizeof(g_category_group_enabled),
669 for (int i = 0; i < TRACE_EVENT_MAX_CATEGORIES; ++i) { 672 // "trace_event category enabled");
670 ANNOTATE_BENIGN_RACE(&g_category_enabled[i], 673 for (int i = 0; i < MAX_CATEGORY_GROUPS; ++i) {
674 ANNOTATE_BENIGN_RACE(&g_category_group_enabled[i],
671 "trace_event category enabled"); 675 "trace_event category enabled");
672 } 676 }
673 #if defined(OS_NACL) // NaCl shouldn't expose the process id. 677 #if defined(OS_NACL) // NaCl shouldn't expose the process id.
674 SetProcessID(0); 678 SetProcessID(0);
675 #else 679 #else
676 SetProcessID(static_cast<int>(GetCurrentProcId())); 680 SetProcessID(static_cast<int>(GetCurrentProcId()));
677 #endif 681 #endif
678 682
679 logged_events_.reset(GetTraceBuffer()); 683 logged_events_.reset(GetTraceBuffer());
680 } 684 }
681 685
682 TraceLog::~TraceLog() { 686 TraceLog::~TraceLog() {
683 } 687 }
684 688
685 const unsigned char* TraceLog::GetCategoryEnabled(const char* name) { 689 const unsigned char* TraceLog::GetCategoryGroupEnabled(
690 const char* category_group) {
686 TraceLog* tracelog = GetInstance(); 691 TraceLog* tracelog = GetInstance();
687 if (!tracelog) { 692 if (!tracelog) {
688 DCHECK(!g_category_enabled[g_category_already_shutdown]); 693 DCHECK(!g_category_group_enabled[g_category_already_shutdown]);
689 return &g_category_enabled[g_category_already_shutdown]; 694 return &g_category_group_enabled[g_category_already_shutdown];
690 } 695 }
691 return tracelog->GetCategoryEnabledInternal(name); 696 return tracelog->GetCategoryGroupEnabledInternal(category_group);
692 } 697 }
693 698
694 const char* TraceLog::GetCategoryName(const unsigned char* category_enabled) { 699 const char* TraceLog::GetCategoryGroupName(
695 // Calculate the index of the category by finding category_enabled in 700 const unsigned char* category_group_enabled) {
696 // g_category_enabled array. 701 // Calculate the index of the category group by finding
697 uintptr_t category_begin = reinterpret_cast<uintptr_t>(g_category_enabled); 702 // category_group_enabled in g_category_group_enabled array.
698 uintptr_t category_ptr = reinterpret_cast<uintptr_t>(category_enabled); 703 uintptr_t category_begin =
704 reinterpret_cast<uintptr_t>(g_category_group_enabled);
705 uintptr_t category_ptr = reinterpret_cast<uintptr_t>(category_group_enabled);
699 DCHECK(category_ptr >= category_begin && 706 DCHECK(category_ptr >= category_begin &&
700 category_ptr < reinterpret_cast<uintptr_t>(g_category_enabled + 707 category_ptr < reinterpret_cast<uintptr_t>(
701 TRACE_EVENT_MAX_CATEGORIES)) << 708 g_category_group_enabled + MAX_CATEGORY_GROUPS)) <<
702 "out of bounds category pointer"; 709 "out of bounds category pointer";
703 uintptr_t category_index = 710 uintptr_t category_index =
704 (category_ptr - category_begin) / sizeof(g_category_enabled[0]); 711 (category_ptr - category_begin) / sizeof(g_category_group_enabled[0]);
705 return g_categories[category_index]; 712 return g_category_groups[category_index];
706 } 713 }
707 714
708 static void EnableMatchingCategory(int category_index, 715 void TraceLog::EnableIncludedCategoryGroup(int category_index) {
709 const std::vector<std::string>& patterns, 716 bool is_enabled = category_filter_.IsCategoryGroupEnabled(
710 unsigned char matched_value, 717 g_category_groups[category_index]);
711 unsigned char unmatched_value) { 718 g_category_group_enabled[category_index] =
712 std::vector<std::string>::const_iterator ci = patterns.begin(); 719 is_enabled ? TraceLog::CATEGORY_ENABLED : 0;
713 bool is_match = false;
714 for (; ci != patterns.end(); ++ci) {
715 is_match = MatchPattern(g_categories[category_index], ci->c_str());
716 if (is_match)
717 break;
718 }
719 g_category_enabled[category_index] = is_match ?
720 matched_value : unmatched_value;
721 } 720 }
722 721
723 // Enable/disable each category based on the category filters in |patterns|. 722 void TraceLog::EnableIncludedCategoryGroups() {
724 // If the category name matches one of the patterns, its enabled status is set
725 // to |matched_value|. Otherwise its enabled status is set to |unmatched_value|.
726 static void EnableMatchingCategories(const std::vector<std::string>& patterns,
727 unsigned char matched_value,
728 unsigned char unmatched_value) {
729 for (int i = 0; i < g_category_index; i++) 723 for (int i = 0; i < g_category_index; i++)
730 EnableMatchingCategory(i, patterns, matched_value, unmatched_value); 724 EnableIncludedCategoryGroup(i);
731 } 725 }
732 726
733 const unsigned char* TraceLog::GetCategoryEnabledInternal(const char* name) { 727 const unsigned char* TraceLog::GetCategoryGroupEnabledInternal(
728 const char* category_group) {
729 DCHECK(!strchr(category_group, '"')) <<
730 "Category groups may not contain double quote";
734 AutoLock lock(lock_); 731 AutoLock lock(lock_);
735 DCHECK(!strchr(name, '"')) << "Category names may not contain double quote";
736 732
737 unsigned char* category_enabled = NULL; 733 unsigned char* category_group_enabled = NULL;
738 // Search for pre-existing category matching this name 734 // Search for pre-existing category group.
739 for (int i = 0; i < g_category_index; i++) { 735 for (int i = 0; i < g_category_index; i++) {
740 if (strcmp(g_categories[i], name) == 0) { 736 if (strcmp(g_category_groups[i], category_group) == 0) {
741 category_enabled = &g_category_enabled[i]; 737 category_group_enabled = &g_category_group_enabled[i];
742 break; 738 break;
743 } 739 }
744 } 740 }
745 741
746 if (!category_enabled) { 742 if (!category_group_enabled) {
747 // Create a new category 743 // Create a new category group
748 DCHECK(g_category_index < TRACE_EVENT_MAX_CATEGORIES) << 744 DCHECK(g_category_index < MAX_CATEGORY_GROUPS) <<
749 "must increase TRACE_EVENT_MAX_CATEGORIES"; 745 "must increase MAX_CATEGORY_GROUPS";
750 if (g_category_index < TRACE_EVENT_MAX_CATEGORIES) { 746 if (g_category_index < MAX_CATEGORY_GROUPS) {
751 int new_index = g_category_index++; 747 int new_index = g_category_index++;
752 // Don't hold on to the name pointer, so that we can create categories 748 // Don't hold on to the category_group pointer, so that we can create
753 // with strings not known at compile time (this is required by 749 // category groups with strings not known at compile time (this is
754 // SetWatchEvent). 750 // required by SetWatchEvent).
755 const char* new_name = strdup(name); 751 const char* new_group = strdup(category_group);
756 ANNOTATE_LEAKING_OBJECT_PTR(new_name); 752 ANNOTATE_LEAKING_OBJECT_PTR(new_group);
757 g_categories[new_index] = new_name; 753 g_category_groups[new_index] = new_group;
758 DCHECK(!g_category_enabled[new_index]); 754 DCHECK(!g_category_group_enabled[new_index]);
759 if (enable_count_) { 755 if (enable_count_) {
760 // Note that if both included and excluded_categories are empty, the 756 // Note that if both included and excluded patterns in the
761 // else clause below excludes nothing, thereby enabling this category. 757 // CategoryFilter are empty, we exclude nothing,
762 if (!included_categories_.empty()) { 758 // thereby enabling this category group.
763 EnableMatchingCategory(new_index, included_categories_, 759 EnableIncludedCategoryGroup(new_index);
764 CATEGORY_ENABLED, 0);
765 } else {
766 EnableMatchingCategory(new_index, excluded_categories_,
767 0, CATEGORY_ENABLED);
768 }
769 } else { 760 } else {
770 g_category_enabled[new_index] = 0; 761 g_category_group_enabled[new_index] = 0;
771 } 762 }
772 category_enabled = &g_category_enabled[new_index]; 763 category_group_enabled = &g_category_group_enabled[new_index];
773 } else { 764 } else {
774 category_enabled = &g_category_enabled[g_category_categories_exhausted]; 765 category_group_enabled =
766 &g_category_group_enabled[g_category_categories_exhausted];
775 } 767 }
776 } 768 }
777 #if defined(OS_ANDROID) 769 #if defined(OS_ANDROID)
778 ApplyATraceEnabledFlag(category_enabled); 770 ApplyATraceEnabledFlag(category_group_enabled);
779 #endif 771 #endif
780 return category_enabled; 772 return category_group_enabled;
781 } 773 }
782 774
783 void TraceLog::GetKnownCategories(std::vector<std::string>* categories) { 775 void TraceLog::GetKnownCategoryGroups(
776 std::vector<std::string>* category_groups) {
784 AutoLock lock(lock_); 777 AutoLock lock(lock_);
785 for (int i = 0; i < g_category_index; i++) 778 for (int i = 0; i < g_category_index; i++)
786 categories->push_back(g_categories[i]); 779 category_groups->push_back(g_category_groups[i]);
787 } 780 }
788 781
789 void TraceLog::SetEnabled(const std::vector<std::string>& included_categories, 782 void TraceLog::SetEnabled(const CategoryFilter& category_filter,
790 const std::vector<std::string>& excluded_categories,
791 Options options) { 783 Options options) {
792 AutoLock lock(lock_); 784 AutoLock lock(lock_);
793 785
794 if (enable_count_++ > 0) { 786 if (enable_count_++ > 0) {
795 if (options != trace_options_) { 787 if (options != trace_options_) {
796 DLOG(ERROR) << "Attemting to re-enable tracing with a different " 788 DLOG(ERROR) << "Attemting to re-enable tracing with a different "
797 << "set of options."; 789 << "set of options.";
798 } 790 }
799 791
800 // Tracing is already enabled, so just merge in enabled categories. 792 // Tracing is already enabled, so just merge in enabled categories.
801 // We only expand the set of enabled categories upon nested SetEnable(). 793 // We only expand the set of enabled categories upon nested SetEnable().
802 if (!included_categories_.empty() && !included_categories.empty()) { 794 if (category_filter_.HasIncludedPatterns() &&
803 included_categories_.insert(included_categories_.end(), 795 category_filter.HasIncludedPatterns()) {
804 included_categories.begin(), 796 category_filter_.Merge(category_filter);
805 included_categories.end());
806 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0);
807 } else { 797 } else {
808 // If either old or new included categories are empty, allow all events. 798 // If either old or new included categories are empty, allow all events.
809 included_categories_.clear(); 799 category_filter_.Clear();
810 excluded_categories_.clear();
811 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED);
812 } 800 }
801 EnableIncludedCategoryGroups();
813 return; 802 return;
814 } 803 }
815 804
816 if (options != trace_options_) { 805 if (options != trace_options_) {
817 trace_options_ = options; 806 trace_options_ = options;
818 logged_events_.reset(GetTraceBuffer()); 807 logged_events_.reset(GetTraceBuffer());
819 } 808 }
820 809
821 if (dispatching_to_observer_list_) { 810 if (dispatching_to_observer_list_) {
822 DLOG(ERROR) << 811 DLOG(ERROR) <<
823 "Cannot manipulate TraceLog::Enabled state from an observer."; 812 "Cannot manipulate TraceLog::Enabled state from an observer.";
824 return; 813 return;
825 } 814 }
826 815
827 dispatching_to_observer_list_ = true; 816 dispatching_to_observer_list_ = true;
828 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, 817 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_,
829 OnTraceLogWillEnable()); 818 OnTraceLogWillEnable());
830 dispatching_to_observer_list_ = false; 819 dispatching_to_observer_list_ = false;
831 820
832 included_categories_ = included_categories; 821 category_filter_ = CategoryFilter(category_filter);
833 excluded_categories_ = excluded_categories; 822 EnableIncludedCategoryGroups();
834 // Note that if both included and excluded_categories are empty, the else
835 // clause below excludes nothing, thereby enabling all categories.
836 if (!included_categories_.empty())
837 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0);
838 else
839 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED);
840 823
841 if (options & ENABLE_SAMPLING) { 824 if (options & ENABLE_SAMPLING) {
842 sampling_thread_.reset(new TraceSamplingThread); 825 sampling_thread_.reset(new TraceSamplingThread);
843 sampling_thread_->RegisterSampleBucket( 826 sampling_thread_->RegisterSampleBucket(
844 &g_trace_state0, 827 &g_trace_state0,
845 "bucket0", 828 "bucket0",
846 Bind(&TraceSamplingThread::DefaultSampleCallback)); 829 Bind(&TraceSamplingThread::DefaultSampleCallback));
847 sampling_thread_->RegisterSampleBucket( 830 sampling_thread_->RegisterSampleBucket(
848 &g_trace_state1, 831 &g_trace_state1,
849 "bucket1", 832 "bucket1",
850 Bind(&TraceSamplingThread::DefaultSampleCallback)); 833 Bind(&TraceSamplingThread::DefaultSampleCallback));
851 sampling_thread_->RegisterSampleBucket( 834 sampling_thread_->RegisterSampleBucket(
852 &g_trace_state2, 835 &g_trace_state2,
853 "bucket2", 836 "bucket2",
854 Bind(&TraceSamplingThread::DefaultSampleCallback)); 837 Bind(&TraceSamplingThread::DefaultSampleCallback));
855 if (!PlatformThread::Create( 838 if (!PlatformThread::Create(
856 0, sampling_thread_.get(), &sampling_thread_handle_)) { 839 0, sampling_thread_.get(), &sampling_thread_handle_)) {
857 DCHECK(false) << "failed to create thread"; 840 DCHECK(false) << "failed to create thread";
858 } 841 }
859 } 842 }
860 } 843 }
861 844
862 void TraceLog::SetEnabled(const std::string& categories, Options options) { 845 const CategoryFilter& TraceLog::GetCurrentCategoryFilter() {
863 std::vector<std::string> included, excluded;
864 // Tokenize list of categories, delimited by ','.
865 StringTokenizer tokens(categories, ",");
866 while (tokens.GetNext()) {
867 bool is_included = true;
868 std::string category = tokens.token();
869 // Excluded categories start with '-'.
870 if (category.at(0) == '-') {
871 // Remove '-' from category string.
872 category = category.substr(1);
873 is_included = false;
874 }
875 if (is_included)
876 included.push_back(category);
877 else
878 excluded.push_back(category);
879 }
880 SetEnabled(included, excluded, options);
881 }
882
883 void TraceLog::GetEnabledTraceCategories(
884 std::vector<std::string>* included_out,
885 std::vector<std::string>* excluded_out) {
886 AutoLock lock(lock_); 846 AutoLock lock(lock_);
887 if (enable_count_) { 847 DCHECK(enable_count_ > 0);
888 *included_out = included_categories_; 848 return category_filter_;
889 *excluded_out = excluded_categories_;
890 }
891 } 849 }
892 850
893 void TraceLog::SetDisabled() { 851 void TraceLog::SetDisabled() {
894 AutoLock lock(lock_); 852 AutoLock lock(lock_);
895 DCHECK(enable_count_ > 0); 853 DCHECK(enable_count_ > 0);
896 if (--enable_count_ != 0) 854 if (--enable_count_ != 0)
897 return; 855 return;
898 856
899 if (dispatching_to_observer_list_) { 857 if (dispatching_to_observer_list_) {
900 DLOG(ERROR) 858 DLOG(ERROR)
(...skipping 10 matching lines...) Expand all
911 sampling_thread_handle_ = 0; 869 sampling_thread_handle_ = 0;
912 sampling_thread_.reset(); 870 sampling_thread_.reset();
913 } 871 }
914 872
915 dispatching_to_observer_list_ = true; 873 dispatching_to_observer_list_ = true;
916 FOR_EACH_OBSERVER(EnabledStateChangedObserver, 874 FOR_EACH_OBSERVER(EnabledStateChangedObserver,
917 enabled_state_observer_list_, 875 enabled_state_observer_list_,
918 OnTraceLogWillDisable()); 876 OnTraceLogWillDisable());
919 dispatching_to_observer_list_ = false; 877 dispatching_to_observer_list_ = false;
920 878
921 included_categories_.clear(); 879 category_filter_.Clear();
922 excluded_categories_.clear();
923 watch_category_ = NULL; 880 watch_category_ = NULL;
924 watch_event_name_ = ""; 881 watch_event_name_ = "";
925 for (int i = 0; i < g_category_index; i++) 882 for (int i = 0; i < g_category_index; i++)
926 g_category_enabled[i] = 0; 883 g_category_group_enabled[i] = 0;
927 AddThreadNameMetadataEvents(); 884 AddThreadNameMetadataEvents();
928 } 885 }
929 886
930 void TraceLog::SetEnabled(bool enabled, Options options) {
931 if (enabled)
932 SetEnabled(std::vector<std::string>(), std::vector<std::string>(), options);
933 else
934 SetDisabled();
935 }
936
937 void TraceLog::AddEnabledStateObserver(EnabledStateChangedObserver* listener) { 887 void TraceLog::AddEnabledStateObserver(EnabledStateChangedObserver* listener) {
938 enabled_state_observer_list_.AddObserver(listener); 888 enabled_state_observer_list_.AddObserver(listener);
939 } 889 }
940 890
941 void TraceLog::RemoveEnabledStateObserver( 891 void TraceLog::RemoveEnabledStateObserver(
942 EnabledStateChangedObserver* listener) { 892 EnabledStateChangedObserver* listener) {
943 enabled_state_observer_list_.RemoveObserver(listener); 893 enabled_state_observer_list_.RemoveObserver(listener);
944 } 894 }
945 895
946 float TraceLog::GetBufferPercentFull() const { 896 float TraceLog::GetBufferPercentFull() const {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 935
986 if (!previous_logged_events->HasMoreEvents()) 936 if (!previous_logged_events->HasMoreEvents())
987 break; 937 break;
988 } 938 }
989 939
990 cb.Run(json_events_str_ptr); 940 cb.Run(json_events_str_ptr);
991 } 941 }
992 } 942 }
993 943
994 void TraceLog::AddTraceEvent(char phase, 944 void TraceLog::AddTraceEvent(char phase,
995 const unsigned char* category_enabled, 945 const unsigned char* category_group_enabled,
996 const char* name, 946 const char* name,
997 unsigned long long id, 947 unsigned long long id,
998 int num_args, 948 int num_args,
999 const char** arg_names, 949 const char** arg_names,
1000 const unsigned char* arg_types, 950 const unsigned char* arg_types,
1001 const unsigned long long* arg_values, 951 const unsigned long long* arg_values,
1002 unsigned char flags) { 952 unsigned char flags) {
1003 int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); 953 int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
1004 base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime(); 954 base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime();
1005 AddTraceEventWithThreadIdAndTimestamp(phase, category_enabled, name, id, 955 AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled, name, id,
1006 thread_id, now, num_args, arg_names, 956 thread_id, now, num_args, arg_names,
1007 arg_types, arg_values, flags); 957 arg_types, arg_values, flags);
1008 } 958 }
1009 959
1010 void TraceLog::AddTraceEventWithThreadIdAndTimestamp( 960 void TraceLog::AddTraceEventWithThreadIdAndTimestamp(
1011 char phase, 961 char phase,
1012 const unsigned char* category_enabled, 962 const unsigned char* category_group_enabled,
1013 const char* name, 963 const char* name,
1014 unsigned long long id, 964 unsigned long long id,
1015 int thread_id, 965 int thread_id,
1016 const TimeTicks& timestamp, 966 const TimeTicks& timestamp,
1017 int num_args, 967 int num_args,
1018 const char** arg_names, 968 const char** arg_names,
1019 const unsigned char* arg_types, 969 const unsigned char* arg_types,
1020 const unsigned long long* arg_values, 970 const unsigned long long* arg_values,
1021 unsigned char flags) { 971 unsigned char flags) {
1022 DCHECK(name); 972 DCHECK(name);
1023 973
1024 if (flags & TRACE_EVENT_FLAG_MANGLE_ID) 974 if (flags & TRACE_EVENT_FLAG_MANGLE_ID)
1025 id ^= process_id_hash_; 975 id ^= process_id_hash_;
1026 976
1027 #if defined(OS_ANDROID) 977 #if defined(OS_ANDROID)
1028 SendToATrace(phase, GetCategoryName(category_enabled), name, id, 978 SendToATrace(phase, GetCategoryGroupName(category__group_enabled), name, id,
1029 num_args, arg_names, arg_types, arg_values, flags); 979 num_args, arg_names, arg_types, arg_values, flags);
1030 #endif 980 #endif
1031 981
1032 TimeTicks now = timestamp - time_offset_; 982 TimeTicks now = timestamp - time_offset_;
1033 EventCallback event_callback_copy; 983 EventCallback event_callback_copy;
1034 984
1035 NotificationHelper notifier(this); 985 NotificationHelper notifier(this);
1036 986
1037 { 987 {
1038 AutoLock lock(lock_); 988 AutoLock lock(lock_);
1039 if (*category_enabled != CATEGORY_ENABLED) 989 if (*category_group_enabled != CATEGORY_ENABLED)
1040 return; 990 return;
1041 if (logged_events_->IsFull()) 991 if (logged_events_->IsFull())
1042 return; 992 return;
1043 993
1044 const char* new_name = ThreadIdNameManager::GetInstance()-> 994 const char* new_name = ThreadIdNameManager::GetInstance()->
1045 GetName(thread_id); 995 GetName(thread_id);
1046 // Check if the thread name has been set or changed since the previous 996 // Check if the thread name has been set or changed since the previous
1047 // call (if any), but don't bother if the new name is empty. Note this will 997 // call (if any), but don't bother if the new name is empty. Note this will
1048 // not detect a thread name change within the same char* buffer address: we 998 // not detect a thread name change within the same char* buffer address: we
1049 // favor common case performance over corner case correctness. 999 // favor common case performance over corner case correctness.
(...skipping 15 matching lines...) Expand all
1065 existing_names.end(), 1015 existing_names.end(),
1066 new_name) != existing_names.end(); 1016 new_name) != existing_names.end();
1067 if (!found) { 1017 if (!found) {
1068 existing_name->second.push_back(','); 1018 existing_name->second.push_back(',');
1069 existing_name->second.append(new_name); 1019 existing_name->second.append(new_name);
1070 } 1020 }
1071 } 1021 }
1072 } 1022 }
1073 1023
1074 logged_events_->AddEvent(TraceEvent(thread_id, 1024 logged_events_->AddEvent(TraceEvent(thread_id,
1075 now, phase, category_enabled, name, id, 1025 now, phase, category_group_enabled, name, id,
1076 num_args, arg_names, arg_types, arg_values, 1026 num_args, arg_names, arg_types, arg_values,
1077 flags)); 1027 flags));
1078 1028
1079 if (logged_events_->IsFull()) 1029 if (logged_events_->IsFull())
1080 notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL); 1030 notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL);
1081 1031
1082 if (watch_category_ == category_enabled && watch_event_name_ == name) 1032 if (watch_category_ == category_group_enabled && watch_event_name_ == name)
1083 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION); 1033 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION);
1084 1034
1085 event_callback_copy = event_callback_; 1035 event_callback_copy = event_callback_;
1086 } // release lock 1036 } // release lock
1087 1037
1088 notifier.SendNotificationIfAny(); 1038 notifier.SendNotificationIfAny();
1089 if (event_callback_copy != NULL) { 1039 if (event_callback_copy != NULL) {
1090 event_callback_copy(phase, category_enabled, name, id, 1040 event_callback_copy(phase, category_group_enabled, name, id,
1091 num_args, arg_names, arg_types, arg_values, 1041 num_args, arg_names, arg_types, arg_values,
1092 flags); 1042 flags);
1093 } 1043 }
1094 } 1044 }
1095 1045
1096 void TraceLog::AddTraceEventEtw(char phase, 1046 void TraceLog::AddTraceEventEtw(char phase,
1097 const char* name, 1047 const char* name,
1098 const void* id, 1048 const void* id,
1099 const char* extra) { 1049 const char* extra) {
1100 #if defined(OS_WIN) 1050 #if defined(OS_WIN)
(...skipping 10 matching lines...) Expand all
1111 { 1061 {
1112 #if defined(OS_WIN) 1062 #if defined(OS_WIN)
1113 TraceEventETWProvider::Trace(name, phase, id, extra); 1063 TraceEventETWProvider::Trace(name, phase, id, extra);
1114 #endif 1064 #endif
1115 INTERNAL_TRACE_EVENT_ADD(phase, "ETW Trace Event", name, 1065 INTERNAL_TRACE_EVENT_ADD(phase, "ETW Trace Event", name,
1116 TRACE_EVENT_FLAG_COPY, "id", id, "extra", extra); 1066 TRACE_EVENT_FLAG_COPY, "id", id, "extra", extra);
1117 } 1067 }
1118 1068
1119 void TraceLog::SetWatchEvent(const std::string& category_name, 1069 void TraceLog::SetWatchEvent(const std::string& category_name,
1120 const std::string& event_name) { 1070 const std::string& event_name) {
1121 const unsigned char* category = GetCategoryEnabled(category_name.c_str()); 1071 const unsigned char* category = GetCategoryGroupEnabled(
1072 category_name.c_str());
1122 size_t notify_count = 0; 1073 size_t notify_count = 0;
1123 { 1074 {
1124 AutoLock lock(lock_); 1075 AutoLock lock(lock_);
1125 watch_category_ = category; 1076 watch_category_ = category;
1126 watch_event_name_ = event_name; 1077 watch_event_name_ = event_name;
1127 1078
1128 // First, search existing events for watch event because we want to catch 1079 // First, search existing events for watch event because we want to catch
1129 // it even if it has already occurred. 1080 // it even if it has already occurred.
1130 notify_count = logged_events_->CountEnabledByName(category, event_name); 1081 notify_count = logged_events_->CountEnabledByName(category, event_name);
1131 } // release lock 1082 } // release lock
(...skipping 20 matching lines...) Expand all
1152 it != thread_names_.end(); 1103 it != thread_names_.end();
1153 it++) { 1104 it++) {
1154 if (!it->second.empty()) { 1105 if (!it->second.empty()) {
1155 int num_args = 1; 1106 int num_args = 1;
1156 const char* arg_name = "name"; 1107 const char* arg_name = "name";
1157 unsigned char arg_type; 1108 unsigned char arg_type;
1158 unsigned long long arg_value; 1109 unsigned long long arg_value;
1159 trace_event_internal::SetTraceValue(it->second, &arg_type, &arg_value); 1110 trace_event_internal::SetTraceValue(it->second, &arg_type, &arg_value);
1160 logged_events_->AddEvent(TraceEvent(it->first, 1111 logged_events_->AddEvent(TraceEvent(it->first,
1161 TimeTicks(), TRACE_EVENT_PHASE_METADATA, 1112 TimeTicks(), TRACE_EVENT_PHASE_METADATA,
1162 &g_category_enabled[g_category_metadata], 1113 &g_category_group_enabled[g_category_metadata],
1163 "thread_name", trace_event_internal::kNoEventId, 1114 "thread_name", trace_event_internal::kNoEventId,
1164 num_args, &arg_name, &arg_type, &arg_value, 1115 num_args, &arg_name, &arg_type, &arg_value,
1165 TRACE_EVENT_FLAG_NONE)); 1116 TRACE_EVENT_FLAG_NONE));
1166 } 1117 }
1167 } 1118 }
1168 } 1119 }
1169 1120
1170 void TraceLog::InstallWaitableEventForSamplingTesting( 1121 void TraceLog::InstallWaitableEventForSamplingTesting(
1171 WaitableEvent* waitable_event) { 1122 WaitableEvent* waitable_event) {
1172 sampling_thread_->InstallWaitableEventForSamplingTesting(waitable_event); 1123 sampling_thread_->InstallWaitableEventForSamplingTesting(waitable_event);
(...skipping 14 matching lines...) Expand all
1187 unsigned long long offset_basis = 14695981039346656037ull; 1138 unsigned long long offset_basis = 14695981039346656037ull;
1188 unsigned long long fnv_prime = 1099511628211ull; 1139 unsigned long long fnv_prime = 1099511628211ull;
1189 unsigned long long pid = static_cast<unsigned long long>(process_id_); 1140 unsigned long long pid = static_cast<unsigned long long>(process_id_);
1190 process_id_hash_ = (offset_basis ^ pid) * fnv_prime; 1141 process_id_hash_ = (offset_basis ^ pid) * fnv_prime;
1191 } 1142 }
1192 1143
1193 void TraceLog::SetTimeOffset(TimeDelta offset) { 1144 void TraceLog::SetTimeOffset(TimeDelta offset) {
1194 time_offset_ = offset; 1145 time_offset_ = offset;
1195 } 1146 }
1196 1147
1148 bool CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
1149 const std::string str) {
1150 return str.empty() ||
1151 str.at(0) == ' ' ||
1152 str.at(str.length() - 1) == ' ';
1153 }
1154
1155 static bool DoesCategoryGroupContainCategory(const char* category_group,
1156 const char* category) {
1157 DCHECK(category);
1158 CStringTokenizer category_group_tokens(category_group,
1159 category_group + strlen(category_group), ",");
1160 while (category_group_tokens.GetNext()) {
1161 std::string category_group_token = category_group_tokens.token();
1162 // Don't allow empty tokens, nor tokens with leading or trailing space.
1163 DCHECK(!CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
1164 category_group_token))
1165 << "Disallowed category string";
1166 if (MatchPattern(category_group_token.c_str(), category))
1167 return true;
1168 }
1169 return false;
1170 }
1171
1172 // Enable everything but debug and test categories by default.
1173 const char* CategoryFilter::kDefaultCategoryFilterString = "-*Debug,-*Test";
1174
1175 CategoryFilter::CategoryFilter(const std::string& filter_string) {
1176 if (!filter_string.empty())
1177 Initialize(filter_string);
1178 else
1179 Initialize(CategoryFilter::kDefaultCategoryFilterString);
1180 }
1181
1182 CategoryFilter::CategoryFilter(const CategoryFilter& cf)
1183 : included_(cf.included_),
1184 excluded_(cf.excluded_) {
1185 }
1186
1187 CategoryFilter& CategoryFilter::operator=(const CategoryFilter& rhs) {
1188 if (this == &rhs)
1189 return *this;
1190
1191 included_ = rhs.included_;
1192 excluded_ = rhs.excluded_;
1193 return *this;
1194 }
1195
1196 void CategoryFilter::Initialize(const std::string& filter_string) {
1197 // Tokenize list of categories, delimited by ','.
1198 StringTokenizer tokens(filter_string, ",");
1199 // Add each token to the appropriate list (included_,excluded_).
1200 while (tokens.GetNext()) {
1201 std::string category = tokens.token();
1202 // Ignore empty categories.
1203 if (category.empty())
1204 continue;
1205 // Excluded categories start with '-'.
1206 if (category.at(0) == '-') {
1207 // Remove '-' from category string.
1208 category = category.substr(1);
1209 excluded_.push_back(category);
1210 } else {
1211 included_.push_back(category);
1212 }
1213 }
1214 }
1215
1216 void CategoryFilter::WriteString(std::string* out,
1217 bool included) const {
1218 std::vector<std::string>::const_iterator ci;
1219 std::vector<std::string>::const_iterator end;
1220 if (included) {
1221 ci = included_.begin();
1222 end = included_.end();
1223 } else {
1224 ci = excluded_.begin();
1225 end = excluded_.end();
1226 }
1227
1228 // Prepend commas for all excluded categories IF we have included categories.
1229 bool prepend_comma_for_first_excluded = !included && !included_.empty();
1230 int token_cnt = 0;
1231 for (; ci != end; ++ci) {
1232 if (token_cnt > 0 || prepend_comma_for_first_excluded)
1233 StringAppendF(out, ",");
1234 StringAppendF(out, "%s%s", (included ? "" : "-"), ci->c_str());
1235 ++token_cnt;
1236 }
1237 }
1238
1239 std::string CategoryFilter::ToString() const {
1240 std::string filter_string;
1241 WriteString(&filter_string, true);
1242 WriteString(&filter_string, false);
1243
1244 return filter_string;
1245 }
1246
1247 bool CategoryFilter::IsCategoryGroupEnabled(
1248 const char* category_group_name) const {
1249 // TraceLog should call this method only as part of enabling/disabling
1250 // categories.
1251 std::vector<std::string>::const_iterator ci = included_.begin();
1252 for (; ci != included_.end(); ++ci) {
1253 if (DoesCategoryGroupContainCategory(category_group_name, ci->c_str()))
1254 return true;
1255 }
1256 ci = excluded_.begin();
1257 for (; ci != excluded_.end(); ++ci) {
1258 if (DoesCategoryGroupContainCategory(category_group_name, ci->c_str()))
1259 return false;
1260 }
1261 // If the category group is not excluded, and there are no included patterns
1262 // we consider this pattern enabled.
1263 return included_.empty();
1264 }
1265
1266 void CategoryFilter::Merge(const CategoryFilter& nested_filter) {
1267 included_.insert(included_.end(),
1268 nested_filter.included_.begin(),
1269 nested_filter.included_.end());
1270 excluded_.insert(excluded_.end(),
1271 nested_filter.excluded_.begin(),
1272 nested_filter.excluded_.end());
1273 }
1274
1275 bool CategoryFilter::HasIncludedPatterns() const {
1276 return !included_.empty();
1277 }
1278
1279 void CategoryFilter::Clear() {
1280 included_.clear();
1281 excluded_.clear();
1282 }
1283
1197 } // namespace debug 1284 } // namespace debug
1198 } // namespace base 1285 } // namespace base
1199 1286
1200 namespace trace_event_internal { 1287 namespace trace_event_internal {
1201 1288
1202 ScopedTrace::ScopedTrace( 1289 ScopedTrace::ScopedTrace(
1203 TRACE_EVENT_API_ATOMIC_WORD* event_uid, const char* name) { 1290 TRACE_EVENT_API_ATOMIC_WORD* event_uid, const char* name) {
1204 category_enabled_ = 1291 category_enabled_ =
1205 reinterpret_cast<const unsigned char*>(TRACE_EVENT_API_ATOMIC_LOAD( 1292 reinterpret_cast<const unsigned char*>(TRACE_EVENT_API_ATOMIC_LOAD(
1206 *event_uid)); 1293 *event_uid));
1207 if (!category_enabled_) { 1294 if (!category_enabled_) {
1208 category_enabled_ = TRACE_EVENT_API_GET_CATEGORY_ENABLED("gpu"); 1295 category_enabled_ = TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("gpu");
1209 TRACE_EVENT_API_ATOMIC_STORE( 1296 TRACE_EVENT_API_ATOMIC_STORE(
1210 *event_uid, 1297 *event_uid,
1211 reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>(category_enabled_)); 1298 reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>(category_enabled_));
1212 } 1299 }
1213 if (*category_enabled_) { 1300 if (*category_enabled_) {
1214 name_ = name; 1301 name_ = name;
1215 TRACE_EVENT_API_ADD_TRACE_EVENT( 1302 TRACE_EVENT_API_ADD_TRACE_EVENT(
1216 TRACE_EVENT_PHASE_BEGIN, // phase 1303 TRACE_EVENT_PHASE_BEGIN, // phase
1217 category_enabled_, // category enabled 1304 category_enabled_, // category enabled
1218 name, // name 1305 name, // name
(...skipping 18 matching lines...) Expand all
1237 0, // num_args 1324 0, // num_args
1238 NULL, // arg_names 1325 NULL, // arg_names
1239 NULL, // arg_types 1326 NULL, // arg_types
1240 NULL, // arg_values 1327 NULL, // arg_values
1241 TRACE_EVENT_FLAG_NONE); // flags 1328 TRACE_EVENT_FLAG_NONE); // flags
1242 } 1329 }
1243 } 1330 }
1244 1331
1245 } // namespace trace_event_internal 1332 } // namespace trace_event_internal
1246 1333
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698