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