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