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

Unified Diff: base/debug/trace_event_impl.cc

Issue 12096115: Update tracing framework to optionally use a ringbuffer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: base/debug/trace_event_impl.cc
diff --git a/base/debug/trace_event_impl.cc b/base/debug/trace_event_impl.cc
index 69e9c600d0e96ae113fb902466212603a3104d1d..2bbfdc25f0babc047e394a1a2b19f79008f364fc 100644
--- a/base/debug/trace_event_impl.cc
+++ b/base/debug/trace_event_impl.cc
@@ -227,17 +227,6 @@ void TraceEvent::AppendValueAsJSON(unsigned char type,
}
}
-void TraceEvent::AppendEventsAsJSON(const std::vector<TraceEvent>& events,
- size_t start,
- size_t count,
- std::string* out) {
- for (size_t i = 0; i < count && start + i < events.size(); ++i) {
- if (i > 0)
- *out += ",";
- events[i + start].AppendAsJSON(out);
- }
-}
-
void TraceEvent::AppendAsJSON(std::string* out) const {
int64 time_int64 = timestamp_.ToInternalValue();
int process_id = TraceLog::GetInstance()->process_id();
@@ -349,6 +338,9 @@ TraceLog* TraceLog::GetInstance() {
TraceLog::TraceLog()
: enable_count_(0),
+ continuous_tracing_(false),
+ logged_events_newest_(0),
+ logged_events_oldest_(0),
dispatching_to_observer_list_(false),
watch_category_(NULL) {
// Trace is enabled or disabled on one thread while other threads are
@@ -604,24 +596,59 @@ void TraceLog::SetNotificationCallback(
void TraceLog::Flush(const TraceLog::OutputCallback& cb) {
std::vector<TraceEvent> previous_logged_events;
+ uint32 oldest_event;
+ uint32 newest_event;
{
AutoLock lock(lock_);
previous_logged_events.swap(logged_events_);
+
+ oldest_event = logged_events_oldest_;
+ newest_event = logged_events_newest_;
+
+ logged_events_oldest_ = logged_events_newest_ = 0;
} // release lock
- for (size_t i = 0;
- i < previous_logged_events.size();
- i += kTraceEventBatchSize) {
+ while (true) {
+ if (oldest_event == newest_event)
+ break;
+
scoped_refptr<RefCountedString> json_events_str_ptr =
new RefCountedString();
- TraceEvent::AppendEventsAsJSON(previous_logged_events,
- i,
- kTraceEventBatchSize,
- &(json_events_str_ptr->data()));
+
+ for (size_t i = 0; i < kTraceEventBatchSize; ++i) {
+ if (i > 0)
+ *(&(json_events_str_ptr->data())) += ",";
+
+ previous_logged_events[oldest_event].AppendAsJSON(
+ &(json_events_str_ptr->data()));
+
+ oldest_event++;
+ if (oldest_event >= kTraceEventBufferSize)
+ oldest_event = 0;
+ if (oldest_event == newest_event)
+ break;
+ }
+
cb.Run(json_events_str_ptr);
}
}
+void TraceLog::AddEvent(const TraceEvent& event) {
+ if (logged_events_newest_ < logged_events_.size())
+ logged_events_[logged_events_newest_] = event;
+ else
+ logged_events_.push_back(event);
+
+ logged_events_newest_++;
+ if (logged_events_newest_ >= kTraceEventBufferSize)
+ logged_events_newest_ = 0;
+ if (logged_events_newest_ == logged_events_oldest_) {
+ logged_events_oldest_++;
+ if (logged_events_oldest_ >= kTraceEventBufferSize)
+ logged_events_oldest_ = 0;
+ }
+}
+
void TraceLog::AddTraceEvent(char phase,
const unsigned char* category_enabled,
const char* name,
@@ -644,7 +671,8 @@ void TraceLog::AddTraceEvent(char phase,
AutoLock lock(lock_);
if (*category_enabled != CATEGORY_ENABLED)
return;
- if (logged_events_.size() >= kTraceEventBufferSize)
+ if (!continuous_tracing_ &&
+ logged_events_.size() >= kTraceEventBufferSize)
return;
int thread_id = static_cast<int>(PlatformThread::CurrentId());
@@ -680,13 +708,12 @@ void TraceLog::AddTraceEvent(char phase,
if (flags & TRACE_EVENT_FLAG_MANGLE_ID)
id ^= process_id_hash_;
- logged_events_.push_back(
- TraceEvent(thread_id,
- now, phase, category_enabled, name, id,
- num_args, arg_names, arg_types, arg_values,
- flags));
+ AddEvent(TraceEvent(thread_id,
+ now, phase, category_enabled, name, id,
+ num_args, arg_names, arg_types, arg_values,
+ flags));
- if (logged_events_.size() == kTraceEventBufferSize)
+ if (!continuous_tracing_ && logged_events_.size() == kTraceEventBufferSize)
notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL);
if (watch_category_ == category_enabled && watch_event_name_ == name)
@@ -730,11 +757,19 @@ void TraceLog::SetWatchEvent(const std::string& category_name,
// First, search existing events for watch event because we want to catch it
// even if it has already occurred.
- for (size_t i = 0u; i < logged_events_.size(); ++i) {
- if (category == logged_events_[i].category_enabled() &&
- strcmp(event_name.c_str(), logged_events_[i].name()) == 0) {
+ size_t idx = logged_events_oldest_;
+ while (true) {
+ if (idx == logged_events_newest_)
+ break;
+
+ if (category == logged_events_[idx].category_enabled() &&
+ strcmp(event_name.c_str(), logged_events_[idx].name()) == 0) {
++notify_count;
}
+
+ idx++;
+ if (idx >= kTraceEventBufferSize)
+ idx = 0;
}
} // release lock
@@ -765,13 +800,12 @@ void TraceLog::AddThreadNameMetadataEvents() {
unsigned char arg_type;
unsigned long long arg_value;
trace_event_internal::SetTraceValue(it->second, &arg_type, &arg_value);
- logged_events_.push_back(
- TraceEvent(it->first,
- TimeTicks(), TRACE_EVENT_PHASE_METADATA,
- &g_category_enabled[g_category_metadata],
- "thread_name", trace_event_internal::kNoEventId,
- num_args, &arg_name, &arg_type, &arg_value,
- TRACE_EVENT_FLAG_NONE));
+ AddEvent(TraceEvent(it->first,
+ TimeTicks(), TRACE_EVENT_PHASE_METADATA,
+ &g_category_enabled[g_category_metadata],
+ "thread_name", trace_event_internal::kNoEventId,
+ num_args, &arg_name, &arg_type, &arg_value,
+ TRACE_EVENT_FLAG_NONE));
}
}
}

Powered by Google App Engine
This is Rietveld 408576698