Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include "base/debug/trace_event_win.h" | 8 #include "base/debug/trace_event_win.h" |
| 9 #endif | 9 #endif |
| 10 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 97 namespace { | 97 namespace { |
| 98 | 98 |
| 99 const char* GetPhaseStr(TraceEventPhase phase) { | 99 const char* GetPhaseStr(TraceEventPhase phase) { |
| 100 switch(phase) { | 100 switch(phase) { |
| 101 case TRACE_EVENT_PHASE_BEGIN: | 101 case TRACE_EVENT_PHASE_BEGIN: |
| 102 return "B"; | 102 return "B"; |
| 103 case TRACE_EVENT_PHASE_INSTANT: | 103 case TRACE_EVENT_PHASE_INSTANT: |
| 104 return "I"; | 104 return "I"; |
| 105 case TRACE_EVENT_PHASE_END: | 105 case TRACE_EVENT_PHASE_END: |
| 106 return "E"; | 106 return "E"; |
| 107 case TRACE_EVENT_PHASE_METADATA: | |
| 108 return "M"; | |
| 107 default: | 109 default: |
| 108 NOTREACHED() << "Invalid phase argument"; | 110 NOTREACHED() << "Invalid phase argument"; |
| 109 return "?"; | 111 return "?"; |
| 110 } | 112 } |
| 111 } | 113 } |
| 112 | 114 |
| 113 size_t GetAllocLength(const char* str) { return str ? strlen(str) + 1 : 0; } | 115 size_t GetAllocLength(const char* str) { return str ? strlen(str) + 1 : 0; } |
| 114 | 116 |
| 115 // Copies |*member| into |*buffer|, sets |*member| to point to this new | 117 // Copies |*member| into |*buffer|, sets |*member| to point to this new |
| 116 // location, and then advances |*buffer| by the amount written. | 118 // location, and then advances |*buffer| by the amount written. |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 288 if (enabled == enabled_) | 290 if (enabled == enabled_) |
| 289 return; | 291 return; |
| 290 logged_events_.reserve(1024); | 292 logged_events_.reserve(1024); |
| 291 enabled_ = enabled; | 293 enabled_ = enabled; |
| 292 for (int i = 0; i < g_category_index; i++) { | 294 for (int i = 0; i < g_category_index; i++) { |
| 293 //TODO(scheib): If changed to enable specific categories instead of all | 295 //TODO(scheib): If changed to enable specific categories instead of all |
| 294 // check GetCategoryInternal creation code that users TraceLog::enabled_ | 296 // check GetCategoryInternal creation code that users TraceLog::enabled_ |
| 295 g_categories[i].enabled = enabled; | 297 g_categories[i].enabled = enabled; |
| 296 } | 298 } |
| 297 } // release lock | 299 } // release lock |
| 298 if (!enabled) | 300 if (!enabled) { |
| 301 AddCurrentMetadataEvents(); | |
| 299 Flush(); | 302 Flush(); |
| 303 } | |
| 300 } | 304 } |
| 301 | 305 |
| 302 float TraceLog::GetBufferPercentFull() const { | 306 float TraceLog::GetBufferPercentFull() const { |
| 303 return (float)((double)logged_events_.size()/(double)kTraceEventBufferSize); | 307 return (float)((double)logged_events_.size()/(double)kTraceEventBufferSize); |
| 304 } | 308 } |
| 305 | 309 |
| 306 void TraceLog::SetOutputCallback(const TraceLog::OutputCallback& cb) { | 310 void TraceLog::SetOutputCallback(const TraceLog::OutputCallback& cb) { |
| 307 AutoLock lock(lock_); | 311 AutoLock lock(lock_); |
| 308 output_callback_ = cb; | 312 output_callback_ = cb; |
| 309 logged_events_.clear(); | 313 logged_events_.clear(); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 354 TimeTicks now = TimeTicks::Now(); | 358 TimeTicks now = TimeTicks::Now(); |
| 355 #endif | 359 #endif |
| 356 BufferFullCallback buffer_full_callback_copy; | 360 BufferFullCallback buffer_full_callback_copy; |
| 357 int ret_begin_id = -1; | 361 int ret_begin_id = -1; |
| 358 { | 362 { |
| 359 AutoLock lock(lock_); | 363 AutoLock lock(lock_); |
| 360 if (!enabled_ || !category->enabled) | 364 if (!enabled_ || !category->enabled) |
| 361 return -1; | 365 return -1; |
| 362 if (logged_events_.size() >= kTraceEventBufferSize) | 366 if (logged_events_.size() >= kTraceEventBufferSize) |
| 363 return -1; | 367 return -1; |
| 368 PlatformThreadId thread_id = PlatformThread::CurrentId(); | |
| 369 if (thread_names_.find(thread_id) == thread_names_.end()) { | |
|
Sigurður Ásgeirsson
2011/08/04 12:31:39
On Windows, thread and process IDs are reused quit
nduca
2011/08/04 18:17:38
Thats an awesome idea.
| |
| 370 const char* name = PlatformThread::GetName(); | |
| 371 // Store something even for unnamed threads so we don't keep searching the | |
| 372 // thread_names_ map every time. | |
| 373 thread_names_[thread_id] = name ? name : ""; | |
| 374 } | |
| 375 | |
| 364 if (threshold_begin_id > -1) { | 376 if (threshold_begin_id > -1) { |
| 365 DCHECK(phase == base::debug::TRACE_EVENT_PHASE_END); | 377 DCHECK(phase == base::debug::TRACE_EVENT_PHASE_END); |
| 366 size_t begin_i = static_cast<size_t>(threshold_begin_id); | 378 size_t begin_i = static_cast<size_t>(threshold_begin_id); |
| 367 // Return now if there has been a flush since the begin event was posted. | 379 // Return now if there has been a flush since the begin event was posted. |
| 368 if (begin_i >= logged_events_.size()) | 380 if (begin_i >= logged_events_.size()) |
| 369 return -1; | 381 return -1; |
| 370 // Determine whether to drop the begin/end pair. | 382 // Determine whether to drop the begin/end pair. |
| 371 TimeDelta elapsed = now - logged_events_[begin_i].timestamp(); | 383 TimeDelta elapsed = now - logged_events_[begin_i].timestamp(); |
| 372 if (elapsed < TimeDelta::FromMicroseconds(threshold)) { | 384 if (elapsed < TimeDelta::FromMicroseconds(threshold)) { |
| 373 // Remove begin event and do not add end event. | 385 // Remove begin event and do not add end event. |
| 374 // This will be expensive if there have been other events in the | 386 // This will be expensive if there have been other events in the |
| 375 // mean time (should be rare). | 387 // mean time (should be rare). |
| 376 logged_events_.erase(logged_events_.begin() + begin_i); | 388 logged_events_.erase(logged_events_.begin() + begin_i); |
| 377 return -1; | 389 return -1; |
| 378 } | 390 } |
| 379 } | 391 } |
| 380 ret_begin_id = static_cast<int>(logged_events_.size()); | 392 ret_begin_id = static_cast<int>(logged_events_.size()); |
| 381 logged_events_.push_back( | 393 logged_events_.push_back( |
| 382 TraceEvent(static_cast<unsigned long>(base::GetCurrentProcId()), | 394 TraceEvent(static_cast<unsigned long>(base::GetCurrentProcId()), |
| 383 PlatformThread::CurrentId(), | 395 thread_id, |
| 384 now, phase, category, name, | 396 now, phase, category, name, |
| 385 arg1_name, arg1_val, | 397 arg1_name, arg1_val, |
| 386 arg2_name, arg2_val, | 398 arg2_name, arg2_val, |
| 387 copy)); | 399 copy)); |
| 388 | 400 |
| 389 if (logged_events_.size() == kTraceEventBufferSize) { | 401 if (logged_events_.size() == kTraceEventBufferSize) { |
| 390 buffer_full_callback_copy = buffer_full_callback_; | 402 buffer_full_callback_copy = buffer_full_callback_; |
| 391 } | 403 } |
| 392 } // release lock | 404 } // release lock |
| 393 | 405 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 412 TraceLog* tracelog = TraceLog::GetInstance(); | 424 TraceLog* tracelog = TraceLog::GetInstance(); |
| 413 if (!tracelog) | 425 if (!tracelog) |
| 414 return; | 426 return; |
| 415 tracelog->AddTraceEvent(phase, category, name, | 427 tracelog->AddTraceEvent(phase, category, name, |
| 416 "id", id, | 428 "id", id, |
| 417 "extra", extra ? extra : "", | 429 "extra", extra ? extra : "", |
| 418 -1, 0, false); | 430 -1, 0, false); |
| 419 } | 431 } |
| 420 } | 432 } |
| 421 | 433 |
| 434 void TraceLog::AddCurrentMetadataEvents() { | |
| 435 static const TraceCategory* metadata_category = | |
| 436 GetCategoryInternal("__metadata"); | |
| 437 for(base::hash_map<PlatformThreadId, std::string>::iterator it = | |
|
Sigurður Ásgeirsson
2011/08/04 12:31:39
lock_.AssertHeld().
However, I don't think you're
nduca
2011/08/04 18:17:38
Nice catch!
| |
| 438 thread_names_.begin(); | |
| 439 it != thread_names_.end(); | |
| 440 it++) { | |
| 441 if (!it->second.empty()) | |
| 442 logged_events_.push_back( | |
| 443 TraceEvent(static_cast<unsigned long>(base::GetCurrentProcId()), | |
| 444 it->first, | |
| 445 TimeTicks(), base::debug::TRACE_EVENT_PHASE_METADATA, | |
| 446 metadata_category, "thread_name", | |
| 447 "name", it->second.c_str(), | |
| 448 NULL, 0, | |
| 449 false)); | |
| 450 } | |
| 451 } | |
| 452 | |
| 422 void TraceLog::Resurrect() { | 453 void TraceLog::Resurrect() { |
| 423 StaticMemorySingletonTraits<TraceLog>::Resurrect(); | 454 StaticMemorySingletonTraits<TraceLog>::Resurrect(); |
| 424 } | 455 } |
| 425 | 456 |
| 426 namespace internal { | 457 namespace internal { |
| 427 | 458 |
| 428 void TraceEndOnScopeClose::Initialize(const TraceCategory* category, | 459 void TraceEndOnScopeClose::Initialize(const TraceCategory* category, |
| 429 const char* name) { | 460 const char* name) { |
| 430 data_.category = category; | 461 data_.category = category; |
| 431 data_.name = name; | 462 data_.name = name; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 464 p_data_->name, | 495 p_data_->name, |
| 465 NULL, 0, NULL, 0, | 496 NULL, 0, NULL, 0, |
| 466 p_data_->threshold_begin_id, p_data_->threshold, false); | 497 p_data_->threshold_begin_id, p_data_->threshold, false); |
| 467 } | 498 } |
| 468 } | 499 } |
| 469 | 500 |
| 470 } // namespace internal | 501 } // namespace internal |
| 471 | 502 |
| 472 } // namespace debug | 503 } // namespace debug |
| 473 } // namespace base | 504 } // namespace base |
| OLD | NEW |