| Index: base/debug/trace_event_impl.cc
|
| diff --git a/base/debug/trace_event_impl.cc b/base/debug/trace_event_impl.cc
|
| index 823acbe17726396b25168599476f1c85f5760e88..11f5d74929013cfdb2df26986358715c85431180 100644
|
| --- a/base/debug/trace_event_impl.cc
|
| +++ b/base/debug/trace_event_impl.cc
|
| @@ -609,6 +609,33 @@ void TraceLog::Flush(const TraceLog::OutputCallback& cb) {
|
| }
|
| }
|
|
|
| +int TraceLog::AddTraceEventExplicit(char phase,
|
| + const unsigned char* category_enabled,
|
| + const char* name,
|
| + int64 timestamp,
|
| + unsigned long long id,
|
| + int num_args,
|
| + const char** arg_names,
|
| + const unsigned char* arg_types,
|
| + const unsigned long long* arg_values,
|
| + int threshold_begin_id,
|
| + long long threshold,
|
| + unsigned char flags) {
|
| + DCHECK(name);
|
| + TimeTicks now = TimeTicks::FromInternalValue(timestamp);
|
| + NotificationHelper notifier(this);
|
| +
|
| + int ret_begin_id = AddTraceEventInternal(notifier, now, phase,
|
| + category_enabled, name,
|
| + id, num_args, arg_names, arg_types,
|
| + arg_values, threshold_begin_id,
|
| + threshold, flags);
|
| +
|
| + notifier.SendNotificationIfAny();
|
| +
|
| + return ret_begin_id;
|
| +}
|
| +
|
| int TraceLog::AddTraceEvent(char phase,
|
| const unsigned char* category_enabled,
|
| const char* name,
|
| @@ -629,79 +656,98 @@ int TraceLog::AddTraceEvent(char phase,
|
|
|
| TimeTicks now = TimeTicks::NowFromSystemTraceTime();
|
| NotificationHelper notifier(this);
|
| - int ret_begin_id = -1;
|
| - {
|
| - AutoLock lock(lock_);
|
| - if (*category_enabled != CATEGORY_ENABLED)
|
| - return -1;
|
| - if (logged_events_.size() >= kTraceEventBufferSize)
|
| - return -1;
|
|
|
| - int thread_id = static_cast<int>(PlatformThread::CurrentId());
|
| -
|
| - const char* new_name = PlatformThread::GetName();
|
| - // Check if the thread name has been set or changed since the previous
|
| - // call (if any), but don't bother if the new name is empty. Note this will
|
| - // not detect a thread name change within the same char* buffer address: we
|
| - // favor common case performance over corner case correctness.
|
| - if (new_name != g_current_thread_name.Get().Get() &&
|
| - new_name && *new_name) {
|
| - g_current_thread_name.Get().Set(new_name);
|
| - base::hash_map<int, 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] = new_name;
|
| - } else {
|
| - // This is a thread id that we've seen before, but potentially with a
|
| - // new name.
|
| - std::vector<base::StringPiece> existing_names;
|
| - Tokenize(existing_name->second, ",", &existing_names);
|
| - bool found = std::find(existing_names.begin(),
|
| - existing_names.end(),
|
| - new_name) != existing_names.end();
|
| - if (!found) {
|
| - existing_name->second.push_back(',');
|
| - existing_name->second.append(new_name);
|
| - }
|
| - }
|
| - }
|
| + int ret_begin_id = AddTraceEventInternal(notifier, now, phase,
|
| + category_enabled, name,
|
| + id, num_args, arg_names, arg_types,
|
| + arg_values, threshold_begin_id,
|
| + threshold, flags);
|
| +
|
| + notifier.SendNotificationIfAny();
|
| +
|
| + return ret_begin_id;
|
| +}
|
|
|
| - if (threshold_begin_id > -1) {
|
| - DCHECK(phase == TRACE_EVENT_PHASE_END);
|
| - size_t begin_i = static_cast<size_t>(threshold_begin_id);
|
| - // Return now if there has been a flush since the begin event was posted.
|
| - if (begin_i >= logged_events_.size())
|
| - return -1;
|
| - // Determine whether to drop the begin/end pair.
|
| - TimeDelta elapsed = now - logged_events_[begin_i].timestamp();
|
| - if (elapsed < TimeDelta::FromMicroseconds(threshold)) {
|
| - // Remove begin event and do not add end event.
|
| - // This will be expensive if there have been other events in the
|
| - // mean time (should be rare).
|
| - logged_events_.erase(logged_events_.begin() + begin_i);
|
| - return -1;
|
| +int TraceLog::AddTraceEventInternal(NotificationHelper& notifier,
|
| + TimeTicks timestamp,
|
| + char phase,
|
| + const unsigned char* category_enabled,
|
| + const char* name,
|
| + unsigned long long id,
|
| + int num_args,
|
| + const char** arg_names,
|
| + const unsigned char* arg_types,
|
| + const unsigned long long* arg_values,
|
| + int threshold_begin_id,
|
| + long long threshold,
|
| + unsigned char flags) {
|
| + AutoLock lock(lock_);
|
| + if (*category_enabled != CATEGORY_ENABLED)
|
| + return -1;
|
| + if (logged_events_.size() >= kTraceEventBufferSize)
|
| + return -1;
|
| +
|
| + int thread_id = static_cast<int>(PlatformThread::CurrentId());
|
| + const char* new_name = PlatformThread::GetName();
|
| + // Check if the thread name has been set or changed since the previous
|
| + // call (if any), but don't bother if the new name is empty. Note this will
|
| + // not detect a thread name change within the same char* buffer address: we
|
| + // favor common case performance over corner case correctness.
|
| + if (new_name != g_current_thread_name.Get().Get() &&
|
| + new_name && *new_name) {
|
| + g_current_thread_name.Get().Set(new_name);
|
| + base::hash_map<int, 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] = new_name;
|
| + } else {
|
| + // This is a thread id that we've seen before, but potentially with a
|
| + // new name.
|
| + std::vector<base::StringPiece> existing_names;
|
| + Tokenize(existing_name->second, ",", &existing_names);
|
| + bool found = std::find(existing_names.begin(),
|
| + existing_names.end(),
|
| + new_name) != existing_names.end();
|
| + if (!found) {
|
| + existing_name->second.push_back(',');
|
| + existing_name->second.append(new_name);
|
| }
|
| }
|
| + }
|
|
|
| - if (flags & TRACE_EVENT_FLAG_MANGLE_ID)
|
| - id ^= process_id_hash_;
|
| + if (threshold_begin_id > -1) {
|
| + DCHECK(phase == TRACE_EVENT_PHASE_END);
|
| + size_t begin_i = static_cast<size_t>(threshold_begin_id);
|
| + // Return now if there has been a flush since the begin event was posted.
|
| + if (begin_i >= logged_events_.size())
|
| + return -1;
|
| + // Determine whether to drop the begin/end pair.
|
| + TimeDelta elapsed = timestamp - logged_events_[begin_i].timestamp();
|
| + if (elapsed < TimeDelta::FromMicroseconds(threshold)) {
|
| + // Remove begin event and do not add end event.
|
| + // This will be expensive if there have been other events in the
|
| + // mean time (should be rare).
|
| + logged_events_.erase(logged_events_.begin() + begin_i);
|
| + return -1;
|
| + }
|
| + }
|
|
|
| - ret_begin_id = static_cast<int>(logged_events_.size());
|
| - logged_events_.push_back(
|
| - TraceEvent(thread_id,
|
| - now, phase, category_enabled, name, id,
|
| - num_args, arg_names, arg_types, arg_values,
|
| - flags));
|
| + if (flags & TRACE_EVENT_FLAG_MANGLE_ID)
|
| + id ^= process_id_hash_;
|
|
|
| - if (logged_events_.size() == kTraceEventBufferSize)
|
| - notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL);
|
| + int ret_begin_id = static_cast<int>(logged_events_.size());
|
| + logged_events_.push_back(
|
| + TraceEvent(thread_id,
|
| + timestamp, phase, category_enabled, name, id,
|
| + num_args, arg_names, arg_types, arg_values,
|
| + flags));
|
|
|
| - if (watch_category_ == category_enabled && watch_event_name_ == name)
|
| - notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION);
|
| - } // release lock
|
| + if (logged_events_.size() == kTraceEventBufferSize)
|
| + notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL);
|
|
|
| - notifier.SendNotificationIfAny();
|
| + if (watch_category_ == category_enabled && watch_event_name_ == name)
|
| + notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION);
|
|
|
| return ret_begin_id;
|
| }
|
|
|