Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/trace_event/trace_event_etw_export_win.h" | 5 #include "base/trace_event/trace_event_etw_export_win.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/singleton.h" | 9 #include "base/memory/singleton.h" |
| 10 #include "base/strings/string_tokenizer.h" | 10 #include "base/strings/string_tokenizer.h" |
| 11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
| 12 #include "base/threading/platform_thread.h" | |
| 12 #include "base/trace_event/trace_event.h" | 13 #include "base/trace_event/trace_event.h" |
| 13 #include "base/trace_event/trace_event_impl.h" | 14 #include "base/trace_event/trace_event_impl.h" |
| 14 | 15 |
| 15 // The GetProcAddress technique is borrowed from | 16 // The GetProcAddress technique is borrowed from |
| 16 // https://github.com/google/UIforETW/tree/master/ETWProviders | 17 // https://github.com/google/UIforETW/tree/master/ETWProviders |
| 17 // | 18 // |
| 18 // EVNTAPI is used in evntprov.h which is included by chrome_events_win.h. | 19 // EVNTAPI is used in evntprov.h which is included by chrome_events_win.h. |
| 19 // We define EVNTAPI without the DECLSPEC_IMPORT specifier so that we can | 20 // We define EVNTAPI without the DECLSPEC_IMPORT specifier so that we can |
| 20 // implement these functions locally instead of using the import library, and | 21 // implement these functions locally instead of using the import library, and |
| 21 // can therefore still run on Windows XP. | 22 // can therefore still run on Windows XP. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 83 "toplevel", // 0x200 | 84 "toplevel", // 0x200 |
| 84 "v8", // 0x400 | 85 "v8", // 0x400 |
| 85 "disabled-by-default-cc.debug", // 0x800 | 86 "disabled-by-default-cc.debug", // 0x800 |
| 86 "disabled-by-default-cc.debug.picture", // 0x1000 | 87 "disabled-by-default-cc.debug.picture", // 0x1000 |
| 87 "disabled-by-default-toplevel.flow"}; // 0x2000 | 88 "disabled-by-default-toplevel.flow"}; // 0x2000 |
| 88 const char* other_events_group_name = "__OTHER_EVENTS"; // 0x2000000000000000 | 89 const char* other_events_group_name = "__OTHER_EVENTS"; // 0x2000000000000000 |
| 89 const char* disabled_other_events_group_name = | 90 const char* disabled_other_events_group_name = |
| 90 "__DISABLED_OTHER_EVENTS"; // 0x4000000000000000 | 91 "__DISABLED_OTHER_EVENTS"; // 0x4000000000000000 |
| 91 uint64 other_events_keyword_bit = 1ULL << 61; | 92 uint64 other_events_keyword_bit = 1ULL << 61; |
| 92 uint64 disabled_other_events_keyword_bit = 1ULL << 62; | 93 uint64 disabled_other_events_keyword_bit = 1ULL << 62; |
| 94 | |
| 95 // This object will be created by each process. It's a background (low-priority) | |
| 96 // thread that will monitor the ETW keyword for any changes.. | |
| 97 class ETWKeywordUpdateThread : public base::PlatformThread::Delegate { | |
| 98 public: | |
| 99 ETWKeywordUpdateThread() {} | |
| 100 ~ETWKeywordUpdateThread() override {} | |
| 101 | |
| 102 // Implementation of PlatformThread::Delegate: | |
| 103 void ThreadMain() override { | |
| 104 base::PlatformThread::SetName("ETW Keyword Update Thread"); | |
| 105 while (1) { | |
| 106 base::PlatformThread::Sleep( | |
| 107 base::TimeDelta::FromMilliseconds(kUpdateTimerDelayMs)); | |
| 108 base::trace_event::TraceEventETWExport::UpdateKeyword(); | |
| 109 } | |
| 110 } | |
| 111 | |
| 112 private: | |
| 113 // Time between checks for ETW keyword changes (in milliseconds). | |
| 114 unsigned int kUpdateTimerDelayMs = 1000; | |
| 115 }; | |
| 116 | |
| 93 } // namespace | 117 } // namespace |
| 94 | 118 |
| 95 // Redirector function for EventRegister. Called by macros in | 119 // Redirector function for EventRegister. Called by macros in |
| 96 // chrome_events_win.h | 120 // chrome_events_win.h |
| 97 ULONG EVNTAPI EventRegister(LPCGUID ProviderId, | 121 ULONG EVNTAPI EventRegister(LPCGUID ProviderId, |
| 98 PENABLECALLBACK EnableCallback, | 122 PENABLECALLBACK EnableCallback, |
| 99 PVOID CallbackContext, | 123 PVOID CallbackContext, |
| 100 PREGHANDLE RegHandle) { | 124 PREGHANDLE RegHandle) { |
| 101 if (EventRegisterProc) | 125 if (EventRegisterProc) |
| 102 return EventRegisterProc(ProviderId, EnableCallback, CallbackContext, | 126 return EventRegisterProc(ProviderId, EnableCallback, CallbackContext, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 153 } | 177 } |
| 154 | 178 |
| 155 // static | 179 // static |
| 156 TraceEventETWExport* TraceEventETWExport::GetInstance() { | 180 TraceEventETWExport* TraceEventETWExport::GetInstance() { |
| 157 return Singleton<TraceEventETWExport, | 181 return Singleton<TraceEventETWExport, |
| 158 StaticMemorySingletonTraits<TraceEventETWExport>>::get(); | 182 StaticMemorySingletonTraits<TraceEventETWExport>>::get(); |
| 159 } | 183 } |
| 160 | 184 |
| 161 // static | 185 // static |
| 162 void TraceEventETWExport::EnableETWExport() { | 186 void TraceEventETWExport::EnableETWExport() { |
| 163 if (GetInstance()) | 187 if (GetInstance() && !GetInstance()->etw_export_enabled_) { |
|
brucedawson
2015/08/10 23:47:15
The repeated calls to GetInstance() seem excessive
Georges Khalil
2015/08/11 18:12:31
Agreed, done. I did it everywhere for consistency.
| |
| 164 GetInstance()->etw_export_enabled_ = true; | 188 GetInstance()->etw_export_enabled_ = true; |
| 189 // We only create the update thread once and it lives for as long as Chrome | |
| 190 // is running. | |
| 191 if (GetInstance()->keyword_update_thread_handle_.is_null()) { | |
| 192 GetInstance()->keyword_update_thread_.reset(new ETWKeywordUpdateThread); | |
| 193 PlatformThread::CreateWithPriority( | |
| 194 0, GetInstance()->keyword_update_thread_.get(), | |
| 195 &GetInstance()->keyword_update_thread_handle_, | |
| 196 ThreadPriority::BACKGROUND); | |
| 197 } | |
| 198 } | |
| 165 } | 199 } |
| 166 | 200 |
| 167 // static | 201 // static |
| 168 void TraceEventETWExport::DisableETWExport() { | 202 void TraceEventETWExport::DisableETWExport() { |
| 169 if (GetInstance()) | 203 if (GetInstance() && GetInstance()->etw_export_enabled_) |
| 170 GetInstance()->etw_export_enabled_ = false; | 204 GetInstance()->etw_export_enabled_ = false; |
| 171 } | 205 } |
| 172 | 206 |
| 173 // static | 207 // static |
| 174 bool TraceEventETWExport::IsETWExportEnabled() { | 208 bool TraceEventETWExport::IsETWExportEnabled() { |
| 175 return (GetInstance() && GetInstance()->etw_export_enabled_); | 209 return (GetInstance() && GetInstance()->etw_export_enabled_); |
| 176 } | 210 } |
| 177 | 211 |
| 178 // static | 212 // static |
| 179 void TraceEventETWExport::AddEvent( | 213 void TraceEventETWExport::AddEvent( |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 369 DCHECK(categories_status_.find(disabled_other_events_group_name) != | 403 DCHECK(categories_status_.find(disabled_other_events_group_name) != |
| 370 categories_status_.end()); | 404 categories_status_.end()); |
| 371 return categories_status_.find(disabled_other_events_group_name)->second; | 405 return categories_status_.find(disabled_other_events_group_name)->second; |
| 372 } else { | 406 } else { |
| 373 DCHECK(categories_status_.find(other_events_group_name) != | 407 DCHECK(categories_status_.find(other_events_group_name) != |
| 374 categories_status_.end()); | 408 categories_status_.end()); |
| 375 return categories_status_.find(other_events_group_name)->second; | 409 return categories_status_.find(other_events_group_name)->second; |
| 376 } | 410 } |
| 377 } | 411 } |
| 378 | 412 |
| 413 // static | |
| 414 void TraceEventETWExport::UpdateKeyword() { | |
| 415 DCHECK(GetInstance()); | |
| 416 if (IsETWExportEnabled()) { | |
| 417 if (GetInstance()->UpdateEnabledCategories()) | |
| 418 TraceLog::GetInstance()->UpdateCategoryGroupEnabledFlags(); | |
|
brucedawson
2015/08/10 23:47:15
I think we need a lock around the data structures
Georges Khalil
2015/08/11 18:12:31
Technically, yes, there's a very small chance of r
| |
| 419 } | |
| 420 } | |
| 379 } // namespace trace_event | 421 } // namespace trace_event |
| 380 } // namespace base | 422 } // namespace base |
| OLD | NEW |