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(); |
} |