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

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

Issue 8590015: trace_event: distinguish between scoped begin/end and global start/finish events (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: jam, nduca feedback Created 9 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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.h" 5 #include "base/debug/trace_event.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/format_macros.h" 10 #include "base/format_macros.h"
(...skipping 25 matching lines...) Expand all
36 36
37 // Controls the number of trace events we will buffer in-memory 37 // Controls the number of trace events we will buffer in-memory
38 // before throwing them away. 38 // before throwing them away.
39 const size_t kTraceEventBufferSize = 500000; 39 const size_t kTraceEventBufferSize = 500000;
40 const size_t kTraceEventBatchSize = 1000; 40 const size_t kTraceEventBatchSize = 1000;
41 41
42 #define TRACE_EVENT_MAX_CATEGORIES 100 42 #define TRACE_EVENT_MAX_CATEGORIES 100
43 43
44 namespace { 44 namespace {
45 45
46 // Specify these values when the corresponding argument of AddTraceEvent is not
47 // used.
48 static const char* kNoArgName = NULL;
49 static const int kNoArgValue = 0;
50 static const int kNoThreshholdBeginId = -1;
51 static const int64 kNoThresholdValue = 0;
52 static const int kNoEventId = 0;
53
46 TraceCategory g_categories[TRACE_EVENT_MAX_CATEGORIES] = { 54 TraceCategory g_categories[TRACE_EVENT_MAX_CATEGORIES] = {
47 { "tracing already shutdown", false }, 55 { "tracing already shutdown", false },
48 { "tracing categories exhausted; must increase TRACE_EVENT_MAX_CATEGORIES", 56 { "tracing categories exhausted; must increase TRACE_EVENT_MAX_CATEGORIES",
49 false }, 57 false },
50 { "__metadata", 58 { "__metadata",
51 false } 59 false }
52 }; 60 };
53 const TraceCategory* const g_category_already_shutdown = 61 const TraceCategory* const g_category_already_shutdown =
54 &g_categories[0]; 62 &g_categories[0];
55 const TraceCategory* const g_category_categories_exhausted = 63 const TraceCategory* const g_category_categories_exhausted =
56 &g_categories[1]; 64 &g_categories[1];
57 const TraceCategory* const g_category_metadata = 65 const TraceCategory* const g_category_metadata =
58 &g_categories[2]; 66 &g_categories[2];
59 int g_category_index = 3; // skip initial 3 categories 67 int g_category_index = 3; // skip initial 3 categories
60 68
61 // The most-recently captured name of the current thread 69 // The most-recently captured name of the current thread
62 LazyInstance<ThreadLocalPointer<const char>, 70 LazyInstance<ThreadLocalPointer<const char>,
63 LeakyLazyInstanceTraits<ThreadLocalPointer<const char> > > 71 LeakyLazyInstanceTraits<ThreadLocalPointer<const char> > >
64 g_current_thread_name = LAZY_INSTANCE_INITIALIZER; 72 g_current_thread_name = LAZY_INSTANCE_INITIALIZER;
65 73
66 } // namespace 74 } // namespace
67 75
68 //////////////////////////////////////////////////////////////////////////////// 76 ////////////////////////////////////////////////////////////////////////////////
69 // 77 //
70 // TraceValue 78 // TraceValue
71 // 79 //
72 //////////////////////////////////////////////////////////////////////////////// 80 ////////////////////////////////////////////////////////////////////////////////
73 81
74 void TraceValue::AppendAsJSON(std::string* out) const { 82 void TraceValue::AppendAsJSON(std::string* out) const {
75 char temp_string[128];
76 std::string::size_type start_pos; 83 std::string::size_type start_pos;
77 switch (type_) { 84 switch (type_) {
78 case TRACE_TYPE_BOOL: 85 case TRACE_TYPE_BOOL:
79 *out += as_bool() ? "true" : "false"; 86 *out += as_bool() ? "true" : "false";
80 break; 87 break;
81 case TRACE_TYPE_UINT: 88 case TRACE_TYPE_UINT:
82 base::snprintf(temp_string, arraysize(temp_string), "%llu", 89 StringAppendF(out, "%" PRIu64, as_uint());
83 static_cast<unsigned long long>(as_uint()));
84 *out += temp_string;
85 break; 90 break;
86 case TRACE_TYPE_INT: 91 case TRACE_TYPE_INT:
87 base::snprintf(temp_string, arraysize(temp_string), "%lld", 92 StringAppendF(out, "%" PRId64, as_int());
88 static_cast<long long>(as_int()));
89 *out += temp_string;
90 break; 93 break;
91 case TRACE_TYPE_DOUBLE: 94 case TRACE_TYPE_DOUBLE:
92 base::snprintf(temp_string, arraysize(temp_string), "%f", as_double()); 95 StringAppendF(out, "%f", as_double());
93 *out += temp_string;
94 break; 96 break;
95 case TRACE_TYPE_POINTER: 97 case TRACE_TYPE_POINTER:
96 base::snprintf(temp_string, arraysize(temp_string), "%llu", 98 // JSON only supports double and int numbers.
97 static_cast<unsigned long long>( 99 // So as not to lose bits from a 64-bit pointer, output as a hex string.
98 reinterpret_cast<intptr_t>( 100 StringAppendF(out, "\"%" PRIx64 "\"", static_cast<uint64>(
99 as_pointer()))); 101 reinterpret_cast<intptr_t>(
100 *out += temp_string; 102 as_pointer())));
101 break; 103 break;
102 case TRACE_TYPE_STRING: 104 case TRACE_TYPE_STRING:
103 case TRACE_TYPE_STATIC_STRING: 105 case TRACE_TYPE_STATIC_STRING:
104 *out += "\""; 106 *out += "\"";
105 start_pos = out->size(); 107 start_pos = out->size();
106 *out += as_string() ? as_string() : "NULL"; 108 *out += as_string() ? as_string() : "NULL";
107 // insert backslash before special characters for proper json format. 109 // insert backslash before special characters for proper json format.
108 while ((start_pos = out->find_first_of("\\\"", start_pos)) != 110 while ((start_pos = out->find_first_of("\\\"", start_pos)) !=
109 std::string::npos) { 111 std::string::npos) {
110 out->insert(start_pos, 1, '\\'); 112 out->insert(start_pos, 1, '\\');
111 // skip inserted escape character and following character. 113 // skip inserted escape character and following character.
112 start_pos += 2; 114 start_pos += 2;
113 } 115 }
114 *out += "\""; 116 *out += "\"";
115 break; 117 break;
116 default: 118 default:
117 NOTREACHED() << "Don't know how to print this value"; 119 NOTREACHED() << "Don't know how to print this value";
118 break; 120 break;
119 } 121 }
120 } 122 }
121 123
122 //////////////////////////////////////////////////////////////////////////////// 124 ////////////////////////////////////////////////////////////////////////////////
123 // 125 //
126 // TraceID
127 //
128 ////////////////////////////////////////////////////////////////////////////////
129
130 TraceID::TraceID(void* rhs) {
131 data_ = base::debug::TraceLog::GetInstance()->GetIntraProcessID(
132 static_cast<uint64>(reinterpret_cast<uintptr_t>(rhs)));
133 }
134
135 ////////////////////////////////////////////////////////////////////////////////
136 //
124 // TraceEvent 137 // TraceEvent
125 // 138 //
126 //////////////////////////////////////////////////////////////////////////////// 139 ////////////////////////////////////////////////////////////////////////////////
127 140
128 namespace { 141 namespace {
129 142
130 size_t GetAllocLength(const char* str) { return str ? strlen(str) + 1 : 0; } 143 size_t GetAllocLength(const char* str) { return str ? strlen(str) + 1 : 0; }
131 144
132 // Copies |*member| into |*buffer|, sets |*member| to point to this new 145 // Copies |*member| into |*buffer|, sets |*member| to point to this new
133 // location, and then advances |*buffer| by the amount written. 146 // location, and then advances |*buffer| by the amount written.
134 void CopyTraceEventParameter(char** buffer, 147 void CopyTraceEventParameter(char** buffer,
135 const char** member, 148 const char** member,
136 const char* end) { 149 const char* end) {
137 if (*member) { 150 if (*member) {
138 size_t written = strlcpy(*buffer, *member, end - *buffer) + 1; 151 size_t written = strlcpy(*buffer, *member, end - *buffer) + 1;
139 DCHECK_LE(static_cast<int>(written), end - *buffer); 152 DCHECK_LE(static_cast<int>(written), end - *buffer);
140 *member = *buffer; 153 *member = *buffer;
141 *buffer += written; 154 *buffer += written;
142 } 155 }
143 } 156 }
144 157
145 } // namespace 158 } // namespace
146 159
147 TraceEvent::TraceEvent() 160 TraceEvent::TraceEvent()
148 : process_id_(0), 161 : id_(0u),
162 category_(NULL),
163 name_(NULL),
149 thread_id_(0), 164 thread_id_(0),
150 phase_(TRACE_EVENT_PHASE_BEGIN), 165 phase_(TRACE_EVENT_PHASE_BEGIN),
151 category_(NULL), 166 flags_(0) {
152 name_(NULL) {
153 arg_names_[0] = NULL; 167 arg_names_[0] = NULL;
154 arg_names_[1] = NULL; 168 arg_names_[1] = NULL;
155 } 169 }
156 170
157 TraceEvent::TraceEvent(unsigned long process_id, 171 TraceEvent::TraceEvent(int thread_id,
158 unsigned long thread_id,
159 TimeTicks timestamp, 172 TimeTicks timestamp,
160 TraceEventPhase phase, 173 TraceEventPhase phase,
161 const TraceCategory* category, 174 const TraceCategory* category,
162 const char* name, 175 const char* name,
176 TraceID id,
163 const char* arg1_name, const TraceValue& arg1_val, 177 const char* arg1_name, const TraceValue& arg1_val,
164 const char* arg2_name, const TraceValue& arg2_val, 178 const char* arg2_name, const TraceValue& arg2_val,
165 bool copy) 179 TraceEventFlags flags)
166 : process_id_(process_id), 180 : timestamp_(timestamp),
181 id_(id),
182 category_(category),
183 name_(name),
167 thread_id_(thread_id), 184 thread_id_(thread_id),
168 timestamp_(timestamp),
169 phase_(phase), 185 phase_(phase),
170 category_(category), 186 flags_(flags) {
171 name_(name) {
172 COMPILE_ASSERT(kTraceMaxNumArgs == 2, TraceEvent_arg_count_out_of_sync); 187 COMPILE_ASSERT(kTraceMaxNumArgs == 2, TraceEvent_arg_count_out_of_sync);
173 arg_names_[0] = arg1_name; 188 arg_names_[0] = arg1_name;
174 arg_names_[1] = arg2_name; 189 arg_names_[1] = arg2_name;
175 arg_values_[0] = arg1_val; 190 arg_values_[0] = arg1_val;
176 arg_values_[1] = arg2_val; 191 arg_values_[1] = arg2_val;
177 192
193 bool copy = !!(flags & TRACE_EVENT_FLAG_COPY);
178 size_t alloc_size = 0; 194 size_t alloc_size = 0;
179 if (copy) { 195 if (copy) {
180 alloc_size += GetAllocLength(name); 196 alloc_size += GetAllocLength(name);
181 alloc_size += GetAllocLength(arg1_name); 197 alloc_size += GetAllocLength(arg1_name);
182 alloc_size += GetAllocLength(arg2_name); 198 alloc_size += GetAllocLength(arg2_name);
183 } 199 }
184 200
185 bool arg1_is_copy = (arg1_val.type() == TraceValue::TRACE_TYPE_STRING); 201 bool arg1_is_copy = (arg1_val.type() == TraceValue::TRACE_TYPE_STRING);
186 bool arg2_is_copy = (arg2_val.type() == TraceValue::TRACE_TYPE_STRING); 202 bool arg2_is_copy = (arg2_val.type() == TraceValue::TRACE_TYPE_STRING);
187 203
(...skipping 18 matching lines...) Expand all
206 CopyTraceEventParameter(&ptr, arg_values_[0].as_assignable_string(), end); 222 CopyTraceEventParameter(&ptr, arg_values_[0].as_assignable_string(), end);
207 if (arg2_is_copy) 223 if (arg2_is_copy)
208 CopyTraceEventParameter(&ptr, arg_values_[1].as_assignable_string(), end); 224 CopyTraceEventParameter(&ptr, arg_values_[1].as_assignable_string(), end);
209 DCHECK_EQ(end, ptr) << "Overrun by " << ptr - end; 225 DCHECK_EQ(end, ptr) << "Overrun by " << ptr - end;
210 } 226 }
211 } 227 }
212 228
213 TraceEvent::~TraceEvent() { 229 TraceEvent::~TraceEvent() {
214 } 230 }
215 231
216 const char* TraceEvent::GetPhaseString(TraceEventPhase phase) {
217 switch(phase) {
218 case TRACE_EVENT_PHASE_BEGIN:
219 return "B";
220 case TRACE_EVENT_PHASE_INSTANT:
221 return "I";
222 case TRACE_EVENT_PHASE_END:
223 return "E";
224 case TRACE_EVENT_PHASE_METADATA:
225 return "M";
226 case TRACE_EVENT_PHASE_COUNTER:
227 return "C";
228 default:
229 NOTREACHED() << "Invalid phase argument";
230 return "?";
231 }
232 }
233
234 TraceEventPhase TraceEvent::GetPhase(const char* phase) {
235 switch(*phase) {
236 case 'B':
237 return TRACE_EVENT_PHASE_BEGIN;
238 case 'I':
239 return TRACE_EVENT_PHASE_INSTANT;
240 case 'E':
241 return TRACE_EVENT_PHASE_END;
242 case 'M':
243 return TRACE_EVENT_PHASE_METADATA;
244 case 'C':
245 return TRACE_EVENT_PHASE_COUNTER;
246 default:
247 NOTREACHED() << "Invalid phase name";
248 return TRACE_EVENT_PHASE_METADATA;
249 }
250 }
251
252 void TraceEvent::AppendEventsAsJSON(const std::vector<TraceEvent>& events, 232 void TraceEvent::AppendEventsAsJSON(const std::vector<TraceEvent>& events,
253 size_t start, 233 size_t start,
254 size_t count, 234 size_t count,
255 std::string* out) { 235 std::string* out) {
256 for (size_t i = 0; i < count && start + i < events.size(); ++i) { 236 for (size_t i = 0; i < count && start + i < events.size(); ++i) {
257 if (i > 0) 237 if (i > 0)
258 *out += ","; 238 *out += ",";
259 events[i + start].AppendAsJSON(out); 239 events[i + start].AppendAsJSON(out);
260 } 240 }
261 } 241 }
262 242
263 void TraceEvent::AppendAsJSON(std::string* out) const { 243 void TraceEvent::AppendAsJSON(std::string* out) const {
264 const char* phase_str = GetPhaseString(phase_); 244 const char phase_char = GetPhaseChar(phase_);
265 int64 time_int64 = timestamp_.ToInternalValue(); 245 int64 time_int64 = timestamp_.ToInternalValue();
246 int process_id = TraceLog::GetInstance()->process_id();
266 // Category name checked at category creation time. 247 // Category name checked at category creation time.
267 DCHECK(!strchr(name_, '"')); 248 DCHECK(!strchr(name_, '"'));
268 StringAppendF(out, 249 StringAppendF(out,
269 "{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%lld," 250 "{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 ","
270 "\"ph\":\"%s\",\"name\":\"%s\",\"args\":{", 251 "\"ph\":\"%c\",\"name\":\"%s\",\"args\":{",
271 category_->name, 252 category_->name,
272 static_cast<int>(process_id_), 253 process_id,
273 static_cast<int>(thread_id_), 254 thread_id_,
274 static_cast<long long>(time_int64), 255 time_int64,
275 phase_str, 256 phase_char,
276 name_); 257 name_);
277 258
278 // Output argument names and values, stop at first NULL argument name. 259 // Output argument names and values, stop at first NULL argument name.
279 for (size_t i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) { 260 for (size_t i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) {
280 if (i > 0) 261 if (i > 0)
281 *out += ","; 262 *out += ",";
282 *out += "\""; 263 *out += "\"";
283 *out += arg_names_[i]; 264 *out += arg_names_[i];
284 *out += "\":"; 265 *out += "\":";
285 arg_values_[i].AppendAsJSON(out); 266 arg_values_[i].AppendAsJSON(out);
286 } 267 }
287 *out += "}}"; 268 *out += "}";
269
270 // If id_ is set, print it out as a hex string so we don't loose any
271 // bits (it might be a 64-bit pointer).
272 if (flags_ & TRACE_EVENT_FLAG_HAS_ID)
273 StringAppendF(out, ",\"id\":\"%" PRIx64 "\"", id_.data());
274 *out += "}";
288 } 275 }
289 276
290 //////////////////////////////////////////////////////////////////////////////// 277 ////////////////////////////////////////////////////////////////////////////////
291 // 278 //
292 // TraceResultBuffer 279 // TraceResultBuffer
293 // 280 //
294 //////////////////////////////////////////////////////////////////////////////// 281 ////////////////////////////////////////////////////////////////////////////////
295 282
296 TraceResultBuffer::OutputCallback 283 TraceResultBuffer::OutputCallback
297 TraceResultBuffer::SimpleOutput::GetCallback() { 284 TraceResultBuffer::SimpleOutput::GetCallback() {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 // 322 //
336 //////////////////////////////////////////////////////////////////////////////// 323 ////////////////////////////////////////////////////////////////////////////////
337 324
338 // static 325 // static
339 TraceLog* TraceLog::GetInstance() { 326 TraceLog* TraceLog::GetInstance() {
340 return Singleton<TraceLog, StaticMemorySingletonTraits<TraceLog> >::get(); 327 return Singleton<TraceLog, StaticMemorySingletonTraits<TraceLog> >::get();
341 } 328 }
342 329
343 TraceLog::TraceLog() 330 TraceLog::TraceLog()
344 : enabled_(false) { 331 : enabled_(false) {
332 SetProcessID(static_cast<int>(base::GetCurrentProcId()));
345 } 333 }
346 334
347 TraceLog::~TraceLog() { 335 TraceLog::~TraceLog() {
348 } 336 }
349 337
350 const TraceCategory* TraceLog::GetCategory(const char* name) { 338 const TraceCategory* TraceLog::GetCategory(const char* name) {
351 TraceLog* tracelog = GetInstance(); 339 TraceLog* tracelog = GetInstance();
352 if (!tracelog){ 340 if (!tracelog){
353 DCHECK(!g_category_already_shutdown->enabled); 341 DCHECK(!g_category_already_shutdown->enabled);
354 return g_category_already_shutdown; 342 return g_category_already_shutdown;
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 i, 514 i,
527 kTraceEventBatchSize, 515 kTraceEventBatchSize,
528 &(json_events_str_ptr->data)); 516 &(json_events_str_ptr->data));
529 output_callback_copy.Run(json_events_str_ptr); 517 output_callback_copy.Run(json_events_str_ptr);
530 } 518 }
531 } 519 }
532 520
533 int TraceLog::AddTraceEvent(TraceEventPhase phase, 521 int TraceLog::AddTraceEvent(TraceEventPhase phase,
534 const TraceCategory* category, 522 const TraceCategory* category,
535 const char* name, 523 const char* name,
524 TraceID id,
536 const char* arg1_name, TraceValue arg1_val, 525 const char* arg1_name, TraceValue arg1_val,
537 const char* arg2_name, TraceValue arg2_val, 526 const char* arg2_name, TraceValue arg2_val,
538 int threshold_begin_id, 527 int threshold_begin_id,
539 int64 threshold, 528 int64 threshold,
540 EventFlags flags) { 529 TraceEventFlags flags) {
541 DCHECK(name); 530 DCHECK(name);
542 TimeTicks now = TimeTicks::HighResNow(); 531 TimeTicks now = TimeTicks::HighResNow();
543 BufferFullCallback buffer_full_callback_copy; 532 BufferFullCallback buffer_full_callback_copy;
544 int ret_begin_id = -1; 533 int ret_begin_id = -1;
545 { 534 {
546 AutoLock lock(lock_); 535 AutoLock lock(lock_);
547 if (!category->enabled) 536 if (!category->enabled)
548 return -1; 537 return -1;
549 if (logged_events_.size() >= kTraceEventBufferSize) 538 if (logged_events_.size() >= kTraceEventBufferSize)
550 return -1; 539 return -1;
551 540
552 PlatformThreadId thread_id = PlatformThread::CurrentId(); 541 int thread_id = static_cast<int>(PlatformThread::CurrentId());
553 542
554 const char* new_name = PlatformThread::GetName(); 543 const char* new_name = PlatformThread::GetName();
555 // Check if the thread name has been set or changed since the previous 544 // Check if the thread name has been set or changed since the previous
556 // call (if any), but don't bother if the new name is empty. Note this will 545 // call (if any), but don't bother if the new name is empty. Note this will
557 // not detect a thread name change within the same char* buffer address: we 546 // not detect a thread name change within the same char* buffer address: we
558 // favor common case performance over corner case correctness. 547 // favor common case performance over corner case correctness.
559 if (new_name != g_current_thread_name.Get().Get() && 548 if (new_name != g_current_thread_name.Get().Get() &&
560 new_name && *new_name) { 549 new_name && *new_name) {
561 g_current_thread_name.Get().Set(new_name); 550 g_current_thread_name.Get().Set(new_name);
562 base::hash_map<PlatformThreadId, std::string>::iterator existing_name = 551 base::hash_map<int, std::string>::iterator existing_name =
563 thread_names_.find(thread_id); 552 thread_names_.find(thread_id);
564 if (existing_name == thread_names_.end()) { 553 if (existing_name == thread_names_.end()) {
565 // This is a new thread id, and a new name. 554 // This is a new thread id, and a new name.
566 thread_names_[thread_id] = new_name; 555 thread_names_[thread_id] = new_name;
567 } else { 556 } else {
568 // This is a thread id that we've seen before, but potentially with a 557 // This is a thread id that we've seen before, but potentially with a
569 // new name. 558 // new name.
570 std::vector<base::StringPiece> existing_names; 559 std::vector<base::StringPiece> existing_names;
571 Tokenize(existing_name->second, ",", &existing_names); 560 Tokenize(existing_name->second, ",", &existing_names);
572 bool found = std::find(existing_names.begin(), 561 bool found = std::find(existing_names.begin(),
573 existing_names.end(), 562 existing_names.end(),
574 new_name) != existing_names.end(); 563 new_name) != existing_names.end();
575 if (!found) { 564 if (!found) {
576 existing_name->second.push_back(','); 565 existing_name->second.push_back(',');
577 existing_name->second.append(new_name); 566 existing_name->second.append(new_name);
578 } 567 }
579 } 568 }
580 } 569 }
581 570
582 if (threshold_begin_id > -1) { 571 if (threshold_begin_id > -1) {
583 DCHECK(phase == base::debug::TRACE_EVENT_PHASE_END); 572 DCHECK(phase == TRACE_EVENT_PHASE_END);
584 size_t begin_i = static_cast<size_t>(threshold_begin_id); 573 size_t begin_i = static_cast<size_t>(threshold_begin_id);
585 // Return now if there has been a flush since the begin event was posted. 574 // Return now if there has been a flush since the begin event was posted.
586 if (begin_i >= logged_events_.size()) 575 if (begin_i >= logged_events_.size())
587 return -1; 576 return -1;
588 // Determine whether to drop the begin/end pair. 577 // Determine whether to drop the begin/end pair.
589 TimeDelta elapsed = now - logged_events_[begin_i].timestamp(); 578 TimeDelta elapsed = now - logged_events_[begin_i].timestamp();
590 if (elapsed < TimeDelta::FromMicroseconds(threshold)) { 579 if (elapsed < TimeDelta::FromMicroseconds(threshold)) {
591 // Remove begin event and do not add end event. 580 // Remove begin event and do not add end event.
592 // This will be expensive if there have been other events in the 581 // This will be expensive if there have been other events in the
593 // mean time (should be rare). 582 // mean time (should be rare).
594 logged_events_.erase(logged_events_.begin() + begin_i); 583 logged_events_.erase(logged_events_.begin() + begin_i);
595 return -1; 584 return -1;
596 } 585 }
597 } 586 }
598 ret_begin_id = static_cast<int>(logged_events_.size()); 587 ret_begin_id = static_cast<int>(logged_events_.size());
599 logged_events_.push_back( 588 logged_events_.push_back(
600 TraceEvent(static_cast<unsigned long>(base::GetCurrentProcId()), 589 TraceEvent(thread_id,
601 thread_id, 590 now, phase, category, name, id,
602 now, phase, category, name,
603 arg1_name, arg1_val, 591 arg1_name, arg1_val,
604 arg2_name, arg2_val, 592 arg2_name, arg2_val,
605 flags & EVENT_FLAG_COPY)); 593 flags));
606 594
607 if (logged_events_.size() == kTraceEventBufferSize) { 595 if (logged_events_.size() == kTraceEventBufferSize) {
608 buffer_full_callback_copy = buffer_full_callback_; 596 buffer_full_callback_copy = buffer_full_callback_;
609 } 597 }
610 } // release lock 598 } // release lock
611 599
612 if (!buffer_full_callback_copy.is_null()) 600 if (!buffer_full_callback_copy.is_null())
613 buffer_full_callback_copy.Run(); 601 buffer_full_callback_copy.Run();
614 602
615 return ret_begin_id; 603 return ret_begin_id;
616 } 604 }
617 605
618 void TraceLog::AddTraceEventEtw(TraceEventPhase phase, 606 void TraceLog::AddTraceEventEtw(TraceEventPhase phase,
619 const char* name, 607 const char* name,
620 const void* id, 608 const void* id,
621 const char* extra) { 609 const char* extra) {
622 #if defined(OS_WIN) 610 #if defined(OS_WIN)
623 TraceEventETWProvider::Trace(name, phase, id, extra); 611 TraceEventETWProvider::Trace(name, phase, id, extra);
624 #endif 612 #endif
625 INTERNAL_TRACE_EVENT_ADD(phase, 613 INTERNAL_TRACE_EVENT_ADD(phase,
626 "ETW Trace Event", name, "id", id, "extra", TRACE_STR_COPY(extra), 614 "ETW Trace Event", name, "id", id, "extra", TRACE_STR_COPY(extra),
627 base::debug::TraceLog::EVENT_FLAG_COPY); 615 TRACE_EVENT_FLAG_COPY);
628 } 616 }
629 617
630 void TraceLog::AddTraceEventEtw(TraceEventPhase phase, 618 void TraceLog::AddTraceEventEtw(TraceEventPhase phase,
631 const char* name, 619 const char* name,
632 const void* id, 620 const void* id,
633 const std::string& extra) 621 const std::string& extra)
634 { 622 {
635 #if defined(OS_WIN) 623 #if defined(OS_WIN)
636 TraceEventETWProvider::Trace(name, phase, id, extra); 624 TraceEventETWProvider::Trace(name, phase, id, extra);
637 #endif 625 #endif
638 INTERNAL_TRACE_EVENT_ADD(phase, 626 INTERNAL_TRACE_EVENT_ADD(phase,
639 "ETW Trace Event", name, "id", id, "extra", extra, 627 "ETW Trace Event", name, "id", id, "extra", extra,
640 base::debug::TraceLog::EVENT_FLAG_COPY); 628 TRACE_EVENT_FLAG_COPY);
641 } 629 }
642 630
643 int TraceLog::AddCounterEvent(const TraceCategory* category, 631 int TraceLog::AddCounterEvent(const TraceCategory* category,
644 const char* name, 632 const char* name,
645 const char* value1_name, int32 value1_val, 633 const char* value1_name, int32 value1_val,
646 const char* value2_name, int32 value2_val, 634 const char* value2_name, int32 value2_val,
647 EventFlags flags) { 635 TraceEventFlags flags) {
648 return AddTraceEvent(TRACE_EVENT_PHASE_COUNTER, 636 return AddTraceEvent(TRACE_EVENT_PHASE_COUNTER,
649 category, 637 category,
650 name, 638 name,
639 0,
651 value1_name, value1_val, 640 value1_name, value1_val,
652 value2_name, value2_val, 641 value2_name, value2_val,
653 -1, 0, 642 -1, 0,
654 flags); 643 flags);
655 } 644 }
656 645
657 void TraceLog::AddCurrentMetadataEvents() { 646 void TraceLog::AddCurrentMetadataEvents() {
658 lock_.AssertAcquired(); 647 lock_.AssertAcquired();
659 for(base::hash_map<PlatformThreadId, std::string>::iterator it = 648 for(base::hash_map<int, std::string>::iterator it = thread_names_.begin();
660 thread_names_.begin();
661 it != thread_names_.end(); 649 it != thread_names_.end();
662 it++) { 650 it++) {
663 if (!it->second.empty()) 651 if (!it->second.empty())
664 logged_events_.push_back( 652 logged_events_.push_back(
665 TraceEvent(static_cast<unsigned long>(base::GetCurrentProcId()), 653 TraceEvent(it->first,
666 it->first, 654 TimeTicks(), TRACE_EVENT_PHASE_METADATA,
667 TimeTicks(), base::debug::TRACE_EVENT_PHASE_METADATA, 655 g_category_metadata, "thread_name", 0,
668 g_category_metadata, "thread_name",
669 "name", it->second, 656 "name", it->second,
670 NULL, 0, 657 NULL, 0,
671 false)); 658 TRACE_EVENT_FLAG_NONE));
672 } 659 }
673 } 660 }
674 661
675 void TraceLog::DeleteForTesting() { 662 void TraceLog::DeleteForTesting() {
676 DeleteTraceLogForTesting::Delete(); 663 DeleteTraceLogForTesting::Delete();
677 } 664 }
678 665
679 void TraceLog::Resurrect() { 666 void TraceLog::Resurrect() {
680 StaticMemorySingletonTraits<TraceLog>::Resurrect(); 667 StaticMemorySingletonTraits<TraceLog>::Resurrect();
681 } 668 }
682 669
670 void TraceLog::SetProcessID(int process_id) {
671 process_id_ = process_id;
672 // Create a FNV hash from the process ID for XORing.
673 // See http://isthe.com/chongo/tech/comp/fnv/ for algorithm details.
674 uint64 offset_basis = 14695981039346656037ull;
675 uint64 fnv_prime = 1099511628211ull;
676 unsigned long long pid = static_cast<unsigned long long>(process_id_);
677 process_id_hash_ = (offset_basis ^ pid) * fnv_prime;
678 }
679
683 namespace internal { 680 namespace internal {
684 681
685 void TraceEndOnScopeClose::Initialize(const TraceCategory* category, 682 void TraceEndOnScopeClose::Initialize(const TraceCategory* category,
686 const char* name) { 683 const char* name) {
687 data_.category = category; 684 data_.category = category;
688 data_.name = name; 685 data_.name = name;
689 p_data_ = &data_; 686 p_data_ = &data_;
690 } 687 }
691 688
692 void TraceEndOnScopeClose::AddEventIfEnabled() { 689 void TraceEndOnScopeClose::AddEventIfEnabled() {
693 // Only called when p_data_ is non-null. 690 // Only called when p_data_ is non-null.
694 if (p_data_->category->enabled) { 691 if (p_data_->category->enabled) {
695 base::debug::TraceLog::GetInstance()->AddTraceEvent( 692 base::debug::TraceLog::GetInstance()->AddTraceEvent(
696 base::debug::TRACE_EVENT_PHASE_END, 693 TRACE_EVENT_PHASE_END,
697 p_data_->category, 694 p_data_->category,
698 p_data_->name, 695 p_data_->name, kNoEventId,
699 NULL, 0, NULL, 0, 696 kNoArgName, kNoArgValue, kNoArgName, kNoArgValue,
700 -1, 0, TraceLog::EVENT_FLAG_NONE); 697 kNoThreshholdBeginId, kNoThresholdValue, TRACE_EVENT_FLAG_NONE);
701 } 698 }
702 } 699 }
703 700
704 void TraceEndOnScopeCloseThreshold::Initialize(const TraceCategory* category, 701 void TraceEndOnScopeCloseThreshold::Initialize(const TraceCategory* category,
705 const char* name, 702 const char* name,
706 int threshold_begin_id, 703 int threshold_begin_id,
707 int64 threshold) { 704 int64 threshold) {
708 data_.category = category; 705 data_.category = category;
709 data_.name = name; 706 data_.name = name;
710 data_.threshold_begin_id = threshold_begin_id; 707 data_.threshold_begin_id = threshold_begin_id;
711 data_.threshold = threshold; 708 data_.threshold = threshold;
712 p_data_ = &data_; 709 p_data_ = &data_;
713 } 710 }
714 711
715 void TraceEndOnScopeCloseThreshold::AddEventIfEnabled() { 712 void TraceEndOnScopeCloseThreshold::AddEventIfEnabled() {
716 // Only called when p_data_ is non-null. 713 // Only called when p_data_ is non-null.
717 if (p_data_->category->enabled) { 714 if (p_data_->category->enabled) {
718 base::debug::TraceLog::GetInstance()->AddTraceEvent( 715 base::debug::TraceLog::GetInstance()->AddTraceEvent(
719 base::debug::TRACE_EVENT_PHASE_END, 716 TRACE_EVENT_PHASE_END,
720 p_data_->category, 717 p_data_->category,
721 p_data_->name, 718 p_data_->name, kNoEventId,
722 NULL, 0, NULL, 0, 719 kNoArgName, kNoArgValue, kNoArgName, kNoArgValue,
723 p_data_->threshold_begin_id, p_data_->threshold, 720 p_data_->threshold_begin_id, p_data_->threshold,
724 TraceLog::EVENT_FLAG_NONE); 721 TRACE_EVENT_FLAG_NONE);
725 } 722 }
726 } 723 }
727 724
728 } // namespace internal 725 } // namespace internal
729 726
730 } // namespace debug 727 } // namespace debug
731 } // namespace base 728 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698