| Index: trace_event/trace_event_etw_export_win.cc
|
| diff --git a/trace_event/trace_event_etw_export_win.cc b/trace_event/trace_event_etw_export_win.cc
|
| index c3b25dbe62b886280c5bfd8f5869ecf92abf3cd7..47935a4708c665f93208bb316fbfe84ba75db7dc 100644
|
| --- a/trace_event/trace_event_etw_export_win.cc
|
| +++ b/trace_event/trace_event_etw_export_win.cc
|
| @@ -43,12 +43,12 @@ tEventRegister EventRegisterProc = nullptr;
|
| tEventWrite EventWriteProc = nullptr;
|
| tEventUnregister EventUnregisterProc = nullptr;
|
|
|
| -// |filtered_event_group_names| contains the event categories that can be
|
| +// |kFilteredEventGroupNames| contains the event categories that can be
|
| // exported individually. These categories can be enabled by passing the correct
|
| // keyword when starting the trace. A keyword is a 64-bit flag and we attribute
|
| // one bit per category. We can therefore enable a particular category by
|
| // setting its corresponding bit in the keyword. For events that are not present
|
| -// in |filtered_event_group_names|, we have two bits that control their
|
| +// in |kFilteredEventGroupNames|, we have two bits that control their
|
| // behaviour. When bit 61 is enabled, any event that is not disabled by default
|
| // (ie. doesn't start with disabled-by-default-) will be exported. Likewise,
|
| // when bit 62 is enabled, any event that is disabled by default will be
|
| @@ -71,49 +71,27 @@ tEventUnregister EventUnregisterProc = nullptr;
|
| // refers to keywords as flags and there are two ways to enable them, using
|
| // group names or the hex representation. We only support the latter. Also, we
|
| // ignore the level.
|
| -const char* const filtered_event_group_names[] = {
|
| - "benchmark", // 0x1
|
| - "blink", // 0x2
|
| - "browser", // 0x4
|
| - "cc", // 0x8
|
| - "evdev", // 0x10
|
| - "gpu", // 0x20
|
| - "input", // 0x40
|
| - "netlog", // 0x80
|
| - "renderer.scheduler", // 0x100
|
| - "toplevel", // 0x200
|
| - "v8", // 0x400
|
| - "disabled-by-default-cc.debug", // 0x800
|
| - "disabled-by-default-cc.debug.picture", // 0x1000
|
| - "disabled-by-default-toplevel.flow"}; // 0x2000
|
| -const char* other_events_group_name = "__OTHER_EVENTS"; // 0x2000000000000000
|
| -const char* disabled_other_events_group_name =
|
| +const char* const kFilteredEventGroupNames[] = {
|
| + "benchmark", // 0x1
|
| + "blink", // 0x2
|
| + "browser", // 0x4
|
| + "cc", // 0x8
|
| + "evdev", // 0x10
|
| + "gpu", // 0x20
|
| + "input", // 0x40
|
| + "netlog", // 0x80
|
| + "renderer.scheduler", // 0x100
|
| + "toplevel", // 0x200
|
| + "v8", // 0x400
|
| + "disabled-by-default-cc.debug", // 0x800
|
| + "disabled-by-default-cc.debug.picture", // 0x1000
|
| + "disabled-by-default-toplevel.flow"}; // 0x2000
|
| +const char kOtherEventsGroupName[] = "__OTHER_EVENTS"; // 0x2000000000000000
|
| +const char kDisabledOtherEventsGroupName[] =
|
| "__DISABLED_OTHER_EVENTS"; // 0x4000000000000000
|
| -uint64 other_events_keyword_bit = 1ULL << 61;
|
| -uint64 disabled_other_events_keyword_bit = 1ULL << 62;
|
| -
|
| -// This object will be created by each process. It's a background (low-priority)
|
| -// thread that will monitor the ETW keyword for any changes.
|
| -class ETWKeywordUpdateThread : public base::PlatformThread::Delegate {
|
| - public:
|
| - ETWKeywordUpdateThread() {}
|
| - ~ETWKeywordUpdateThread() override {}
|
| -
|
| - // Implementation of PlatformThread::Delegate:
|
| - void ThreadMain() override {
|
| - base::PlatformThread::SetName("ETW Keyword Update Thread");
|
| - base::TimeDelta sleep_time =
|
| - base::TimeDelta::FromMilliseconds(kUpdateTimerDelayMs);
|
| - while (1) {
|
| - base::PlatformThread::Sleep(sleep_time);
|
| - base::trace_event::TraceEventETWExport::UpdateETWKeyword();
|
| - }
|
| - }
|
| -
|
| - private:
|
| - // Time between checks for ETW keyword changes (in milliseconds).
|
| - unsigned int kUpdateTimerDelayMs = 1000;
|
| -};
|
| +const uint64 kOtherEventsKeywordBit = 1ULL << 61;
|
| +const uint64 kDisabledOtherEventsKeywordBit = 1ULL << 62;
|
| +const size_t kNumberOfCategories = ARRAYSIZE(kFilteredEventGroupNames) + 2U;
|
|
|
| } // namespace
|
|
|
| @@ -152,6 +130,30 @@ ULONG EVNTAPI EventUnregister(REGHANDLE RegHandle) {
|
| namespace base {
|
| namespace trace_event {
|
|
|
| +// This object will be created by each process. It's a background (low-priority)
|
| +// thread that will monitor the ETW keyword for any changes.
|
| +class TraceEventETWExport::ETWKeywordUpdateThread
|
| + : public base::PlatformThread::Delegate {
|
| + public:
|
| + ETWKeywordUpdateThread() {}
|
| + ~ETWKeywordUpdateThread() override {}
|
| +
|
| + // Implementation of PlatformThread::Delegate:
|
| + void ThreadMain() override {
|
| + base::PlatformThread::SetName("ETW Keyword Update Thread");
|
| + base::TimeDelta sleep_time =
|
| + base::TimeDelta::FromMilliseconds(kUpdateTimerDelayMs);
|
| + while (1) {
|
| + base::PlatformThread::Sleep(sleep_time);
|
| + base::trace_event::TraceEventETWExport::UpdateETWKeyword();
|
| + }
|
| + }
|
| +
|
| + private:
|
| + // Time between checks for ETW keyword changes (in milliseconds).
|
| + unsigned int kUpdateTimerDelayMs = 1000;
|
| +};
|
| +
|
| TraceEventETWExport::TraceEventETWExport()
|
| : etw_export_enabled_(false), etw_match_any_keyword_(0ULL) {
|
| // Find Advapi32.dll. This should always succeed.
|
| @@ -169,6 +171,16 @@ TraceEventETWExport::TraceEventETWExport()
|
| // calls will fail (on XP this call will do nothing).
|
| EventRegisterChrome();
|
| }
|
| +
|
| + // Make sure to initialize the map with all the group names. Subsequent
|
| + // modifications will be made by the background thread and only affect the
|
| + // values of the keys (no key addition/deletion). Therefore, the map does not
|
| + // require a lock for access.
|
| + for (int i = 0; i < ARRAYSIZE(kFilteredEventGroupNames); i++)
|
| + categories_status_[kFilteredEventGroupNames[i]] = false;
|
| + categories_status_[kOtherEventsGroupName] = false;
|
| + categories_status_[kDisabledOtherEventsGroupName] = false;
|
| + DCHECK_EQ(kNumberOfCategories, categories_status_.size());
|
| }
|
|
|
| TraceEventETWExport::~TraceEventETWExport() {
|
| @@ -371,26 +383,28 @@ bool TraceEventETWExport::UpdateEnabledCategories() {
|
| // recording tools) using the ETW infrastructure. This value will be set in
|
| // all Chrome processes that have registered their ETW provider.
|
| etw_match_any_keyword_ = CHROME_Context.MatchAnyKeyword;
|
| - for (int i = 0; i < ARRAYSIZE(filtered_event_group_names); i++) {
|
| + for (int i = 0; i < ARRAYSIZE(kFilteredEventGroupNames); i++) {
|
| if (etw_match_any_keyword_ & (1ULL << i)) {
|
| - categories_status_[filtered_event_group_names[i]] = true;
|
| + categories_status_[kFilteredEventGroupNames[i]] = true;
|
| } else {
|
| - categories_status_[filtered_event_group_names[i]] = false;
|
| + categories_status_[kFilteredEventGroupNames[i]] = false;
|
| }
|
| }
|
|
|
| // Also update the two default categories.
|
| - if (etw_match_any_keyword_ & other_events_keyword_bit) {
|
| - categories_status_[other_events_group_name] = true;
|
| + if (etw_match_any_keyword_ & kOtherEventsKeywordBit) {
|
| + categories_status_[kOtherEventsGroupName] = true;
|
| } else {
|
| - categories_status_[other_events_group_name] = false;
|
| + categories_status_[kOtherEventsGroupName] = false;
|
| }
|
| - if (etw_match_any_keyword_ & disabled_other_events_keyword_bit) {
|
| - categories_status_[disabled_other_events_group_name] = true;
|
| + if (etw_match_any_keyword_ & kDisabledOtherEventsKeywordBit) {
|
| + categories_status_[kDisabledOtherEventsGroupName] = true;
|
| } else {
|
| - categories_status_[disabled_other_events_group_name] = false;
|
| + categories_status_[kDisabledOtherEventsGroupName] = false;
|
| }
|
|
|
| + DCHECK_EQ(kNumberOfCategories, categories_status_.size());
|
| +
|
| // Update the categories in TraceLog.
|
| TraceLog::GetInstance()->UpdateETWCategoryGroupEnabledFlags();
|
|
|
| @@ -398,6 +412,7 @@ bool TraceEventETWExport::UpdateEnabledCategories() {
|
| }
|
|
|
| bool TraceEventETWExport::IsCategoryEnabled(const char* category_name) const {
|
| + DCHECK_EQ(kNumberOfCategories, categories_status_.size());
|
| // Try to find the category and return its status if found
|
| auto it = categories_status_.find(category_name);
|
| if (it != categories_status_.end())
|
| @@ -406,13 +421,13 @@ bool TraceEventETWExport::IsCategoryEnabled(const char* category_name) const {
|
| // Otherwise return the corresponding default status by first checking if the
|
| // category is disabled by default.
|
| if (StringPiece(category_name).starts_with("disabled-by-default")) {
|
| - DCHECK(categories_status_.find(disabled_other_events_group_name) !=
|
| + DCHECK(categories_status_.find(kDisabledOtherEventsGroupName) !=
|
| categories_status_.end());
|
| - return categories_status_.find(disabled_other_events_group_name)->second;
|
| + return categories_status_.find(kDisabledOtherEventsGroupName)->second;
|
| } else {
|
| - DCHECK(categories_status_.find(other_events_group_name) !=
|
| + DCHECK(categories_status_.find(kOtherEventsGroupName) !=
|
| categories_status_.end());
|
| - return categories_status_.find(other_events_group_name)->second;
|
| + return categories_status_.find(kOtherEventsGroupName)->second;
|
| }
|
| }
|
|
|
|
|