| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/debug/trace_event_impl.h" | 5 #include "base/debug/trace_event_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/debug/leak_annotations.h" | 10 #include "base/debug/leak_annotations.h" |
| (...skipping 892 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 | 903 |
| 904 void TraceLog::GetKnownCategoryGroups( | 904 void TraceLog::GetKnownCategoryGroups( |
| 905 std::vector<std::string>* category_groups) { | 905 std::vector<std::string>* category_groups) { |
| 906 AutoLock lock(lock_); | 906 AutoLock lock(lock_); |
| 907 for (int i = g_num_builtin_categories; i < g_category_index; i++) | 907 for (int i = g_num_builtin_categories; i < g_category_index; i++) |
| 908 category_groups->push_back(g_category_groups[i]); | 908 category_groups->push_back(g_category_groups[i]); |
| 909 } | 909 } |
| 910 | 910 |
| 911 void TraceLog::SetEnabled(const CategoryFilter& category_filter, | 911 void TraceLog::SetEnabled(const CategoryFilter& category_filter, |
| 912 Options options) { | 912 Options options) { |
| 913 AutoLock lock(lock_); | 913 std::vector<EnabledStateObserver*> observer_list; |
| 914 { |
| 915 AutoLock lock(lock_); |
| 914 | 916 |
| 915 if (enable_count_++ > 0) { | 917 if (enable_count_++ > 0) { |
| 916 if (options != trace_options_) { | 918 if (options != trace_options_) { |
| 917 DLOG(ERROR) << "Attemting to re-enable tracing with a different " | 919 DLOG(ERROR) << "Attemting to re-enable tracing with a different " |
| 918 << "set of options."; | 920 << "set of options."; |
| 921 } |
| 922 |
| 923 category_filter_.Merge(category_filter); |
| 924 EnableIncludedCategoryGroups(); |
| 925 return; |
| 919 } | 926 } |
| 920 | 927 |
| 921 category_filter_.Merge(category_filter); | 928 if (options != trace_options_) { |
| 929 trace_options_ = options; |
| 930 logged_events_.reset(GetTraceBuffer()); |
| 931 } |
| 932 |
| 933 if (dispatching_to_observer_list_) { |
| 934 DLOG(ERROR) << |
| 935 "Cannot manipulate TraceLog::Enabled state from an observer."; |
| 936 return; |
| 937 } |
| 938 |
| 939 num_traces_recorded_++; |
| 940 |
| 941 category_filter_ = CategoryFilter(category_filter); |
| 922 EnableIncludedCategoryGroups(); | 942 EnableIncludedCategoryGroups(); |
| 923 return; | 943 |
| 944 // Not supported in split-dll build. http://crbug.com/237249 |
| 945 #if !defined(CHROME_SPLIT_DLL) |
| 946 if (options & ENABLE_SAMPLING) { |
| 947 sampling_thread_.reset(new TraceSamplingThread); |
| 948 sampling_thread_->RegisterSampleBucket( |
| 949 &g_trace_state0, |
| 950 "bucket0", |
| 951 Bind(&TraceSamplingThread::DefaultSampleCallback)); |
| 952 sampling_thread_->RegisterSampleBucket( |
| 953 &g_trace_state1, |
| 954 "bucket1", |
| 955 Bind(&TraceSamplingThread::DefaultSampleCallback)); |
| 956 sampling_thread_->RegisterSampleBucket( |
| 957 &g_trace_state2, |
| 958 "bucket2", |
| 959 Bind(&TraceSamplingThread::DefaultSampleCallback)); |
| 960 if (!PlatformThread::Create( |
| 961 0, sampling_thread_.get(), &sampling_thread_handle_)) { |
| 962 DCHECK(false) << "failed to create thread"; |
| 963 } |
| 964 } |
| 965 #endif |
| 966 |
| 967 dispatching_to_observer_list_ = true; |
| 968 observer_list = enabled_state_observer_list_; |
| 924 } | 969 } |
| 970 // Notify observers outside the lock in case they trigger trace events. |
| 971 for (size_t i = 0; i < observer_list.size(); ++i) |
| 972 observer_list[i]->OnTraceLogEnabled(); |
| 925 | 973 |
| 926 if (options != trace_options_) { | 974 { |
| 927 trace_options_ = options; | 975 AutoLock lock(lock_); |
| 928 logged_events_.reset(GetTraceBuffer()); | 976 dispatching_to_observer_list_ = false; |
| 929 } | 977 } |
| 930 | |
| 931 if (dispatching_to_observer_list_) { | |
| 932 DLOG(ERROR) << | |
| 933 "Cannot manipulate TraceLog::Enabled state from an observer."; | |
| 934 return; | |
| 935 } | |
| 936 | |
| 937 num_traces_recorded_++; | |
| 938 | |
| 939 dispatching_to_observer_list_ = true; | |
| 940 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, | |
| 941 OnTraceLogWillEnable()); | |
| 942 dispatching_to_observer_list_ = false; | |
| 943 | |
| 944 category_filter_ = CategoryFilter(category_filter); | |
| 945 EnableIncludedCategoryGroups(); | |
| 946 | |
| 947 // Not supported in split-dll build. http://crbug.com/237249 | |
| 948 #if !defined(CHROME_SPLIT_DLL) | |
| 949 if (options & ENABLE_SAMPLING) { | |
| 950 sampling_thread_.reset(new TraceSamplingThread); | |
| 951 sampling_thread_->RegisterSampleBucket( | |
| 952 &g_trace_state0, | |
| 953 "bucket0", | |
| 954 Bind(&TraceSamplingThread::DefaultSampleCallback)); | |
| 955 sampling_thread_->RegisterSampleBucket( | |
| 956 &g_trace_state1, | |
| 957 "bucket1", | |
| 958 Bind(&TraceSamplingThread::DefaultSampleCallback)); | |
| 959 sampling_thread_->RegisterSampleBucket( | |
| 960 &g_trace_state2, | |
| 961 "bucket2", | |
| 962 Bind(&TraceSamplingThread::DefaultSampleCallback)); | |
| 963 if (!PlatformThread::Create( | |
| 964 0, sampling_thread_.get(), &sampling_thread_handle_)) { | |
| 965 DCHECK(false) << "failed to create thread"; | |
| 966 } | |
| 967 } | |
| 968 #endif | |
| 969 } | 978 } |
| 970 | 979 |
| 971 const CategoryFilter& TraceLog::GetCurrentCategoryFilter() { | 980 const CategoryFilter& TraceLog::GetCurrentCategoryFilter() { |
| 972 AutoLock lock(lock_); | 981 AutoLock lock(lock_); |
| 973 DCHECK(enable_count_ > 0); | 982 DCHECK(enable_count_ > 0); |
| 974 return category_filter_; | 983 return category_filter_; |
| 975 } | 984 } |
| 976 | 985 |
| 977 void TraceLog::SetDisabled() { | 986 void TraceLog::SetDisabled() { |
| 978 AutoLock lock(lock_); | 987 std::vector<EnabledStateObserver*> observer_list; |
| 979 DCHECK(enable_count_ > 0); | 988 { |
| 980 if (--enable_count_ != 0) | 989 AutoLock lock(lock_); |
| 981 return; | 990 DCHECK(enable_count_ > 0); |
| 991 if (--enable_count_ != 0) |
| 992 return; |
| 982 | 993 |
| 983 if (dispatching_to_observer_list_) { | 994 if (dispatching_to_observer_list_) { |
| 984 DLOG(ERROR) | 995 DLOG(ERROR) |
| 985 << "Cannot manipulate TraceLog::Enabled state from an observer."; | 996 << "Cannot manipulate TraceLog::Enabled state from an observer."; |
| 986 return; | 997 return; |
| 998 } |
| 999 |
| 1000 if (sampling_thread_.get()) { |
| 1001 // Stop the sampling thread. |
| 1002 sampling_thread_->Stop(); |
| 1003 lock_.Release(); |
| 1004 PlatformThread::Join(sampling_thread_handle_); |
| 1005 lock_.Acquire(); |
| 1006 sampling_thread_handle_ = PlatformThreadHandle(); |
| 1007 sampling_thread_.reset(); |
| 1008 } |
| 1009 |
| 1010 category_filter_.Clear(); |
| 1011 watch_category_ = NULL; |
| 1012 watch_event_name_ = ""; |
| 1013 for (int i = 0; i < g_category_index; i++) |
| 1014 SetCategoryGroupEnabled(i, false); |
| 1015 AddThreadNameMetadataEvents(); |
| 1016 |
| 1017 dispatching_to_observer_list_ = true; |
| 1018 observer_list = enabled_state_observer_list_; |
| 987 } | 1019 } |
| 988 | 1020 |
| 989 if (sampling_thread_.get()) { | 1021 // Dispatch to observers outside the lock in case the observer triggers a |
| 990 // Stop the sampling thread. | 1022 // trace event. |
| 991 sampling_thread_->Stop(); | 1023 for (size_t i = 0; i < observer_list.size(); ++i) |
| 992 lock_.Release(); | 1024 observer_list[i]->OnTraceLogDisabled(); |
| 993 PlatformThread::Join(sampling_thread_handle_); | 1025 |
| 994 lock_.Acquire(); | 1026 { |
| 995 sampling_thread_handle_ = PlatformThreadHandle(); | 1027 AutoLock lock(lock_); |
| 996 sampling_thread_.reset(); | 1028 dispatching_to_observer_list_ = false; |
| 997 } | 1029 } |
| 998 | |
| 999 dispatching_to_observer_list_ = true; | |
| 1000 FOR_EACH_OBSERVER(EnabledStateChangedObserver, | |
| 1001 enabled_state_observer_list_, | |
| 1002 OnTraceLogWillDisable()); | |
| 1003 dispatching_to_observer_list_ = false; | |
| 1004 | |
| 1005 category_filter_.Clear(); | |
| 1006 watch_category_ = NULL; | |
| 1007 watch_event_name_ = ""; | |
| 1008 for (int i = 0; i < g_category_index; i++) | |
| 1009 SetCategoryGroupEnabled(i, false); | |
| 1010 AddThreadNameMetadataEvents(); | |
| 1011 } | 1030 } |
| 1012 | 1031 |
| 1013 int TraceLog::GetNumTracesRecorded() { | 1032 int TraceLog::GetNumTracesRecorded() { |
| 1014 AutoLock lock(lock_); | 1033 AutoLock lock(lock_); |
| 1015 if (enable_count_ == 0) | 1034 if (enable_count_ == 0) |
| 1016 return -1; | 1035 return -1; |
| 1017 return num_traces_recorded_; | 1036 return num_traces_recorded_; |
| 1018 } | 1037 } |
| 1019 | 1038 |
| 1020 void TraceLog::AddEnabledStateObserver(EnabledStateChangedObserver* listener) { | 1039 void TraceLog::AddEnabledStateObserver(EnabledStateObserver* listener) { |
| 1021 enabled_state_observer_list_.AddObserver(listener); | 1040 enabled_state_observer_list_.push_back(listener); |
| 1022 } | 1041 } |
| 1023 | 1042 |
| 1024 void TraceLog::RemoveEnabledStateObserver( | 1043 void TraceLog::RemoveEnabledStateObserver(EnabledStateObserver* listener) { |
| 1025 EnabledStateChangedObserver* listener) { | 1044 std::vector<EnabledStateObserver*>::iterator it = |
| 1026 enabled_state_observer_list_.RemoveObserver(listener); | 1045 std::find(enabled_state_observer_list_.begin(), |
| 1046 enabled_state_observer_list_.end(), |
| 1047 listener); |
| 1048 if (it != enabled_state_observer_list_.end()) |
| 1049 enabled_state_observer_list_.erase(it); |
| 1027 } | 1050 } |
| 1028 | 1051 |
| 1029 float TraceLog::GetBufferPercentFull() const { | 1052 float TraceLog::GetBufferPercentFull() const { |
| 1030 return (float)((double)logged_events_->Size()/(double)kTraceEventBufferSize); | 1053 return (float)((double)logged_events_->Size()/(double)kTraceEventBufferSize); |
| 1031 } | 1054 } |
| 1032 | 1055 |
| 1033 void TraceLog::SetNotificationCallback( | 1056 void TraceLog::SetNotificationCallback( |
| 1034 const TraceLog::NotificationCallback& cb) { | 1057 const TraceLog::NotificationCallback& cb) { |
| 1035 AutoLock lock(lock_); | 1058 AutoLock lock(lock_); |
| 1036 notification_callback_ = cb; | 1059 notification_callback_ = cb; |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1313 unsigned long long offset_basis = 14695981039346656037ull; | 1336 unsigned long long offset_basis = 14695981039346656037ull; |
| 1314 unsigned long long fnv_prime = 1099511628211ull; | 1337 unsigned long long fnv_prime = 1099511628211ull; |
| 1315 unsigned long long pid = static_cast<unsigned long long>(process_id_); | 1338 unsigned long long pid = static_cast<unsigned long long>(process_id_); |
| 1316 process_id_hash_ = (offset_basis ^ pid) * fnv_prime; | 1339 process_id_hash_ = (offset_basis ^ pid) * fnv_prime; |
| 1317 } | 1340 } |
| 1318 | 1341 |
| 1319 void TraceLog::SetTimeOffset(TimeDelta offset) { | 1342 void TraceLog::SetTimeOffset(TimeDelta offset) { |
| 1320 time_offset_ = offset; | 1343 time_offset_ = offset; |
| 1321 } | 1344 } |
| 1322 | 1345 |
| 1346 size_t TraceLog::GetObserverCountForTest() const { |
| 1347 return enabled_state_observer_list_.size(); |
| 1348 } |
| 1349 |
| 1323 bool CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( | 1350 bool CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( |
| 1324 const std::string& str) { | 1351 const std::string& str) { |
| 1325 return str.empty() || | 1352 return str.empty() || |
| 1326 str.at(0) == ' ' || | 1353 str.at(0) == ' ' || |
| 1327 str.at(str.length() - 1) == ' '; | 1354 str.at(str.length() - 1) == ' '; |
| 1328 } | 1355 } |
| 1329 | 1356 |
| 1330 bool CategoryFilter::DoesCategoryGroupContainCategory( | 1357 bool CategoryFilter::DoesCategoryGroupContainCategory( |
| 1331 const char* category_group, | 1358 const char* category_group, |
| 1332 const char* category) const { | 1359 const char* category) const { |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1520 0, // num_args | 1547 0, // num_args |
| 1521 NULL, // arg_names | 1548 NULL, // arg_names |
| 1522 NULL, // arg_types | 1549 NULL, // arg_types |
| 1523 NULL, // arg_values | 1550 NULL, // arg_values |
| 1524 NULL, // convertable values | 1551 NULL, // convertable values |
| 1525 TRACE_EVENT_FLAG_NONE); // flags | 1552 TRACE_EVENT_FLAG_NONE); // flags |
| 1526 } | 1553 } |
| 1527 } | 1554 } |
| 1528 | 1555 |
| 1529 } // namespace trace_event_internal | 1556 } // namespace trace_event_internal |
| OLD | NEW |