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 |