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

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

Issue 12096115: Update tracing framework to optionally use a ringbuffer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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 | Annotate | Revision Log
« no previous file with comments | « base/debug/trace_event_impl.h ('k') | base/debug/trace_event_unittest.cc » ('j') | 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 BASE_EXPORT TRACE_EVENT_API_ATOMIC_WORD g_trace_state1; 45 BASE_EXPORT TRACE_EVENT_API_ATOMIC_WORD g_trace_state1;
46 BASE_EXPORT TRACE_EVENT_API_ATOMIC_WORD g_trace_state2; 46 BASE_EXPORT TRACE_EVENT_API_ATOMIC_WORD g_trace_state2;
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 56
56 #define TRACE_EVENT_MAX_CATEGORIES 100 57 #define TRACE_EVENT_MAX_CATEGORIES 100
57 58
58 namespace { 59 namespace {
59 60
60 // Parallel arrays g_categories and g_category_enabled are separate so that 61 // Parallel arrays g_categories and g_category_enabled are separate so that
61 // a pointer to a member of g_category_enabled can be easily converted to an 62 // a pointer to a member of g_category_enabled can be easily converted to an
62 // index into g_categories. This allows macros to deal only with char enabled 63 // index into g_categories. This allows macros to deal only with char enabled
63 // pointers from g_category_enabled, and we can convert internally to determine 64 // pointers from g_category_enabled, and we can convert internally to determine
64 // the category name from the char enabled pointer. 65 // the category name from the char enabled pointer.
65 const char* g_categories[TRACE_EVENT_MAX_CATEGORIES] = { 66 const char* g_categories[TRACE_EVENT_MAX_CATEGORIES] = {
66 "tracing already shutdown", 67 "tracing already shutdown",
67 "tracing categories exhausted; must increase TRACE_EVENT_MAX_CATEGORIES", 68 "tracing categories exhausted; must increase TRACE_EVENT_MAX_CATEGORIES",
68 "__metadata", 69 "__metadata",
69 }; 70 };
71
70 // The enabled flag is char instead of bool so that the API can be used from C. 72 // The enabled flag is char instead of bool so that the API can be used from C.
71 unsigned char g_category_enabled[TRACE_EVENT_MAX_CATEGORIES] = { 0 }; 73 unsigned char g_category_enabled[TRACE_EVENT_MAX_CATEGORIES] = { 0 };
72 const int g_category_already_shutdown = 0; 74 const int g_category_already_shutdown = 0;
73 const int g_category_categories_exhausted = 1; 75 const int g_category_categories_exhausted = 1;
74 const int g_category_metadata = 2; 76 const int g_category_metadata = 2;
75 int g_category_index = 3; // skip initial 3 categories 77 int g_category_index = 3; // skip initial 3 categories
76 78
77 // The name of the current thread. This is used to decide if the current 79 // The name of the current thread. This is used to decide if the current
78 // thread name has changed. We combine all the seen thread names into the 80 // thread name has changed. We combine all the seen thread names into the
79 // output name for the thread. 81 // output name for the thread.
80 LazyInstance<ThreadLocalPointer<const char> >::Leaky 82 LazyInstance<ThreadLocalPointer<const char> >::Leaky
81 g_current_thread_name = LAZY_INSTANCE_INITIALIZER; 83 g_current_thread_name = LAZY_INSTANCE_INITIALIZER;
82 84
83 const char kRecordUntilFull[] = "record-until-full"; 85 const char kRecordUntilFull[] = "record-until-full";
86 const char kRecordContinuously[] = "record-continuously";
87
88 size_t NextIndex(size_t index) {
89 index++;
90 if (index >= kTraceEventBufferSize)
91 index = 0;
92 return index;
93 }
84 94
85 } // namespace 95 } // namespace
86 96
97 class TraceBufferRingBuffer : public TraceBuffer {
98 public:
99 TraceBufferRingBuffer()
100 : unused_event_index_(0),
101 oldest_event_index_(0) {
102 logged_events_.reserve(kTraceEventInitialBufferSize);
103 }
104
105 ~TraceBufferRingBuffer() {}
106
107 void AddEvent(const TraceEvent& event) OVERRIDE {
108 if (unused_event_index_ < Size())
109 logged_events_[unused_event_index_] = event;
110 else
111 logged_events_.push_back(event);
112
113 unused_event_index_ = NextIndex(unused_event_index_);
114 if (unused_event_index_ == oldest_event_index_) {
115 oldest_event_index_ = NextIndex(oldest_event_index_);
116 }
117 }
118
119 bool HasMoreEvents() const OVERRIDE {
120 return oldest_event_index_ != unused_event_index_;
121 }
122
123 const TraceEvent& NextEvent() OVERRIDE {
124 DCHECK(HasMoreEvents());
125
126 size_t next = oldest_event_index_;
127 oldest_event_index_ = NextIndex(oldest_event_index_);
128 return GetEventAt(next);
129 }
130
131 bool IsFull() const OVERRIDE {
132 return false;
133 }
134
135 size_t CountEnabledByName(const unsigned char* category,
136 const std::string& event_name) const OVERRIDE {
137 size_t notify_count = 0;
138 size_t index = oldest_event_index_;
139 while (index != unused_event_index_) {
140 const TraceEvent& event = GetEventAt(index);
141 if (category == event.category_enabled() &&
142 strcmp(event_name.c_str(), event.name()) == 0) {
143 ++notify_count;
144 }
145 index = NextIndex(index);
146 }
147 return notify_count;
148 }
149
150 const TraceEvent& GetEventAt(size_t index) const OVERRIDE {
151 DCHECK(index < logged_events_.size());
152 return logged_events_[index];
153 }
154
155 size_t Size() const OVERRIDE {
156 return logged_events_.size();
157 }
158
159 private:
160 size_t unused_event_index_;
161 size_t oldest_event_index_;
162 std::vector<TraceEvent> logged_events_;
163
164 DISALLOW_COPY_AND_ASSIGN(TraceBufferRingBuffer);
165 };
166
167 class TraceBufferVector : public TraceBuffer {
168 public:
169 TraceBufferVector() : current_iteration_index_(0) {
170 logged_events_.reserve(kTraceEventInitialBufferSize);
171 }
172
173 ~TraceBufferVector() {
174 }
175
176 void AddEvent(const TraceEvent& event) OVERRIDE {
177 // Note, we have two callers which need to be handled. The first is
178 // AddTraceEventWithThreadIdAndTimestamp() which checks Size() and does an
179 // early exit if full. The second is AddThreadNameMetadataEvents().
180 // We can not DECHECK(!IsFull()) because we have to add the metadata
181 // events even if the buffer is full.
182 logged_events_.push_back(event);
183 }
184
185 bool HasMoreEvents() const OVERRIDE {
186 return current_iteration_index_ < Size();
187 }
188
189 const TraceEvent& NextEvent() OVERRIDE {
190 DCHECK(HasMoreEvents());
191 return GetEventAt(current_iteration_index_++);
192 }
193
194 bool IsFull() const OVERRIDE {
195 return Size() >= kTraceEventBufferSize;
196 }
197
198 size_t CountEnabledByName(const unsigned char* category,
199 const std::string& event_name) const OVERRIDE {
200 size_t notify_count = 0;
201 for (size_t i = 0; i < Size(); i++) {
202 const TraceEvent& event = GetEventAt(i);
203 if (category == event.category_enabled() &&
204 strcmp(event_name.c_str(), event.name()) == 0) {
205 ++notify_count;
206 }
207 }
208 return notify_count;
209 }
210
211 const TraceEvent& GetEventAt(size_t index) const OVERRIDE {
212 DCHECK(index < logged_events_.size());
213 return logged_events_[index];
214 }
215
216 size_t Size() const OVERRIDE {
217 return logged_events_.size();
218 }
219
220 private:
221 size_t current_iteration_index_;
222 std::vector<TraceEvent> logged_events_;
223
224 DISALLOW_COPY_AND_ASSIGN(TraceBufferVector);
225 };
226
87 //////////////////////////////////////////////////////////////////////////////// 227 ////////////////////////////////////////////////////////////////////////////////
88 // 228 //
89 // TraceEvent 229 // TraceEvent
90 // 230 //
91 //////////////////////////////////////////////////////////////////////////////// 231 ////////////////////////////////////////////////////////////////////////////////
92 232
93 namespace { 233 namespace {
94 234
95 size_t GetAllocLength(const char* str) { return str ? strlen(str) + 1 : 0; } 235 size_t GetAllocLength(const char* str) { return str ? strlen(str) + 1 : 0; }
96 236
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 start_pos += 2; 371 start_pos += 2;
232 } 372 }
233 *out += "\""; 373 *out += "\"";
234 break; 374 break;
235 default: 375 default:
236 NOTREACHED() << "Don't know how to print this value"; 376 NOTREACHED() << "Don't know how to print this value";
237 break; 377 break;
238 } 378 }
239 } 379 }
240 380
241 void TraceEvent::AppendEventsAsJSON(const std::vector<TraceEvent>& events,
242 size_t start,
243 size_t count,
244 std::string* out) {
245 for (size_t i = 0; i < count && start + i < events.size(); ++i) {
246 if (i > 0)
247 *out += ",";
248 events[i + start].AppendAsJSON(out);
249 }
250 }
251
252 void TraceEvent::AppendAsJSON(std::string* out) const { 381 void TraceEvent::AppendAsJSON(std::string* out) const {
253 int64 time_int64 = timestamp_.ToInternalValue(); 382 int64 time_int64 = timestamp_.ToInternalValue();
254 int process_id = TraceLog::GetInstance()->process_id(); 383 int process_id = TraceLog::GetInstance()->process_id();
255 // Category name checked at category creation time. 384 // Category name checked at category creation time.
256 DCHECK(!strchr(name_, '"')); 385 DCHECK(!strchr(name_, '"'));
257 StringAppendF(out, 386 StringAppendF(out,
258 "{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 "," 387 "{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 ","
259 "\"ph\":\"%c\",\"name\":\"%s\",\"args\":{", 388 "\"ph\":\"%c\",\"name\":\"%s\",\"args\":{",
260 TraceLog::GetCategoryName(category_enabled_), 389 TraceLog::GetCategoryName(category_enabled_),
261 process_id, 390 process_id,
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 // content/browser/devtools/devtools_tracing_handler:TraceOptionsFromString 633 // content/browser/devtools/devtools_tracing_handler:TraceOptionsFromString
505 TraceLog::Options TraceLog::TraceOptionsFromString(const std::string& options) { 634 TraceLog::Options TraceLog::TraceOptionsFromString(const std::string& options) {
506 std::vector<std::string> split; 635 std::vector<std::string> split;
507 base::SplitString(options, ',', &split); 636 base::SplitString(options, ',', &split);
508 int ret = 0; 637 int ret = 0;
509 for (std::vector<std::string>::iterator iter = split.begin(); 638 for (std::vector<std::string>::iterator iter = split.begin();
510 iter != split.end(); 639 iter != split.end();
511 ++iter) { 640 ++iter) {
512 if (*iter == kRecordUntilFull) { 641 if (*iter == kRecordUntilFull) {
513 ret |= RECORD_UNTIL_FULL; 642 ret |= RECORD_UNTIL_FULL;
643 } else if (*iter == kRecordContinuously) {
644 ret |= RECORD_CONTINUOUSLY;
514 } else { 645 } else {
515 NOTREACHED(); // Unknown option provided. 646 NOTREACHED(); // Unknown option provided.
516 } 647 }
517 } 648 }
518 // Check to see if any RECORD_* options are set, and if none, then provide 649 if (!(ret & RECORD_UNTIL_FULL) && !(ret & RECORD_CONTINUOUSLY))
519 // a default.
520 // TODO(dsinclair): Remove this comment when we have more then one RECORD_*
521 // flag and the code's structure is then sensible.
522 if (!(ret & RECORD_UNTIL_FULL))
523 ret |= RECORD_UNTIL_FULL; // Default when no options are specified. 650 ret |= RECORD_UNTIL_FULL; // Default when no options are specified.
524 651
525 return static_cast<Options>(ret); 652 return static_cast<Options>(ret);
526 } 653 }
527 654
528 TraceLog::TraceLog() 655 TraceLog::TraceLog()
529 : enable_count_(0), 656 : enable_count_(0),
657 logged_events_(NULL),
530 dispatching_to_observer_list_(false), 658 dispatching_to_observer_list_(false),
531 watch_category_(NULL), 659 watch_category_(NULL),
532 trace_options_(RECORD_UNTIL_FULL), 660 trace_options_(RECORD_UNTIL_FULL),
533 sampling_thread_handle_(0) { 661 sampling_thread_handle_(0) {
534 // Trace is enabled or disabled on one thread while other threads are 662 // Trace is enabled or disabled on one thread while other threads are
535 // accessing the enabled flag. We don't care whether edge-case events are 663 // accessing the enabled flag. We don't care whether edge-case events are
536 // traced or not, so we allow races on the enabled flag to keep the trace 664 // traced or not, so we allow races on the enabled flag to keep the trace
537 // macros fast. 665 // macros fast.
538 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: 666 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots:
539 // ANNOTATE_BENIGN_RACE_SIZED(g_category_enabled, sizeof(g_category_enabled), 667 // ANNOTATE_BENIGN_RACE_SIZED(g_category_enabled, sizeof(g_category_enabled),
540 // "trace_event category enabled"); 668 // "trace_event category enabled");
541 for (int i = 0; i < TRACE_EVENT_MAX_CATEGORIES; ++i) { 669 for (int i = 0; i < TRACE_EVENT_MAX_CATEGORIES; ++i) {
542 ANNOTATE_BENIGN_RACE(&g_category_enabled[i], 670 ANNOTATE_BENIGN_RACE(&g_category_enabled[i],
543 "trace_event category enabled"); 671 "trace_event category enabled");
544 } 672 }
545 #if defined(OS_NACL) // NaCl shouldn't expose the process id. 673 #if defined(OS_NACL) // NaCl shouldn't expose the process id.
546 SetProcessID(0); 674 SetProcessID(0);
547 #else 675 #else
548 SetProcessID(static_cast<int>(GetCurrentProcId())); 676 SetProcessID(static_cast<int>(GetCurrentProcId()));
549 #endif 677 #endif
678
679 logged_events_.reset(GetTraceBuffer());
550 } 680 }
551 681
552 TraceLog::~TraceLog() { 682 TraceLog::~TraceLog() {
553 } 683 }
554 684
555 const unsigned char* TraceLog::GetCategoryEnabled(const char* name) { 685 const unsigned char* TraceLog::GetCategoryEnabled(const char* name) {
556 TraceLog* tracelog = GetInstance(); 686 TraceLog* tracelog = GetInstance();
557 if (!tracelog) { 687 if (!tracelog) {
558 DCHECK(!g_category_enabled[g_category_already_shutdown]); 688 DCHECK(!g_category_enabled[g_category_already_shutdown]);
559 return &g_category_enabled[g_category_already_shutdown]; 689 return &g_category_enabled[g_category_already_shutdown];
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 included_categories.end()); 805 included_categories.end());
676 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0); 806 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0);
677 } else { 807 } else {
678 // If either old or new included categories are empty, allow all events. 808 // If either old or new included categories are empty, allow all events.
679 included_categories_.clear(); 809 included_categories_.clear();
680 excluded_categories_.clear(); 810 excluded_categories_.clear();
681 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED); 811 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED);
682 } 812 }
683 return; 813 return;
684 } 814 }
685 trace_options_ = options; 815
816 if (options != trace_options_) {
817 trace_options_ = options;
818 logged_events_.reset(GetTraceBuffer());
819 }
686 820
687 if (dispatching_to_observer_list_) { 821 if (dispatching_to_observer_list_) {
688 DLOG(ERROR) << 822 DLOG(ERROR) <<
689 "Cannot manipulate TraceLog::Enabled state from an observer."; 823 "Cannot manipulate TraceLog::Enabled state from an observer.";
690 return; 824 return;
691 } 825 }
692 826
693 dispatching_to_observer_list_ = true; 827 dispatching_to_observer_list_ = true;
694 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, 828 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_,
695 OnTraceLogWillEnable()); 829 OnTraceLogWillEnable());
696 dispatching_to_observer_list_ = false; 830 dispatching_to_observer_list_ = false;
697 831
698 logged_events_.reserve(1024);
699 included_categories_ = included_categories; 832 included_categories_ = included_categories;
700 excluded_categories_ = excluded_categories; 833 excluded_categories_ = excluded_categories;
701 // Note that if both included and excluded_categories are empty, the else 834 // Note that if both included and excluded_categories are empty, the else
702 // clause below excludes nothing, thereby enabling all categories. 835 // clause below excludes nothing, thereby enabling all categories.
703 if (!included_categories_.empty()) 836 if (!included_categories_.empty())
704 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0); 837 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0);
705 else 838 else
706 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED); 839 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED);
707 840
708 if (options & ENABLE_SAMPLING) { 841 if (options & ENABLE_SAMPLING) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 void TraceLog::AddEnabledStateObserver(EnabledStateChangedObserver* listener) { 937 void TraceLog::AddEnabledStateObserver(EnabledStateChangedObserver* listener) {
805 enabled_state_observer_list_.AddObserver(listener); 938 enabled_state_observer_list_.AddObserver(listener);
806 } 939 }
807 940
808 void TraceLog::RemoveEnabledStateObserver( 941 void TraceLog::RemoveEnabledStateObserver(
809 EnabledStateChangedObserver* listener) { 942 EnabledStateChangedObserver* listener) {
810 enabled_state_observer_list_.RemoveObserver(listener); 943 enabled_state_observer_list_.RemoveObserver(listener);
811 } 944 }
812 945
813 float TraceLog::GetBufferPercentFull() const { 946 float TraceLog::GetBufferPercentFull() const {
814 return (float)((double)logged_events_.size()/(double)kTraceEventBufferSize); 947 return (float)((double)logged_events_->Size()/(double)kTraceEventBufferSize);
815 } 948 }
816 949
817 void TraceLog::SetNotificationCallback( 950 void TraceLog::SetNotificationCallback(
818 const TraceLog::NotificationCallback& cb) { 951 const TraceLog::NotificationCallback& cb) {
819 AutoLock lock(lock_); 952 AutoLock lock(lock_);
820 notification_callback_ = cb; 953 notification_callback_ = cb;
821 } 954 }
822 955
956 TraceBuffer* TraceLog::GetTraceBuffer() {
957 if (trace_options_ & RECORD_CONTINUOUSLY)
958 return new TraceBufferRingBuffer();
959 return new TraceBufferVector();
960 }
961
823 void TraceLog::SetEventCallback(EventCallback cb) { 962 void TraceLog::SetEventCallback(EventCallback cb) {
824 AutoLock lock(lock_); 963 AutoLock lock(lock_);
825 event_callback_ = cb; 964 event_callback_ = cb;
826 }; 965 };
827 966
828 void TraceLog::Flush(const TraceLog::OutputCallback& cb) { 967 void TraceLog::Flush(const TraceLog::OutputCallback& cb) {
829 std::vector<TraceEvent> previous_logged_events; 968 scoped_ptr<TraceBuffer> previous_logged_events;
830 { 969 {
831 AutoLock lock(lock_); 970 AutoLock lock(lock_);
832 previous_logged_events.swap(logged_events_); 971 previous_logged_events.swap(logged_events_);
972 logged_events_.reset(GetTraceBuffer());
833 } // release lock 973 } // release lock
834 974
835 for (size_t i = 0; 975 while (previous_logged_events->HasMoreEvents()) {
836 i < previous_logged_events.size();
837 i += kTraceEventBatchSize) {
838 scoped_refptr<RefCountedString> json_events_str_ptr = 976 scoped_refptr<RefCountedString> json_events_str_ptr =
839 new RefCountedString(); 977 new RefCountedString();
840 TraceEvent::AppendEventsAsJSON(previous_logged_events, 978
841 i, 979 for (size_t i = 0; i < kTraceEventBatchSize; ++i) {
842 kTraceEventBatchSize, 980 if (i > 0)
843 &(json_events_str_ptr->data())); 981 *(&(json_events_str_ptr->data())) += ",";
982
983 previous_logged_events->NextEvent().AppendAsJSON(
984 &(json_events_str_ptr->data()));
985
986 if (!previous_logged_events->HasMoreEvents())
987 break;
988 }
989
844 cb.Run(json_events_str_ptr); 990 cb.Run(json_events_str_ptr);
845 } 991 }
846 } 992 }
847 993
848 void TraceLog::AddTraceEvent(char phase, 994 void TraceLog::AddTraceEvent(char phase,
849 const unsigned char* category_enabled, 995 const unsigned char* category_enabled,
850 const char* name, 996 const char* name,
851 unsigned long long id, 997 unsigned long long id,
852 int num_args, 998 int num_args,
853 const char** arg_names, 999 const char** arg_names,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 1031
886 TimeTicks now = timestamp - time_offset_; 1032 TimeTicks now = timestamp - time_offset_;
887 EventCallback event_callback_copy; 1033 EventCallback event_callback_copy;
888 1034
889 NotificationHelper notifier(this); 1035 NotificationHelper notifier(this);
890 1036
891 { 1037 {
892 AutoLock lock(lock_); 1038 AutoLock lock(lock_);
893 if (*category_enabled != CATEGORY_ENABLED) 1039 if (*category_enabled != CATEGORY_ENABLED)
894 return; 1040 return;
895 if (logged_events_.size() >= kTraceEventBufferSize) 1041 if (logged_events_->IsFull())
896 return; 1042 return;
897 1043
898 const char* new_name = ThreadIdNameManager::GetInstance()-> 1044 const char* new_name = ThreadIdNameManager::GetInstance()->
899 GetName(thread_id); 1045 GetName(thread_id);
900 // Check if the thread name has been set or changed since the previous 1046 // Check if the thread name has been set or changed since the previous
901 // call (if any), but don't bother if the new name is empty. Note this will 1047 // call (if any), but don't bother if the new name is empty. Note this will
902 // not detect a thread name change within the same char* buffer address: we 1048 // not detect a thread name change within the same char* buffer address: we
903 // favor common case performance over corner case correctness. 1049 // favor common case performance over corner case correctness.
904 if (new_name != g_current_thread_name.Get().Get() && 1050 if (new_name != g_current_thread_name.Get().Get() &&
905 new_name && *new_name) { 1051 new_name && *new_name) {
(...skipping 12 matching lines...) Expand all
918 bool found = std::find(existing_names.begin(), 1064 bool found = std::find(existing_names.begin(),
919 existing_names.end(), 1065 existing_names.end(),
920 new_name) != existing_names.end(); 1066 new_name) != existing_names.end();
921 if (!found) { 1067 if (!found) {
922 existing_name->second.push_back(','); 1068 existing_name->second.push_back(',');
923 existing_name->second.append(new_name); 1069 existing_name->second.append(new_name);
924 } 1070 }
925 } 1071 }
926 } 1072 }
927 1073
928 logged_events_.push_back( 1074 logged_events_->AddEvent(TraceEvent(thread_id,
929 TraceEvent(thread_id, 1075 now, phase, category_enabled, name, id,
930 now, phase, category_enabled, name, id, 1076 num_args, arg_names, arg_types, arg_values,
931 num_args, arg_names, arg_types, arg_values, 1077 flags));
932 flags));
933 1078
934 if (logged_events_.size() == kTraceEventBufferSize) 1079 if (logged_events_->IsFull())
935 notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL); 1080 notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL);
936 1081
937 if (watch_category_ == category_enabled && watch_event_name_ == name) 1082 if (watch_category_ == category_enabled && watch_event_name_ == name)
938 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION); 1083 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION);
939 1084
940 event_callback_copy = event_callback_; 1085 event_callback_copy = event_callback_;
941 } // release lock 1086 } // release lock
942 1087
943 notifier.SendNotificationIfAny(); 1088 notifier.SendNotificationIfAny();
944 if (event_callback_copy != NULL) { 1089 if (event_callback_copy != NULL) {
(...skipping 22 matching lines...) Expand all
967 #if defined(OS_WIN) 1112 #if defined(OS_WIN)
968 TraceEventETWProvider::Trace(name, phase, id, extra); 1113 TraceEventETWProvider::Trace(name, phase, id, extra);
969 #endif 1114 #endif
970 INTERNAL_TRACE_EVENT_ADD(phase, "ETW Trace Event", name, 1115 INTERNAL_TRACE_EVENT_ADD(phase, "ETW Trace Event", name,
971 TRACE_EVENT_FLAG_COPY, "id", id, "extra", extra); 1116 TRACE_EVENT_FLAG_COPY, "id", id, "extra", extra);
972 } 1117 }
973 1118
974 void TraceLog::SetWatchEvent(const std::string& category_name, 1119 void TraceLog::SetWatchEvent(const std::string& category_name,
975 const std::string& event_name) { 1120 const std::string& event_name) {
976 const unsigned char* category = GetCategoryEnabled(category_name.c_str()); 1121 const unsigned char* category = GetCategoryEnabled(category_name.c_str());
977 int notify_count = 0; 1122 size_t notify_count = 0;
978 { 1123 {
979 AutoLock lock(lock_); 1124 AutoLock lock(lock_);
980 watch_category_ = category; 1125 watch_category_ = category;
981 watch_event_name_ = event_name; 1126 watch_event_name_ = event_name;
982 1127
983 // First, search existing events for watch event because we want to catch it 1128 // First, search existing events for watch event because we want to catch
984 // even if it has already occurred. 1129 // it even if it has already occurred.
985 for (size_t i = 0u; i < logged_events_.size(); ++i) { 1130 notify_count = logged_events_->CountEnabledByName(category, event_name);
986 if (category == logged_events_[i].category_enabled() &&
987 strcmp(event_name.c_str(), logged_events_[i].name()) == 0) {
988 ++notify_count;
989 }
990 }
991 } // release lock 1131 } // release lock
992 1132
993 // Send notification for each event found. 1133 // Send notification for each event found.
994 for (int i = 0; i < notify_count; ++i) { 1134 for (size_t i = 0; i < notify_count; ++i) {
995 NotificationHelper notifier(this); 1135 NotificationHelper notifier(this);
996 lock_.Acquire(); 1136 lock_.Acquire();
997 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION); 1137 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION);
998 lock_.Release(); 1138 lock_.Release();
999 notifier.SendNotificationIfAny(); 1139 notifier.SendNotificationIfAny();
1000 } 1140 }
1001 } 1141 }
1002 1142
1003 void TraceLog::CancelWatchEvent() { 1143 void TraceLog::CancelWatchEvent() {
1004 AutoLock lock(lock_); 1144 AutoLock lock(lock_);
1005 watch_category_ = NULL; 1145 watch_category_ = NULL;
1006 watch_event_name_ = ""; 1146 watch_event_name_ = "";
1007 } 1147 }
1008 1148
1009 void TraceLog::AddThreadNameMetadataEvents() { 1149 void TraceLog::AddThreadNameMetadataEvents() {
1010 lock_.AssertAcquired(); 1150 lock_.AssertAcquired();
1011 for(hash_map<int, std::string>::iterator it = thread_names_.begin(); 1151 for(hash_map<int, std::string>::iterator it = thread_names_.begin();
1012 it != thread_names_.end(); 1152 it != thread_names_.end();
1013 it++) { 1153 it++) {
1014 if (!it->second.empty()) { 1154 if (!it->second.empty()) {
1015 int num_args = 1; 1155 int num_args = 1;
1016 const char* arg_name = "name"; 1156 const char* arg_name = "name";
1017 unsigned char arg_type; 1157 unsigned char arg_type;
1018 unsigned long long arg_value; 1158 unsigned long long arg_value;
1019 trace_event_internal::SetTraceValue(it->second, &arg_type, &arg_value); 1159 trace_event_internal::SetTraceValue(it->second, &arg_type, &arg_value);
1020 logged_events_.push_back( 1160 logged_events_->AddEvent(TraceEvent(it->first,
1021 TraceEvent(it->first, 1161 TimeTicks(), TRACE_EVENT_PHASE_METADATA,
1022 TimeTicks(), TRACE_EVENT_PHASE_METADATA, 1162 &g_category_enabled[g_category_metadata],
1023 &g_category_enabled[g_category_metadata], 1163 "thread_name", trace_event_internal::kNoEventId,
1024 "thread_name", trace_event_internal::kNoEventId, 1164 num_args, &arg_name, &arg_type, &arg_value,
1025 num_args, &arg_name, &arg_type, &arg_value, 1165 TRACE_EVENT_FLAG_NONE));
1026 TRACE_EVENT_FLAG_NONE));
1027 } 1166 }
1028 } 1167 }
1029 } 1168 }
1030 1169
1031 void TraceLog::InstallWaitableEventForSamplingTesting( 1170 void TraceLog::InstallWaitableEventForSamplingTesting(
1032 WaitableEvent* waitable_event) { 1171 WaitableEvent* waitable_event) {
1033 sampling_thread_->InstallWaitableEventForSamplingTesting(waitable_event); 1172 sampling_thread_->InstallWaitableEventForSamplingTesting(waitable_event);
1034 } 1173 }
1035 1174
1036 void TraceLog::DeleteForTesting() { 1175 void TraceLog::DeleteForTesting() {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 0, // num_args 1237 0, // num_args
1099 NULL, // arg_names 1238 NULL, // arg_names
1100 NULL, // arg_types 1239 NULL, // arg_types
1101 NULL, // arg_values 1240 NULL, // arg_values
1102 TRACE_EVENT_FLAG_NONE); // flags 1241 TRACE_EVENT_FLAG_NONE); // flags
1103 } 1242 }
1104 } 1243 }
1105 1244
1106 } // namespace trace_event_internal 1245 } // namespace trace_event_internal
1107 1246
OLDNEW
« no previous file with comments | « base/debug/trace_event_impl.h ('k') | base/debug/trace_event_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698