Chromium Code Reviews| Index: base/trace_event/trace_log.cc |
| diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc |
| index c56f5c7894cc9df80a22ff10d0b51870e4af10fc..1d7c74002e798e847cb3d6519454223db66eab37 100644 |
| --- a/base/trace_event/trace_log.cc |
| +++ b/base/trace_event/trace_log.cc |
| @@ -462,7 +462,7 @@ TraceLog* TraceLog::GetInstance() { |
| } |
| TraceLog::TraceLog() |
| - : mode_(DISABLED), |
| + : enabled_modes_(0), |
| num_traces_recorded_(0), |
| event_callback_(0), |
| dispatching_to_observer_list_(false), |
| @@ -560,7 +560,7 @@ const char* TraceLog::GetCategoryGroupName( |
| void TraceLog::UpdateCategoryGroupEnabledFlag(size_t category_index) { |
| unsigned char enabled_flag = 0; |
| const char* category_group = g_category_groups[category_index]; |
| - if (mode_ == RECORDING_MODE && |
| + if (enabled_modes_ & RECORDING_MODE && |
| trace_config_.IsCategoryGroupEnabled(category_group)) { |
| enabled_flag |= ENABLED_FOR_RECORDING; |
| } |
| @@ -580,12 +580,12 @@ void TraceLog::UpdateCategoryGroupEnabledFlag(size_t category_index) { |
| // TODO(primiano): this is a temporary workaround for catapult:#2341, |
| // to guarantee that metadata events are always added even if the category |
| // filter is "-*". See crbug.com/618054 for more details and long-term fix. |
| - if (mode_ == RECORDING_MODE && !strcmp(category_group, "__metadata")) |
| + if (enabled_modes_ & RECORDING_MODE && !strcmp(category_group, "__metadata")) |
| enabled_flag |= ENABLED_FOR_RECORDING; |
| uint32_t enabled_filters_bitmap = 0; |
| int index = 0; |
| - for (const auto& event_filter : trace_config_.event_filters()) { |
| + for (const auto& event_filter : event_filters_enabled_) { |
| if (event_filter.IsCategoryGroupEnabled(category_group)) { |
| enabled_flag |= ENABLED_FOR_FILTERING; |
| DCHECK(g_category_group_filters.Get()[index]); |
| @@ -609,12 +609,15 @@ void TraceLog::UpdateCategoryGroupEnabledFlags() { |
| } |
| void TraceLog::CreateFiltersForTraceConfig() { |
| + if (!enabled_modes_ & FILTERING_MODE) |
|
Primiano Tucci (use gerrit)
2016/10/12 17:50:17
watch out operator orders, here you really want
i
ssid
2016/10/12 19:04:44
yes, i was going to fix this.
|
| + return; |
| + |
| // Filters were already added and tracing could be enabled. Filters list |
| // cannot be changed when trace events are using them. |
| if (g_category_group_filters.Get().size()) |
| return; |
| - for (auto& event_filter : trace_config_.event_filters()) { |
| + for (auto& event_filter : event_filters_enabled_) { |
| if (g_category_group_filters.Get().size() >= MAX_TRACE_EVENT_FILTERS) { |
| NOTREACHED() |
| << "Too many trace event filters installed in the current session"; |
| @@ -727,7 +730,7 @@ void TraceLog::GetKnownCategoryGroups( |
| category_groups->push_back(g_category_groups[i]); |
| } |
| -void TraceLog::SetEnabled(const TraceConfig& trace_config, Mode mode) { |
| +void TraceLog::SetEnabled(const TraceConfig& trace_config, uint8_t modes) { |
| std::vector<EnabledStateObserver*> observer_list; |
| std::map<AsyncEnabledStateObserver*, RegisteredAsyncObserver> observer_map; |
| { |
| @@ -741,32 +744,55 @@ void TraceLog::SetEnabled(const TraceConfig& trace_config, Mode mode) { |
| InternalTraceOptions old_options = trace_options(); |
| - if (IsEnabled()) { |
| - if (new_options != old_options) { |
| - DLOG(ERROR) << "Attempting to re-enable tracing with a different " |
| - << "set of options."; |
| - } |
| + if (dispatching_to_observer_list_) { |
| + NOTREACHED() |
| + << "Cannot manipulate TraceLog::Enabled state from an observer."; |
| + return; |
| + } |
| - if (mode != mode_) { |
| - DLOG(ERROR) << "Attempting to re-enable tracing with a different mode."; |
| + // Clear all filters from previous tracing session. These filters are not |
| + // cleared at the end of tracing because some threads which hit trace event |
| + // when disabling, could try to use the filters. |
| + if (!enabled_modes_) |
| + g_category_group_filters.Get().clear(); |
| + |
| + // Update trace config for recording. |
| + bool already_recording = enabled_modes_ & RECORDING_MODE; |
|
Primiano Tucci (use gerrit)
2016/10/12 17:50:17
+const (const bool)
ssid
2016/10/12 19:04:44
Done.
|
| + if (modes & RECORDING_MODE) { |
| + if (already_recording) { |
| + DCHECK_EQ(new_options, old_options) << "Attempting to re-enable " |
| + "tracing with a different set " |
| + "of options."; |
| + trace_config_.Merge(trace_config); |
| + } else { |
| + trace_config_ = trace_config; |
| } |
| - |
| - DCHECK(!trace_config.event_filters().size()) |
| - << "Adding new filters while tracing was already enabled is not " |
| - "supported."; |
| - |
| - trace_config_.Merge(trace_config); |
| - UpdateCategoryGroupEnabledFlags(); |
| - return; |
| } |
| - if (dispatching_to_observer_list_) { |
| - DLOG(ERROR) |
| - << "Cannot manipulate TraceLog::Enabled state from an observer."; |
| - return; |
| + // Update event filters. |
| + if (modes & FILTERING_MODE) { |
| + DCHECK(!trace_config.event_filters().empty()) |
| + << "Attempting to enable filtering without any filters"; |
| + DCHECK(event_filters_enabled_.empty()) << "Attempting to re-enable " |
| + "filtering when filters are " |
| + "already enabled."; |
| + |
| + // Use the given event filters only if filtering was not enabled. |
| + if (event_filters_enabled_.empty()) |
| + event_filters_enabled_ = trace_config.event_filters(); |
| } |
| + // Keep the |trace_config_| updated with only enabled filters in case anyone |
| + // tries to read it using |GetCurrentTraceConfig| (even if filters are |
| + // empty). |
| + trace_config_.SetEventFilterConfigs(event_filters_enabled_); |
| - mode_ = mode; |
| + enabled_modes_ |= modes; |
| + UpdateCategoryGroupEnabledFlags(); |
| + |
| + // Do not notify observers or create trace buffer if only enabled for |
| + // filtering or if recording was already enabled. |
| + if (!(modes & RECORDING_MODE) || already_recording) |
| + return; |
| if (new_options != old_options) { |
| subtle::NoBarrier_Store(&trace_options_, new_options); |
| @@ -775,12 +801,6 @@ void TraceLog::SetEnabled(const TraceConfig& trace_config, Mode mode) { |
| num_traces_recorded_++; |
| - // Clear all filters from previous tracing session. These filters are not |
| - // cleared at the end of tracing because some threads which hit trace event |
| - // when disabling, could try to use the filters. |
| - g_category_group_filters.Get().clear(); |
| - |
| - trace_config_ = TraceConfig(trace_config); |
| UpdateCategoryGroupEnabledFlags(); |
| UpdateSyntheticDelaysFromTraceConfig(); |
| @@ -837,27 +857,44 @@ TraceConfig TraceLog::GetCurrentTraceConfig() const { |
| void TraceLog::SetDisabled() { |
| AutoLock lock(lock_); |
| - SetDisabledWhileLocked(); |
| + SetDisabledWhileLocked(RECORDING_MODE); |
| +} |
| + |
| +void TraceLog::SetDisabled(uint8_t modes) { |
| + AutoLock lock(lock_); |
| + SetDisabledWhileLocked(modes); |
| } |
| -void TraceLog::SetDisabledWhileLocked() { |
| +void TraceLog::SetDisabledWhileLocked(uint8_t modes) { |
| lock_.AssertAcquired(); |
| - if (!IsEnabled()) |
| + if (!(enabled_modes_ & modes)) |
| return; |
| if (dispatching_to_observer_list_) { |
| - DLOG(ERROR) |
| + NOTREACHED() |
| << "Cannot manipulate TraceLog::Enabled state from an observer."; |
| return; |
| } |
| - mode_ = DISABLED; |
| + enabled_modes_ &= ~modes; |
| + |
| + if (modes & FILTERING_MODE) |
| + event_filters_enabled_.clear(); |
| + |
| + if (modes & RECORDING_MODE) { |
| + trace_config_.Clear(); |
| + |
| + subtle::NoBarrier_Store(&watch_category_, 0); |
| + watch_event_name_.clear(); |
| + } |
| - trace_config_.Clear(); |
| - subtle::NoBarrier_Store(&watch_category_, 0); |
| - watch_event_name_.clear(); |
| UpdateCategoryGroupEnabledFlags(); |
| + |
| + // Skip adding metadata events and notifying observers for filtering mode. |
| + if (!(modes & RECORDING_MODE)) |
| + return; |
| + |
| AddMetadataEventsWhileLocked(); |
| // Remove metadata events so they will not get added to a subsequent trace. |
| @@ -957,7 +994,7 @@ void TraceLog::CheckIfBufferIsFullWhileLocked() { |
| if (buffer_limit_reached_timestamp_.is_null()) { |
| buffer_limit_reached_timestamp_ = OffsetNow(); |
| } |
| - SetDisabledWhileLocked(); |
| + SetDisabledWhileLocked(RECORDING_MODE); |
| } |
| } |
| @@ -1344,11 +1381,6 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp( |
| TimeTicks offset_event_timestamp = OffsetTimestamp(timestamp); |
| ThreadTicks thread_now = ThreadNow(); |
| - // |thread_local_event_buffer_| can be null if the current thread doesn't have |
| - // a message loop or the message loop is blocked. |
| - InitializeThreadLocalEventBufferIfSupported(); |
|
Primiano Tucci (use gerrit)
2016/10/12 17:50:17
hmm can you keep the InitializeTLEBIS here (maybe
ssid
2016/10/12 19:04:44
Done.
|
| - auto* thread_local_event_buffer = thread_local_event_buffer_.Get(); |
| - |
| // Check and update the current thread name only if the event is for the |
| // current thread to avoid locks in most cases. |
| if (thread_id == static_cast<int>(PlatformThread::CurrentId())) { |
| @@ -1420,6 +1452,11 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp( |
| // filters indicates or category is not enabled for filtering. |
| if ((*category_group_enabled & ENABLED_FOR_RECORDING) && |
| !disabled_by_filters) { |
| + // |thread_local_event_buffer_| can be null if the current thread doesn't |
| + // have a message loop or the message loop is blocked. |
| + InitializeThreadLocalEventBufferIfSupported(); |
| + auto* thread_local_event_buffer = thread_local_event_buffer_.Get(); |
| + |
| OptionalAutoLock lock(&lock_); |
| TraceEvent* trace_event = NULL; |