diff options
author | tonyg@chromium.org <tonyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-27 00:47:55 +0000 |
---|---|---|
committer | tonyg@chromium.org <tonyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-27 00:47:55 +0000 |
commit | 6aa58b8599840160df945afa89e7482d14d1c4d4 (patch) | |
tree | 7da568401c9497ac63894493ca5dd2e68230e35f /base/debug | |
parent | 7b05498220a28e7a351c28e75ce1dc68abc746f3 (diff) | |
download | chromium_src-6aa58b8599840160df945afa89e7482d14d1c4d4.zip chromium_src-6aa58b8599840160df945afa89e7482d14d1c4d4.tar.gz chromium_src-6aa58b8599840160df945afa89e7482d14d1c4d4.tar.bz2 |
Revert 237280 "Remove TraceController"
Seems to have broken trace-based telemetry benchmarks on android.
BUG=323749
> Remove TraceController
>
> TraceController is obsoleted by TracingController.
> Changed all remaining clients to use TracingController.
>
> BUG=none
>
> Review URL: https://codereview.chromium.org/67683003
TBR=wangxianzhu@chromium.org
Review URL: https://codereview.chromium.org/89753004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@237452 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/debug')
-rw-r--r-- | base/debug/trace_event_impl.cc | 216 | ||||
-rw-r--r-- | base/debug/trace_event_impl.h | 67 | ||||
-rw-r--r-- | base/debug/trace_event_unittest.cc | 48 |
3 files changed, 231 insertions, 100 deletions
diff --git a/base/debug/trace_event_impl.cc b/base/debug/trace_event_impl.cc index e4d20a5..8f08a1c 100644 --- a/base/debug/trace_event_impl.cc +++ b/base/debug/trace_event_impl.cc @@ -99,6 +99,11 @@ int g_category_index = g_num_builtin_categories; // Skip default categories. 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 @@ class TraceLog::ThreadLocalEventBuffer 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 @@ TraceLog::ThreadLocalEventBuffer::~ThreadLocalEventBuffer() { // - the thread has no message loop; // - trace_event_overhead is disabled. if (event_count_) { - InitializeMetadataEvent(AddTraceEvent(NULL), + NotificationHelper notifier(trace_log_); + InitializeMetadataEvent(AddTraceEvent(¬ifier, NULL), static_cast<int>(base::PlatformThread::CurrentId()), "overhead", "average_overhead", overhead_.InMillisecondsF() / event_count_); + notifier.SendNotificationIfAny(); } { @@ -1014,6 +1023,7 @@ TraceLog::ThreadLocalEventBuffer::~ThreadLocalEventBuffer() { } TraceEvent* TraceLog::ThreadLocalEventBuffer::AddTraceEvent( + NotificationHelper* notifier, TraceEventHandle* handle) { CheckThisIsCurrentBuffer(); @@ -1025,7 +1035,7 @@ TraceEvent* TraceLog::ThreadLocalEventBuffer::AddTraceEvent( 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 @@ TraceEvent* TraceLog::ThreadLocalEventBuffer::AddTraceEvent( 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 @@ void TraceLog::ThreadLocalEventBuffer::ReportOverhead( 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 @@ void TraceLog::ThreadLocalEventBuffer::FlushWhileLocked() { // 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 @@ void TraceLog::SetEnabled(const CategoryFilter& category_filter, 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 @@ CategoryFilter TraceLog::GetCurrentCategoryFilter() { } 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(); - - 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. + for (size_t i = 0; i < observer_list.size(); ++i) + observer_list[i]->OnTraceLogDisabled(); { - // 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 @@ bool TraceLog::HasEnabledStateObserver(EnabledStateObserver* listener) const { } 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 @@ TraceBuffer* TraceLog::CreateTraceBuffer() { } 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 @@ TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked( 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 @@ TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked( 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 @@ void TraceLog::FinishFlush(int generation) { 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 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp( 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 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp( } 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(¬ifier, + &handle); } else { lock.EnsureAcquired(); - trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true); + trace_event = AddEventToThreadSharedChunkWhileLocked(¬ifier, &handle); } if (trace_event) { @@ -1750,24 +1819,20 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp( 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,7 +1850,9 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp( } if (thread_local_event_buffer) - thread_local_event_buffer->ReportOverhead(now, thread_now); + thread_local_event_buffer->ReportOverhead(now, thread_now, ¬ifier); + + notifier.SendNotificationIfAny(); return handle; } @@ -1895,22 +1962,19 @@ void TraceLog::UpdateTraceEventDuration( } 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 @@ void TraceLog::AddMetadataEventsWhileLocked() { 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 @@ void TraceLog::AddMetadataEventsWhileLocked() { 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 @@ void TraceLog::AddMetadataEventsWhileLocked() { 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 @@ void TraceLog::AddMetadataEventsWhileLocked() { it++) { if (it->second.empty()) continue; - InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), + InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, NULL), it->first, "thread_name", "name", it->second); diff --git a/base/debug/trace_event_impl.h b/base/debug/trace_event_impl.h index 31a5f94..9e0ece9 100644 --- a/base/debug/trace_event_impl.h +++ b/base/debug/trace_event_impl.h @@ -352,6 +352,16 @@ class TraceSamplingThread; class BASE_EXPORT TraceLog { public: + // Notification is a mask of one or more of the following events. + enum Notification { + // The trace buffer does not flush dynamically, so when it fills up, + // subsequent trace events will be dropped. This callback is generated when + // the trace buffer is full. The callback must be thread safe. + TRACE_BUFFER_FULL = 1 << 0, + // A subscribed trace-event occurred. + EVENT_WATCH_NOTIFICATION = 1 << 1 + }; + // Options determines how the trace buffer stores data. enum Options { // Record until the trace buffer is full. @@ -383,6 +393,10 @@ class BASE_EXPORT TraceLog { static TraceLog* GetInstance(); + // Convert the given string to trace options. Defaults to RECORD_UNTIL_FULL if + // the string does not provide valid options. + static Options TraceOptionsFromString(const std::string& str); + // Get set of known category groups. This can change as new code paths are // reached. The known category groups are inserted into |category_groups|. void GetKnownCategoryGroups(std::vector<std::string>* category_groups); @@ -436,7 +450,14 @@ class BASE_EXPORT TraceLog { bool HasEnabledStateObserver(EnabledStateObserver* listener) const; float GetBufferPercentFull() const; - bool BufferIsFull() const; + + // Set the thread-safe notification callback. The callback can occur at any + // time and from any thread. WARNING: It is possible for the previously set + // callback to be called during OR AFTER a call to SetNotificationCallback. + // Therefore, the target of the callback must either be a global function, + // ref-counted object or a LazyInstance with Leaky traits (or equivalent). + typedef base::Callback<void(int)> NotificationCallback; + void SetNotificationCallback(const NotificationCallback& cb); // Not using base::Callback because of its limited by 7 parameters. // Also, using primitive type allows directly passing callback from WebCore. @@ -524,11 +545,12 @@ class BASE_EXPORT TraceLog { const char* name, TraceEventHandle handle); - // For every matching event, the callback will be called. - typedef base::Callback<void()> WatchEventCallback; + // For every matching event, a notification will be fired. NOTE: the + // notification will fire for each matching event that has already occurred + // since tracing was started (including before tracing if the process was + // started with tracing turned on). void SetWatchEvent(const std::string& category_name, - const std::string& event_name, - const WatchEventCallback& callback); + const std::string& event_name); // Cancel the watch event. If tracing is enabled, this may race with the // watch event notification firing. void CancelWatchEvent(); @@ -597,6 +619,29 @@ class BASE_EXPORT TraceLog { void UpdateCategoryGroupEnabledFlags(); void UpdateCategoryGroupEnabledFlag(int category_index); + // Helper class for managing notification_thread_count_ and running + // notification callbacks. This is very similar to a reader-writer lock, but + // shares the lock with TraceLog and manages the notification flags. + class NotificationHelper { + public: + inline explicit NotificationHelper(TraceLog* trace_log); + inline ~NotificationHelper(); + + // Called only while TraceLog::lock_ is held. This ORs the given + // notification with any existing notifications. + inline void AddNotificationWhileLocked(int notification); + + // Called only while TraceLog::lock_ is NOT held. If there are any pending + // notifications from previous calls to AddNotificationWhileLocked, this + // will call the NotificationCallback. + inline void SendNotificationIfAny(); + + private: + TraceLog* trace_log_; + NotificationCallback callback_copy_; + int notification_; + }; + class ThreadLocalEventBuffer; class OptionalAutoLock; @@ -612,10 +657,9 @@ class BASE_EXPORT TraceLog { const TimeTicks& timestamp, TraceEvent* trace_event); - TraceEvent* AddEventToThreadSharedChunkWhileLocked(TraceEventHandle* handle, - bool check_buffer_is_full); - void CheckIfBufferIsFullWhileLocked(); - void SetDisabledWhileLocked(); + TraceEvent* AddEventToThreadSharedChunkWhileLocked( + NotificationHelper* notifier, TraceEventHandle* handle); + void CheckIfBufferIsFullWhileLocked(NotificationHelper* notifier); TraceEvent* GetEventByHandleInternal(TraceEventHandle handle, OptionalAutoLock* lock); @@ -646,10 +690,12 @@ class BASE_EXPORT TraceLog { } // This lock protects TraceLog member accesses from arbitrary threads. - mutable Lock lock_; + Lock lock_; int locked_line_; bool enabled_; int num_traces_recorded_; + subtle::AtomicWord /* bool */ buffer_is_full_; + NotificationCallback notification_callback_; scoped_ptr<TraceBuffer> logged_events_; subtle::AtomicWord /* EventCallback */ event_callback_; bool dispatching_to_observer_list_; @@ -673,7 +719,6 @@ class BASE_EXPORT TraceLog { TimeDelta time_offset_; // Allow tests to wake up when certain events occur. - WatchEventCallback watch_event_callback_; subtle::AtomicWord /* const unsigned char* */ watch_category_; std::string watch_event_name_; diff --git a/base/debug/trace_event_unittest.cc b/base/debug/trace_event_unittest.cc index 0849c08..4aca180 100644 --- a/base/debug/trace_event_unittest.cc +++ b/base/debug/trace_event_unittest.cc @@ -53,8 +53,10 @@ class TraceEventTestFixture : public testing::Test { WaitableEvent* flush_complete_event, const scoped_refptr<base::RefCountedString>& events_str, bool has_more_events); - void OnWatchEventMatched() { - ++event_watch_notification_; + void OnTraceNotification(int notification) { + if (notification & TraceLog::EVENT_WATCH_NOTIFICATION) + ++event_watch_notification_; + notifications_received_ |= notification; } DictionaryValue* FindMatchingTraceEntry(const JsonKeyValue* key_values); DictionaryValue* FindNamePhase(const char* name, const char* phase); @@ -77,6 +79,7 @@ class TraceEventTestFixture : public testing::Test { void BeginSpecificTrace(const std::string& filter) { event_watch_notification_ = 0; + notifications_received_ = 0; TraceLog::GetInstance()->SetEnabled(CategoryFilter(filter), TraceLog::RECORD_UNTIL_FULL); } @@ -124,13 +127,16 @@ class TraceEventTestFixture : public testing::Test { virtual void SetUp() OVERRIDE { const char* name = PlatformThread::GetName(); old_thread_name_ = name ? strdup(name) : NULL; + notifications_received_ = 0; TraceLog::DeleteForTesting(); TraceLog* tracelog = TraceLog::GetInstance(); ASSERT_TRUE(tracelog); ASSERT_FALSE(tracelog->IsEnabled()); + tracelog->SetNotificationCallback( + base::Bind(&TraceEventTestFixture::OnTraceNotification, + base::Unretained(this))); trace_buffer_.SetOutputCallback(json_output_.GetCallback()); - event_watch_notification_ = 0; } virtual void TearDown() OVERRIDE { if (TraceLog::GetInstance()) @@ -147,6 +153,7 @@ class TraceEventTestFixture : public testing::Test { base::debug::TraceResultBuffer trace_buffer_; base::debug::TraceResultBuffer::SimpleOutput json_output_; int event_watch_notification_; + int notifications_received_; private: // We want our singleton torn down after each test. @@ -1181,17 +1188,14 @@ TEST_F(TraceEventTestFixture, Categories) { TEST_F(TraceEventTestFixture, EventWatchNotification) { // Basic one occurrence. BeginTrace(); - TraceLog::WatchEventCallback callback = - base::Bind(&TraceEventTestFixture::OnWatchEventMatched, - base::Unretained(this)); - TraceLog::GetInstance()->SetWatchEvent("cat", "event", callback); + TraceLog::GetInstance()->SetWatchEvent("cat", "event"); TRACE_EVENT_INSTANT0("cat", "event", TRACE_EVENT_SCOPE_THREAD); EndTraceAndFlush(); EXPECT_EQ(event_watch_notification_, 1); // Auto-reset after end trace. BeginTrace(); - TraceLog::GetInstance()->SetWatchEvent("cat", "event", callback); + TraceLog::GetInstance()->SetWatchEvent("cat", "event"); EndTraceAndFlush(); BeginTrace(); TRACE_EVENT_INSTANT0("cat", "event", TRACE_EVENT_SCOPE_THREAD); @@ -1201,7 +1205,7 @@ TEST_F(TraceEventTestFixture, EventWatchNotification) { // Multiple occurrence. BeginTrace(); int num_occurrences = 5; - TraceLog::GetInstance()->SetWatchEvent("cat", "event", callback); + TraceLog::GetInstance()->SetWatchEvent("cat", "event"); for (int i = 0; i < num_occurrences; ++i) TRACE_EVENT_INSTANT0("cat", "event", TRACE_EVENT_SCOPE_THREAD); EndTraceAndFlush(); @@ -1209,21 +1213,21 @@ TEST_F(TraceEventTestFixture, EventWatchNotification) { // Wrong category. BeginTrace(); - TraceLog::GetInstance()->SetWatchEvent("cat", "event", callback); + TraceLog::GetInstance()->SetWatchEvent("cat", "event"); TRACE_EVENT_INSTANT0("wrong_cat", "event", TRACE_EVENT_SCOPE_THREAD); EndTraceAndFlush(); EXPECT_EQ(event_watch_notification_, 0); // Wrong name. BeginTrace(); - TraceLog::GetInstance()->SetWatchEvent("cat", "event", callback); + TraceLog::GetInstance()->SetWatchEvent("cat", "event"); TRACE_EVENT_INSTANT0("cat", "wrong_event", TRACE_EVENT_SCOPE_THREAD); EndTraceAndFlush(); EXPECT_EQ(event_watch_notification_, 0); // Canceled. BeginTrace(); - TraceLog::GetInstance()->SetWatchEvent("cat", "event", callback); + TraceLog::GetInstance()->SetWatchEvent("cat", "event"); TraceLog::GetInstance()->CancelWatchEvent(); TRACE_EVENT_INSTANT0("cat", "event", TRACE_EVENT_SCOPE_THREAD); EndTraceAndFlush(); @@ -1730,7 +1734,23 @@ TEST_F(TraceEventTestFixture, TraceCategoriesAfterNestedEnable) { trace_log->SetDisabled(); } +TEST_F(TraceEventTestFixture, TraceOptionsParsing) { + EXPECT_EQ(TraceLog::RECORD_UNTIL_FULL, + TraceLog::TraceOptionsFromString(std::string())); + + EXPECT_EQ(TraceLog::RECORD_UNTIL_FULL, + TraceLog::TraceOptionsFromString("record-until-full")); + EXPECT_EQ(TraceLog::RECORD_CONTINUOUSLY, + TraceLog::TraceOptionsFromString("record-continuously")); + EXPECT_EQ(TraceLog::RECORD_UNTIL_FULL | TraceLog::ENABLE_SAMPLING, + TraceLog::TraceOptionsFromString("enable-sampling")); + EXPECT_EQ(TraceLog::RECORD_CONTINUOUSLY | TraceLog::ENABLE_SAMPLING, + TraceLog::TraceOptionsFromString( + "record-continuously,enable-sampling")); +} + TEST_F(TraceEventTestFixture, TraceSampling) { + event_watch_notification_ = 0; TraceLog::GetInstance()->SetEnabled( CategoryFilter("*"), TraceLog::Options(TraceLog::RECORD_UNTIL_FULL | @@ -1749,6 +1769,7 @@ TEST_F(TraceEventTestFixture, TraceSampling) { } TEST_F(TraceEventTestFixture, TraceSamplingScope) { + event_watch_notification_ = 0; TraceLog::GetInstance()->SetEnabled( CategoryFilter("*"), TraceLog::Options(TraceLog::RECORD_UNTIL_FULL | @@ -1783,6 +1804,7 @@ TEST_F(TraceEventTestFixture, TraceSamplingScope) { } TEST_F(TraceEventTestFixture, TraceContinuousSampling) { + event_watch_notification_ = 0; TraceLog::GetInstance()->SetEnabled( CategoryFilter("*"), TraceLog::Options(TraceLog::MONITOR_SAMPLING)); @@ -2049,7 +2071,7 @@ TEST_F(TraceEventCallbackTest, TraceEventCallbackWhileFull) { TraceLog::RECORD_UNTIL_FULL); do { TRACE_EVENT_INSTANT0("all", "badger badger", TRACE_EVENT_SCOPE_GLOBAL); - } while (!TraceLog::GetInstance()->BufferIsFull()); + } while ((notifications_received_ & TraceLog::TRACE_BUFFER_FULL) == 0); TraceLog::GetInstance()->SetEventCallbackEnabled(CategoryFilter("*"), Callback); TRACE_EVENT_INSTANT0("all", "a snake", TRACE_EVENT_SCOPE_GLOBAL); |