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

Unified Diff: trunk/src/base/debug/trace_event_impl.cc

Issue 89753004: Revert 237280 "Remove TraceController" (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 years, 1 month 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
« no previous file with comments | « trunk/src/base/debug/trace_event_impl.h ('k') | trunk/src/base/debug/trace_event_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: trunk/src/base/debug/trace_event_impl.cc
===================================================================
--- trunk/src/base/debug/trace_event_impl.cc (revision 237451)
+++ trunk/src/base/debug/trace_event_impl.cc (working copy)
@@ -99,6 +99,11 @@
LazyInstance<ThreadLocalPointer<const char> >::Leaky
g_current_thread_name = LAZY_INSTANCE_INITIALIZER;
+const char kRecordUntilFull[] = "record-until-full";
+const char kRecordContinuously[] = "record-continuously";
+const char kEnableSampling[] = "enable-sampling";
+const char kMonitorSampling[] = "monitor-sampling";
+
TimeTicks ThreadNow() {
return TimeTicks::IsThreadNowSupported() ?
TimeTicks::ThreadNow() : TimeTicks();
@@ -939,10 +944,12 @@
ThreadLocalEventBuffer(TraceLog* trace_log);
virtual ~ThreadLocalEventBuffer();
- TraceEvent* AddTraceEvent(TraceEventHandle* handle);
+ TraceEvent* AddTraceEvent(NotificationHelper* notifier,
+ TraceEventHandle* handle);
void ReportOverhead(const TimeTicks& event_timestamp,
- const TimeTicks& event_thread_timestamp);
+ const TimeTicks& event_thread_timestamp,
+ NotificationHelper* notifier);
TraceEvent* GetEventByHandle(TraceEventHandle handle) {
if (!chunk_ || handle.chunk_seq != chunk_->seq() ||
@@ -999,10 +1006,12 @@
// - the thread has no message loop;
// - trace_event_overhead is disabled.
if (event_count_) {
- InitializeMetadataEvent(AddTraceEvent(NULL),
+ NotificationHelper notifier(trace_log_);
+ InitializeMetadataEvent(AddTraceEvent(&notifier, NULL),
static_cast<int>(base::PlatformThread::CurrentId()),
"overhead", "average_overhead",
overhead_.InMillisecondsF() / event_count_);
+ notifier.SendNotificationIfAny();
}
{
@@ -1014,6 +1023,7 @@
}
TraceEvent* TraceLog::ThreadLocalEventBuffer::AddTraceEvent(
+ NotificationHelper* notifier,
TraceEventHandle* handle) {
CheckThisIsCurrentBuffer();
@@ -1025,7 +1035,7 @@
if (!chunk_) {
AutoLock lock(trace_log_->lock_);
chunk_ = trace_log_->logged_events_->GetChunk(&chunk_index_);
- trace_log_->CheckIfBufferIsFullWhileLocked();
+ trace_log_->CheckIfBufferIsFullWhileLocked(notifier);
}
if (!chunk_)
return NULL;
@@ -1040,7 +1050,8 @@
void TraceLog::ThreadLocalEventBuffer::ReportOverhead(
const TimeTicks& event_timestamp,
- const TimeTicks& event_thread_timestamp) {
+ const TimeTicks& event_thread_timestamp,
+ NotificationHelper* notifier) {
if (!g_category_group_enabled[g_category_trace_event_overhead])
return;
@@ -1050,7 +1061,7 @@
TimeTicks now = trace_log_->OffsetNow();
TimeDelta overhead = now - event_timestamp;
if (overhead.InMicroseconds() >= kOverheadReportThresholdInMicroseconds) {
- TraceEvent* trace_event = AddTraceEvent(NULL);
+ TraceEvent* trace_event = AddTraceEvent(notifier, NULL);
if (trace_event) {
trace_event->Initialize(
static_cast<int>(PlatformThread::CurrentId()),
@@ -1081,14 +1092,66 @@
// find the generation mismatch and delete this buffer soon.
}
+TraceLog::NotificationHelper::NotificationHelper(TraceLog* trace_log)
+ : trace_log_(trace_log),
+ notification_(0) {
+}
+
+TraceLog::NotificationHelper::~NotificationHelper() {
+}
+
+void TraceLog::NotificationHelper::AddNotificationWhileLocked(
+ int notification) {
+ trace_log_->lock_.AssertAcquired();
+ if (trace_log_->notification_callback_.is_null())
+ return;
+ if (notification_ == 0)
+ callback_copy_ = trace_log_->notification_callback_;
+ notification_ |= notification;
+}
+
+void TraceLog::NotificationHelper::SendNotificationIfAny() {
+ if (notification_)
+ callback_copy_.Run(notification_);
+}
+
// static
TraceLog* TraceLog::GetInstance() {
return Singleton<TraceLog, LeakySingletonTraits<TraceLog> >::get();
}
+// static
+// Note, if you add more options here you also need to update:
+// content/browser/devtools/devtools_tracing_handler:TraceOptionsFromString
+TraceLog::Options TraceLog::TraceOptionsFromString(const std::string& options) {
+ std::vector<std::string> split;
+ base::SplitString(options, ',', &split);
+ int ret = 0;
+ for (std::vector<std::string>::iterator iter = split.begin();
+ iter != split.end();
+ ++iter) {
+ if (*iter == kRecordUntilFull) {
+ ret |= RECORD_UNTIL_FULL;
+ } else if (*iter == kRecordContinuously) {
+ ret |= RECORD_CONTINUOUSLY;
+ } else if (*iter == kEnableSampling) {
+ ret |= ENABLE_SAMPLING;
+ } else if (*iter == kMonitorSampling) {
+ ret |= MONITOR_SAMPLING;
+ } else {
+ NOTREACHED(); // Unknown option provided.
+ }
+ }
+ if (!(ret & RECORD_UNTIL_FULL) && !(ret & RECORD_CONTINUOUSLY))
+ ret |= RECORD_UNTIL_FULL; // Default when no options are specified.
+
+ return static_cast<Options>(ret);
+}
+
TraceLog::TraceLog()
: enabled_(false),
num_traces_recorded_(0),
+ buffer_is_full_(0),
event_callback_(0),
dispatching_to_observer_list_(false),
process_sort_index_(0),
@@ -1265,6 +1328,7 @@
subtle::NoBarrier_Store(&trace_options_, options);
logged_events_.reset(CreateTraceBuffer());
NextGeneration();
+ subtle::NoBarrier_Store(&buffer_is_full_, 0);
}
num_traces_recorded_++;
@@ -1311,52 +1375,49 @@
}
void TraceLog::SetDisabled() {
- AutoLock lock(lock_);
- SetDisabledWhileLocked();
-}
+ std::vector<EnabledStateObserver*> observer_list;
+ {
+ AutoLock lock(lock_);
+ if (!enabled_)
+ return;
-void TraceLog::SetDisabledWhileLocked() {
- lock_.AssertAcquired();
+ if (dispatching_to_observer_list_) {
+ DLOG(ERROR)
+ << "Cannot manipulate TraceLog::Enabled state from an observer.";
+ return;
+ }
- if (!enabled_)
- return;
+ enabled_ = false;
- if (dispatching_to_observer_list_) {
- DLOG(ERROR)
- << "Cannot manipulate TraceLog::Enabled state from an observer.";
- return;
- }
+ if (sampling_thread_.get()) {
+ // Stop the sampling thread.
+ sampling_thread_->Stop();
+ lock_.Release();
+ PlatformThread::Join(sampling_thread_handle_);
+ lock_.Acquire();
+ sampling_thread_handle_ = PlatformThreadHandle();
+ sampling_thread_.reset();
+ }
- enabled_ = false;
+ category_filter_.Clear();
+ subtle::NoBarrier_Store(&watch_category_, 0);
+ watch_event_name_ = "";
+ UpdateCategoryGroupEnabledFlags();
+ AddMetadataEventsWhileLocked();
- if (sampling_thread_.get()) {
- // Stop the sampling thread.
- sampling_thread_->Stop();
- lock_.Release();
- PlatformThread::Join(sampling_thread_handle_);
- lock_.Acquire();
- sampling_thread_handle_ = PlatformThreadHandle();
- sampling_thread_.reset();
+ dispatching_to_observer_list_ = true;
+ observer_list = enabled_state_observer_list_;
}
- category_filter_.Clear();
- subtle::NoBarrier_Store(&watch_category_, 0);
- watch_event_name_ = "";
- UpdateCategoryGroupEnabledFlags();
- AddMetadataEventsWhileLocked();
+ // Dispatch to observers outside the lock in case the observer triggers a
+ // trace event.
+ for (size_t i = 0; i < observer_list.size(); ++i)
+ observer_list[i]->OnTraceLogDisabled();
- dispatching_to_observer_list_ = true;
- std::vector<EnabledStateObserver*> observer_list =
- enabled_state_observer_list_;
-
{
- // Dispatch to observers outside the lock in case the observer triggers a
- // trace event.
- AutoUnlock unlock(lock_);
- for (size_t i = 0; i < observer_list.size(); ++i)
- observer_list[i]->OnTraceLogDisabled();
+ AutoLock lock(lock_);
+ dispatching_to_observer_list_ = false;
}
- dispatching_to_observer_list_ = false;
}
int TraceLog::GetNumTracesRecorded() {
@@ -1388,14 +1449,14 @@
}
float TraceLog::GetBufferPercentFull() const {
- AutoLock lock(lock_);
return static_cast<float>(static_cast<double>(logged_events_->Size()) /
logged_events_->Capacity());
}
-bool TraceLog::BufferIsFull() const {
+void TraceLog::SetNotificationCallback(
+ const TraceLog::NotificationCallback& cb) {
AutoLock lock(lock_);
- return logged_events_->IsFull();
+ notification_callback_ = cb;
}
TraceBuffer* TraceLog::CreateTraceBuffer() {
@@ -1410,7 +1471,7 @@
}
TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked(
- TraceEventHandle* handle, bool check_buffer_is_full) {
+ NotificationHelper* notifier, TraceEventHandle* handle) {
lock_.AssertAcquired();
if (thread_shared_chunk_ && thread_shared_chunk_->IsFull()) {
@@ -1421,8 +1482,8 @@
if (!thread_shared_chunk_) {
thread_shared_chunk_ = logged_events_->GetChunk(
&thread_shared_chunk_index_);
- if (check_buffer_is_full)
- CheckIfBufferIsFullWhileLocked();
+ if (notifier)
+ CheckIfBufferIsFullWhileLocked(notifier);
}
if (!thread_shared_chunk_)
return NULL;
@@ -1436,10 +1497,13 @@
return trace_event;
}
-void TraceLog::CheckIfBufferIsFullWhileLocked() {
+void TraceLog::CheckIfBufferIsFullWhileLocked(NotificationHelper* notifier) {
lock_.AssertAcquired();
- if (logged_events_->IsFull())
- SetDisabledWhileLocked();
+ if (!subtle::NoBarrier_Load(&buffer_is_full_) && logged_events_->IsFull()) {
+ subtle::NoBarrier_Store(&buffer_is_full_,
+ static_cast<subtle::AtomicWord>(1));
+ notifier->AddNotificationWhileLocked(TRACE_BUFFER_FULL);
+ }
}
void TraceLog::SetEventCallbackEnabled(const CategoryFilter& category_filter,
@@ -1556,6 +1620,7 @@
previous_logged_events.swap(logged_events_);
logged_events_.reset(CreateTraceBuffer());
NextGeneration();
+ subtle::NoBarrier_Store(&buffer_is_full_, 0);
thread_message_loops_.clear();
flush_message_loop_proxy_ = NULL;
@@ -1675,6 +1740,8 @@
TimeTicks now = OffsetTimestamp(timestamp);
TimeTicks thread_now = ThreadNow();
+ NotificationHelper notifier(this);
+
ThreadLocalEventBuffer* thread_local_event_buffer = NULL;
// A ThreadLocalEventBuffer needs the message loop
// - to know when the thread exits;
@@ -1731,13 +1798,15 @@
}
TraceEvent* trace_event = NULL;
- if ((*category_group_enabled & ENABLED_FOR_RECORDING)) {
+ if ((*category_group_enabled & ENABLED_FOR_RECORDING) &&
+ !subtle::NoBarrier_Load(&buffer_is_full_)) {
if (thread_local_event_buffer) {
lock.EnsureReleased();
- trace_event = thread_local_event_buffer->AddTraceEvent(&handle);
+ trace_event = thread_local_event_buffer->AddTraceEvent(&notifier,
+ &handle);
} else {
lock.EnsureAcquired();
- trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true);
+ trace_event = AddEventToThreadSharedChunkWhileLocked(&notifier, &handle);
}
if (trace_event) {
@@ -1750,24 +1819,20 @@
trace_event->SendToATrace();
#endif
}
+ }
- if (trace_options() & ECHO_TO_CONSOLE) {
- lock.EnsureAcquired();
- OutputEventToConsoleWhileLocked(
- phase == TRACE_EVENT_PHASE_COMPLETE ? TRACE_EVENT_PHASE_BEGIN : phase,
- timestamp, trace_event);
- }
+ if (trace_options() & ECHO_TO_CONSOLE) {
+ lock.EnsureAcquired();
+ OutputEventToConsoleWhileLocked(
+ phase == TRACE_EVENT_PHASE_COMPLETE ? TRACE_EVENT_PHASE_BEGIN : phase,
+ timestamp, trace_event);
}
if (reinterpret_cast<const unsigned char*>(subtle::NoBarrier_Load(
&watch_category_)) == category_group_enabled) {
lock.EnsureAcquired();
- if (watch_event_name_ == name) {
- WatchEventCallback watch_event_callback_copy = watch_event_callback_;
- lock.EnsureReleased();
- if (!watch_event_callback_copy.is_null())
- watch_event_callback_copy.Run();
- }
+ if (watch_event_name_ == name)
+ notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION);
}
lock.EnsureReleased();
@@ -1785,8 +1850,10 @@
}
if (thread_local_event_buffer)
- thread_local_event_buffer->ReportOverhead(now, thread_now);
+ thread_local_event_buffer->ReportOverhead(now, thread_now, &notifier);
+ notifier.SendNotificationIfAny();
+
return handle;
}
@@ -1895,22 +1962,19 @@
}
void TraceLog::SetWatchEvent(const std::string& category_name,
- const std::string& event_name,
- const WatchEventCallback& callback) {
+ const std::string& event_name) {
const unsigned char* category = GetCategoryGroupEnabled(
category_name.c_str());
AutoLock lock(lock_);
subtle::NoBarrier_Store(&watch_category_,
reinterpret_cast<subtle::AtomicWord>(category));
watch_event_name_ = event_name;
- watch_event_callback_ = callback;
}
void TraceLog::CancelWatchEvent() {
AutoLock lock(lock_);
subtle::NoBarrier_Store(&watch_category_, 0);
watch_event_name_ = "";
- watch_event_callback_.Reset();
}
void TraceLog::AddMetadataEventsWhileLocked() {
@@ -1918,14 +1982,14 @@
int current_thread_id = static_cast<int>(base::PlatformThread::CurrentId());
if (process_sort_index_ != 0) {
- InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false),
+ InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, NULL),
current_thread_id,
"process_sort_index", "sort_index",
process_sort_index_);
}
if (process_name_.size()) {
- InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false),
+ InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, NULL),
current_thread_id,
"process_name", "name",
process_name_);
@@ -1938,7 +2002,7 @@
it++) {
labels.push_back(it->second);
}
- InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false),
+ InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, NULL),
current_thread_id,
"process_labels", "labels",
JoinString(labels, ','));
@@ -1950,7 +2014,7 @@
it++) {
if (it->second == 0)
continue;
- InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false),
+ InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, NULL),
it->first,
"thread_sort_index", "sort_index",
it->second);
@@ -1962,7 +2026,7 @@
it++) {
if (it->second.empty())
continue;
- InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false),
+ InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, NULL),
it->first,
"thread_name", "name",
it->second);
« no previous file with comments | « trunk/src/base/debug/trace_event_impl.h ('k') | trunk/src/base/debug/trace_event_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698