| Index: base/debug/trace_event.cc
|
| diff --git a/base/debug/trace_event.cc b/base/debug/trace_event.cc
|
| index d467055be9646f6aea8216eaf80f89a0b68a48e4..c983df9a4468e416f6a331aa634906db9d6fd0ca 100644
|
| --- a/base/debug/trace_event.cc
|
| +++ b/base/debug/trace_event.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "base/debug/trace_event.h"
|
|
|
| +#include <algorithm>
|
| +
|
| #if defined(OS_WIN)
|
| #include "base/debug/trace_event_win.h"
|
| #endif
|
| @@ -11,6 +13,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"
|
| @@ -30,13 +33,20 @@ const size_t kTraceEventBatchSize = 1000;
|
| static TraceCategory g_categories[TRACE_EVENT_MAX_CATEGORIES] = {
|
| { "tracing already shutdown", false },
|
| { "tracing categories exhausted; must increase TRACE_EVENT_MAX_CATEGORIES",
|
| + false },
|
| + { "__metadata",
|
| false }
|
| };
|
| static const TraceCategory* const g_category_already_shutdown =
|
| &g_categories[0];
|
| static const TraceCategory* const g_category_categories_exhausted =
|
| &g_categories[1];
|
| -static int g_category_index = 2; // skip initial 2 error categories
|
| +static const TraceCategory* const g_category_metadata =
|
| + &g_categories[2];
|
| +static int g_category_index = 3; // skip initial 3 categories
|
| +
|
| +// Flag to indicate whether we captured the current thread name
|
| +static ThreadLocalBoolean g_current_thread_name_captured;
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| //
|
| @@ -104,6 +114,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 +306,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 +377,33 @@ 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
|
| + // new name.
|
| + std::vector<std::string> existing_names;
|
| + Tokenize(existing_name->second, std::string(","), &existing_names);
|
| + bool found = std::find(existing_names.begin(),
|
| + existing_names.end(),
|
| + cur_name) != existing_names.end();
|
| + 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 +423,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 +462,24 @@ void TraceLog::AddTraceEventEtw(TraceEventPhase phase,
|
| }
|
| }
|
|
|
| +void TraceLog::AddCurrentMetadataEvents() {
|
| + lock_.AssertAcquired();
|
| + 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,
|
| + g_category_metadata, "thread_name",
|
| + "name", it->second.c_str(),
|
| + NULL, 0,
|
| + false));
|
| + }
|
| +}
|
| +
|
| void TraceLog::Resurrect() {
|
| StaticMemorySingletonTraits<TraceLog>::Resurrect();
|
| }
|
|
|