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

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

Issue 7495031: trace_event support for thread names (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Tweaks to pass all trybots. Created 9 years, 4 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
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>
8
7 #if defined(OS_WIN) 9 #if defined(OS_WIN)
8 #include "base/debug/trace_event_win.h" 10 #include "base/debug/trace_event_win.h"
9 #endif 11 #endif
10 #include "base/format_macros.h" 12 #include "base/format_macros.h"
11 #include "base/memory/ref_counted_memory.h" 13 #include "base/memory/ref_counted_memory.h"
12 #include "base/process_util.h" 14 #include "base/process_util.h"
13 #include "base/stringprintf.h" 15 #include "base/stringprintf.h"
16 #include "base/threading/thread_local.h"
14 #include "base/utf_string_conversions.h" 17 #include "base/utf_string_conversions.h"
15 #include "base/stl_util.h" 18 #include "base/stl_util.h"
16 #include "base/time.h" 19 #include "base/time.h"
17 20
18 #define USE_UNRELIABLE_NOW 21 #define USE_UNRELIABLE_NOW
19 22
20 namespace base { 23 namespace base {
21 namespace debug { 24 namespace debug {
22 25
23 // Controls the number of trace events we will buffer in-memory 26 // Controls the number of trace events we will buffer in-memory
24 // before throwing them away. 27 // before throwing them away.
25 const size_t kTraceEventBufferSize = 500000; 28 const size_t kTraceEventBufferSize = 500000;
26 const size_t kTraceEventBatchSize = 1000; 29 const size_t kTraceEventBatchSize = 1000;
27 30
28 #define TRACE_EVENT_MAX_CATEGORIES 42 31 #define TRACE_EVENT_MAX_CATEGORIES 42
29 32
30 static TraceCategory g_categories[TRACE_EVENT_MAX_CATEGORIES] = { 33 static TraceCategory g_categories[TRACE_EVENT_MAX_CATEGORIES] = {
31 { "tracing already shutdown", false }, 34 { "tracing already shutdown", false },
32 { "tracing categories exhausted; must increase TRACE_EVENT_MAX_CATEGORIES", 35 { "tracing categories exhausted; must increase TRACE_EVENT_MAX_CATEGORIES",
36 false },
37 { "__metadata",
33 false } 38 false }
34 }; 39 };
35 static const TraceCategory* const g_category_already_shutdown = 40 static const TraceCategory* const g_category_already_shutdown =
36 &g_categories[0]; 41 &g_categories[0];
37 static const TraceCategory* const g_category_categories_exhausted = 42 static const TraceCategory* const g_category_categories_exhausted =
38 &g_categories[1]; 43 &g_categories[1];
39 static int g_category_index = 2; // skip initial 2 error categories 44 static const TraceCategory* const g_category_metadata =
45 &g_categories[2];
46 static int g_category_index = 3; // skip initial 3 categories
47
48 // Flag to indicate whether we captured the current thread name
49 static ThreadLocalBoolean g_current_thread_name_captured;
40 50
41 //////////////////////////////////////////////////////////////////////////////// 51 ////////////////////////////////////////////////////////////////////////////////
42 // 52 //
43 // TraceValue 53 // TraceValue
44 // 54 //
45 //////////////////////////////////////////////////////////////////////////////// 55 ////////////////////////////////////////////////////////////////////////////////
46 56
47 void TraceValue::AppendAsJSON(std::string* out) const { 57 void TraceValue::AppendAsJSON(std::string* out) const {
48 char temp_string[128]; 58 char temp_string[128];
49 std::string::size_type start_pos; 59 std::string::size_type start_pos;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 namespace { 107 namespace {
98 108
99 const char* GetPhaseStr(TraceEventPhase phase) { 109 const char* GetPhaseStr(TraceEventPhase phase) {
100 switch(phase) { 110 switch(phase) {
101 case TRACE_EVENT_PHASE_BEGIN: 111 case TRACE_EVENT_PHASE_BEGIN:
102 return "B"; 112 return "B";
103 case TRACE_EVENT_PHASE_INSTANT: 113 case TRACE_EVENT_PHASE_INSTANT:
104 return "I"; 114 return "I";
105 case TRACE_EVENT_PHASE_END: 115 case TRACE_EVENT_PHASE_END:
106 return "E"; 116 return "E";
117 case TRACE_EVENT_PHASE_METADATA:
118 return "M";
107 default: 119 default:
108 NOTREACHED() << "Invalid phase argument"; 120 NOTREACHED() << "Invalid phase argument";
109 return "?"; 121 return "?";
110 } 122 }
111 } 123 }
112 124
113 size_t GetAllocLength(const char* str) { return str ? strlen(str) + 1 : 0; } 125 size_t GetAllocLength(const char* str) { return str ? strlen(str) + 1 : 0; }
114 126
115 // Copies |*member| into |*buffer|, sets |*member| to point to this new 127 // Copies |*member| into |*buffer|, sets |*member| to point to this new
116 // location, and then advances |*buffer| by the amount written. 128 // location, and then advances |*buffer| by the amount written.
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 AutoLock lock(lock_); 299 AutoLock lock(lock_);
288 if (enabled == enabled_) 300 if (enabled == enabled_)
289 return; 301 return;
290 logged_events_.reserve(1024); 302 logged_events_.reserve(1024);
291 enabled_ = enabled; 303 enabled_ = enabled;
292 for (int i = 0; i < g_category_index; i++) { 304 for (int i = 0; i < g_category_index; i++) {
293 //TODO(scheib): If changed to enable specific categories instead of all 305 //TODO(scheib): If changed to enable specific categories instead of all
294 // check GetCategoryInternal creation code that users TraceLog::enabled_ 306 // check GetCategoryInternal creation code that users TraceLog::enabled_
295 g_categories[i].enabled = enabled; 307 g_categories[i].enabled = enabled;
296 } 308 }
309
310 if (!enabled)
311 AddCurrentMetadataEvents();
297 } // release lock 312 } // release lock
298 if (!enabled) 313 if (!enabled) {
299 Flush(); 314 Flush();
315 }
300 } 316 }
301 317
302 float TraceLog::GetBufferPercentFull() const { 318 float TraceLog::GetBufferPercentFull() const {
303 return (float)((double)logged_events_.size()/(double)kTraceEventBufferSize); 319 return (float)((double)logged_events_.size()/(double)kTraceEventBufferSize);
304 } 320 }
305 321
306 void TraceLog::SetOutputCallback(const TraceLog::OutputCallback& cb) { 322 void TraceLog::SetOutputCallback(const TraceLog::OutputCallback& cb) {
307 AutoLock lock(lock_); 323 AutoLock lock(lock_);
308 output_callback_ = cb; 324 output_callback_ = cb;
309 logged_events_.clear(); 325 logged_events_.clear();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 TimeTicks now = TimeTicks::Now(); 370 TimeTicks now = TimeTicks::Now();
355 #endif 371 #endif
356 BufferFullCallback buffer_full_callback_copy; 372 BufferFullCallback buffer_full_callback_copy;
357 int ret_begin_id = -1; 373 int ret_begin_id = -1;
358 { 374 {
359 AutoLock lock(lock_); 375 AutoLock lock(lock_);
360 if (!enabled_ || !category->enabled) 376 if (!enabled_ || !category->enabled)
361 return -1; 377 return -1;
362 if (logged_events_.size() >= kTraceEventBufferSize) 378 if (logged_events_.size() >= kTraceEventBufferSize)
363 return -1; 379 return -1;
380
381 PlatformThreadId thread_id = PlatformThread::CurrentId();
382
383 // Record the name of the calling thread, if not done already.
384 if (!g_current_thread_name_captured.Get()) {
385 const char* cur_name = PlatformThread::GetName();
386 base::hash_map<PlatformThreadId, std::string>::iterator existing_name =
387 thread_names_.find(thread_id);
388 if (existing_name == thread_names_.end()) {
389 // This is a new thread id, and a new name.
390 thread_names_[thread_id] = cur_name ? cur_name : "";
391 } else if(cur_name != NULL) {
392 // This is a thread id that we've seen before, but potentially with a
393 // new name.
394 std::vector<std::string> existing_names;
395 Tokenize(existing_name->second, std::string(","), &existing_names);
396 bool found = std::find(existing_names.begin(),
397 existing_names.end(),
398 cur_name) != existing_names.end();
399 if (!found) {
400 existing_names.push_back(cur_name);
401 thread_names_[thread_id] =
402 JoinString(existing_names, ',');
403 }
404 }
405 }
406
364 if (threshold_begin_id > -1) { 407 if (threshold_begin_id > -1) {
365 DCHECK(phase == base::debug::TRACE_EVENT_PHASE_END); 408 DCHECK(phase == base::debug::TRACE_EVENT_PHASE_END);
366 size_t begin_i = static_cast<size_t>(threshold_begin_id); 409 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. 410 // Return now if there has been a flush since the begin event was posted.
368 if (begin_i >= logged_events_.size()) 411 if (begin_i >= logged_events_.size())
369 return -1; 412 return -1;
370 // Determine whether to drop the begin/end pair. 413 // Determine whether to drop the begin/end pair.
371 TimeDelta elapsed = now - logged_events_[begin_i].timestamp(); 414 TimeDelta elapsed = now - logged_events_[begin_i].timestamp();
372 if (elapsed < TimeDelta::FromMicroseconds(threshold)) { 415 if (elapsed < TimeDelta::FromMicroseconds(threshold)) {
373 // Remove begin event and do not add end event. 416 // Remove begin event and do not add end event.
374 // This will be expensive if there have been other events in the 417 // This will be expensive if there have been other events in the
375 // mean time (should be rare). 418 // mean time (should be rare).
376 logged_events_.erase(logged_events_.begin() + begin_i); 419 logged_events_.erase(logged_events_.begin() + begin_i);
377 return -1; 420 return -1;
378 } 421 }
379 } 422 }
380 ret_begin_id = static_cast<int>(logged_events_.size()); 423 ret_begin_id = static_cast<int>(logged_events_.size());
381 logged_events_.push_back( 424 logged_events_.push_back(
382 TraceEvent(static_cast<unsigned long>(base::GetCurrentProcId()), 425 TraceEvent(static_cast<unsigned long>(base::GetCurrentProcId()),
383 PlatformThread::CurrentId(), 426 thread_id,
384 now, phase, category, name, 427 now, phase, category, name,
385 arg1_name, arg1_val, 428 arg1_name, arg1_val,
386 arg2_name, arg2_val, 429 arg2_name, arg2_val,
387 copy)); 430 copy));
388 431
389 if (logged_events_.size() == kTraceEventBufferSize) { 432 if (logged_events_.size() == kTraceEventBufferSize) {
390 buffer_full_callback_copy = buffer_full_callback_; 433 buffer_full_callback_copy = buffer_full_callback_;
391 } 434 }
392 } // release lock 435 } // release lock
393 436
(...skipping 18 matching lines...) Expand all
412 TraceLog* tracelog = TraceLog::GetInstance(); 455 TraceLog* tracelog = TraceLog::GetInstance();
413 if (!tracelog) 456 if (!tracelog)
414 return; 457 return;
415 tracelog->AddTraceEvent(phase, category, name, 458 tracelog->AddTraceEvent(phase, category, name,
416 "id", id, 459 "id", id,
417 "extra", extra ? extra : "", 460 "extra", extra ? extra : "",
418 -1, 0, false); 461 -1, 0, false);
419 } 462 }
420 } 463 }
421 464
465 void TraceLog::AddCurrentMetadataEvents() {
466 lock_.AssertAcquired();
467 for(base::hash_map<PlatformThreadId, std::string>::iterator it =
468 thread_names_.begin();
469 it != thread_names_.end();
470 it++) {
471 if (!it->second.empty())
472 logged_events_.push_back(
473 TraceEvent(static_cast<unsigned long>(base::GetCurrentProcId()),
474 it->first,
475 TimeTicks(), base::debug::TRACE_EVENT_PHASE_METADATA,
476 g_category_metadata, "thread_name",
477 "name", it->second.c_str(),
478 NULL, 0,
479 false));
480 }
481 }
482
422 void TraceLog::Resurrect() { 483 void TraceLog::Resurrect() {
423 StaticMemorySingletonTraits<TraceLog>::Resurrect(); 484 StaticMemorySingletonTraits<TraceLog>::Resurrect();
424 } 485 }
425 486
426 namespace internal { 487 namespace internal {
427 488
428 void TraceEndOnScopeClose::Initialize(const TraceCategory* category, 489 void TraceEndOnScopeClose::Initialize(const TraceCategory* category,
429 const char* name) { 490 const char* name) {
430 data_.category = category; 491 data_.category = category;
431 data_.name = name; 492 data_.name = name;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 p_data_->name, 525 p_data_->name,
465 NULL, 0, NULL, 0, 526 NULL, 0, NULL, 0,
466 p_data_->threshold_begin_id, p_data_->threshold, false); 527 p_data_->threshold_begin_id, p_data_->threshold, false);
467 } 528 }
468 } 529 }
469 530
470 } // namespace internal 531 } // namespace internal
471 532
472 } // namespace debug 533 } // namespace debug
473 } // namespace base 534 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698