Chromium Code Reviews| Index: base/debug/trace_event.cc |
| diff --git a/base/debug/trace_event.cc b/base/debug/trace_event.cc |
| index d467055be9646f6aea8216eaf80f89a0b68a48e4..323a4b09d20c7b7dce38f7de76ca7a0fefb3d86f 100644 |
| --- a/base/debug/trace_event.cc |
| +++ b/base/debug/trace_event.cc |
| @@ -11,6 +11,7 @@ |
| #include "base/memory/ref_counted_memory.h" |
| #include "base/process_util.h" |
| #include "base/stringprintf.h" |
| +#include "base/threading/thread_local.h" |
| #include "base/utf_string_conversions.h" |
| #include "base/stl_util.h" |
| #include "base/time.h" |
| @@ -38,6 +39,9 @@ static const TraceCategory* const g_category_categories_exhausted = |
| &g_categories[1]; |
| static int g_category_index = 2; // skip initial 2 error categories |
| +// Flag to indicate whether we captured the current thread name |
| +static ThreadLocalBoolean g_current_thread_name_captured; |
| + |
| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // TraceValue |
| @@ -104,6 +108,8 @@ const char* GetPhaseStr(TraceEventPhase phase) { |
| return "I"; |
| case TRACE_EVENT_PHASE_END: |
| return "E"; |
| + case TRACE_EVENT_PHASE_METADATA: |
| + return "M"; |
| default: |
| NOTREACHED() << "Invalid phase argument"; |
| return "?"; |
| @@ -294,9 +300,13 @@ void TraceLog::SetEnabled(bool enabled) { |
| // check GetCategoryInternal creation code that users TraceLog::enabled_ |
| g_categories[i].enabled = enabled; |
| } |
| + |
| + if (!enabled) |
| + AddCurrentMetadataEvents(); |
| } // release lock |
| - if (!enabled) |
| + if (!enabled) { |
| Flush(); |
| + } |
| } |
| float TraceLog::GetBufferPercentFull() const { |
| @@ -361,6 +371,37 @@ int TraceLog::AddTraceEvent(TraceEventPhase phase, |
| return -1; |
| if (logged_events_.size() >= kTraceEventBufferSize) |
| return -1; |
| + |
| + PlatformThreadId thread_id = PlatformThread::CurrentId(); |
| + |
| + // Record the name of the calling thread, if not done already. |
| + if (!g_current_thread_name_captured.Get()) { |
| + const char* cur_name = PlatformThread::GetName(); |
| + base::hash_map<PlatformThreadId, std::string>::iterator existing_name = |
| + thread_names_.find(thread_id); |
| + if (existing_name == thread_names_.end()) { |
| + // This is a new thread id, and a new name. |
| + thread_names_[thread_id] = cur_name ? cur_name : ""; |
| + } else if(cur_name != NULL) { |
| + // This is a thread id that we've seen before, but potentially with a |
|
Sigurður Ásgeirsson
2011/08/04 20:07:05
so, you want to keep all names you've seen?
|
| + // new name. |
| + std::vector<std::string> existing_names; |
| + Tokenize(existing_name->second, std::string(","), &existing_names); |
| + bool found = false; |
| + for (size_t i = 0; i < existing_names.size(); ++i) { |
|
Sigurður Ásgeirsson
2011/08/04 20:07:05
nit: to the naked eye this looks equivalent to
bo
|
| + if(existing_names[i] == cur_name) { |
| + found = true; |
| + break; |
| + } |
| + } |
| + if (!found) { |
| + existing_names.push_back(cur_name); |
| + thread_names_[thread_id] = |
| + JoinString(existing_names, ','); |
| + } |
| + } |
| + } |
| + |
| if (threshold_begin_id > -1) { |
| DCHECK(phase == base::debug::TRACE_EVENT_PHASE_END); |
| size_t begin_i = static_cast<size_t>(threshold_begin_id); |
| @@ -380,7 +421,7 @@ int TraceLog::AddTraceEvent(TraceEventPhase phase, |
| ret_begin_id = static_cast<int>(logged_events_.size()); |
| logged_events_.push_back( |
| TraceEvent(static_cast<unsigned long>(base::GetCurrentProcId()), |
| - PlatformThread::CurrentId(), |
| + thread_id, |
| now, phase, category, name, |
| arg1_name, arg1_val, |
| arg2_name, arg2_val, |
| @@ -419,6 +460,26 @@ void TraceLog::AddTraceEventEtw(TraceEventPhase phase, |
| } |
| } |
| +void TraceLog::AddCurrentMetadataEvents() { |
| + lock_.AssertAcquired(); |
| + static const TraceCategory* metadata_category = |
| + GetCategoryInternal("__metadata"); |
| + for(base::hash_map<PlatformThreadId, std::string>::iterator it = |
| + thread_names_.begin(); |
| + it != thread_names_.end(); |
| + it++) { |
| + if (!it->second.empty()) |
| + logged_events_.push_back( |
| + TraceEvent(static_cast<unsigned long>(base::GetCurrentProcId()), |
| + it->first, |
| + TimeTicks(), base::debug::TRACE_EVENT_PHASE_METADATA, |
| + metadata_category, "thread_name", |
| + "name", it->second.c_str(), |
| + NULL, 0, |
| + false)); |
| + } |
| +} |
| + |
| void TraceLog::Resurrect() { |
| StaticMemorySingletonTraits<TraceLog>::Resurrect(); |
| } |