| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/stack_sampling_configuration.h" | |
| 6 | |
| 7 #include "base/rand_util.h" | |
| 8 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" | |
| 9 #include "chrome/common/channel_info.h" | |
| 10 #include "components/version_info/version_info.h" | |
| 11 | |
| 12 namespace { | |
| 13 | |
| 14 // The profiler is currently only implemented for Windows x64, and only runs on | |
| 15 // trunk, canary, and dev. | |
| 16 bool IsProfilerSupported() { | |
| 17 #if !defined(_WIN64) | |
| 18 return false; | |
| 19 #else | |
| 20 const version_info::Channel channel = chrome::GetChannel(); | |
| 21 return (channel == version_info::Channel::UNKNOWN || | |
| 22 channel == version_info::Channel::CANARY || | |
| 23 channel == version_info::Channel::DEV); | |
| 24 #endif | |
| 25 } | |
| 26 | |
| 27 } // namespace | |
| 28 | |
| 29 StackSamplingConfiguration::StackSamplingConfiguration() | |
| 30 : configuration_(GenerateConfiguration()) { | |
| 31 } | |
| 32 | |
| 33 base::StackSamplingProfiler::SamplingParams | |
| 34 StackSamplingConfiguration::GetSamplingParams() const { | |
| 35 base::StackSamplingProfiler::SamplingParams params; | |
| 36 params.bursts = 1; | |
| 37 const base::TimeDelta duration = base::TimeDelta::FromSeconds(30); | |
| 38 | |
| 39 switch (configuration_) { | |
| 40 case PROFILE_DISABLED: | |
| 41 case PROFILE_CONTROL: | |
| 42 params.initial_delay = base::TimeDelta::FromMilliseconds(0); | |
| 43 params.sampling_interval = base::TimeDelta::FromMilliseconds(0); | |
| 44 params.samples_per_burst = 0; | |
| 45 break; | |
| 46 | |
| 47 case PROFILE_NO_SAMPLES: | |
| 48 params.initial_delay = duration; | |
| 49 params.sampling_interval = base::TimeDelta::FromMilliseconds(0); | |
| 50 params.samples_per_burst = 0; | |
| 51 break; | |
| 52 | |
| 53 case PROFILE_5HZ: | |
| 54 params.initial_delay = base::TimeDelta::FromMilliseconds(0); | |
| 55 params.sampling_interval = base::TimeDelta::FromMilliseconds(200); | |
| 56 params.samples_per_burst = duration / params.sampling_interval; | |
| 57 break; | |
| 58 | |
| 59 case PROFILE_10HZ: | |
| 60 params.initial_delay = base::TimeDelta::FromMilliseconds(0); | |
| 61 params.sampling_interval = base::TimeDelta::FromMilliseconds(100); | |
| 62 params.samples_per_burst = duration / params.sampling_interval; | |
| 63 break; | |
| 64 | |
| 65 case PROFILE_100HZ: | |
| 66 params.initial_delay = base::TimeDelta::FromMilliseconds(0); | |
| 67 params.sampling_interval = base::TimeDelta::FromMilliseconds(10); | |
| 68 params.samples_per_burst = duration / params.sampling_interval; | |
| 69 break; | |
| 70 } | |
| 71 return params; | |
| 72 } | |
| 73 | |
| 74 bool StackSamplingConfiguration::IsProfilerEnabled() const { | |
| 75 return (configuration_ != PROFILE_DISABLED && | |
| 76 configuration_ != PROFILE_CONTROL); | |
| 77 } | |
| 78 | |
| 79 void StackSamplingConfiguration::RegisterSyntheticFieldTrial() const { | |
| 80 if (!IsProfilerSupported()) | |
| 81 return; | |
| 82 | |
| 83 std::string group; | |
| 84 switch (configuration_) { | |
| 85 case PROFILE_DISABLED: | |
| 86 group = "Disabled"; | |
| 87 break; | |
| 88 | |
| 89 case PROFILE_CONTROL: | |
| 90 group = "Control"; | |
| 91 break; | |
| 92 | |
| 93 case PROFILE_NO_SAMPLES: | |
| 94 group = "NoSamples"; | |
| 95 break; | |
| 96 | |
| 97 case PROFILE_5HZ: | |
| 98 group = "5Hz"; | |
| 99 break; | |
| 100 | |
| 101 case PROFILE_10HZ: | |
| 102 group = "10Hz"; | |
| 103 break; | |
| 104 | |
| 105 case PROFILE_100HZ: | |
| 106 group = "100Hz"; | |
| 107 break; | |
| 108 } | |
| 109 | |
| 110 ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial( | |
| 111 "SyntheticStackProfilingConfiguration", | |
| 112 group); | |
| 113 } | |
| 114 | |
| 115 // static | |
| 116 StackSamplingConfiguration::ProfileConfiguration | |
| 117 StackSamplingConfiguration::GenerateConfiguration() { | |
| 118 if (!IsProfilerSupported()) | |
| 119 return PROFILE_DISABLED; | |
| 120 | |
| 121 // Enable the profiler in the intended ultimate production configuration for | |
| 122 // development/waterfall builds. | |
| 123 if (chrome::GetChannel() == version_info::Channel::UNKNOWN) | |
| 124 return PROFILE_10HZ; | |
| 125 | |
| 126 // Enable according to the variations below in canary and dev. | |
| 127 if (chrome::GetChannel() == version_info::Channel::CANARY || | |
| 128 chrome::GetChannel() == version_info::Channel::DEV) { | |
| 129 struct Variation { | |
| 130 ProfileConfiguration config; | |
| 131 int weight; | |
| 132 }; | |
| 133 | |
| 134 // Generate a configuration according to the associated weights. | |
| 135 const Variation variations[] = { | |
| 136 { PROFILE_10HZ, 100}, | |
| 137 { PROFILE_CONTROL, 0}, | |
| 138 { PROFILE_DISABLED, 0} | |
| 139 }; | |
| 140 | |
| 141 int total_weight = 0; | |
| 142 for (const Variation& variation : variations) | |
| 143 total_weight += variation.weight; | |
| 144 DCHECK_EQ(100, total_weight); | |
| 145 | |
| 146 int chosen = base::RandInt(0, total_weight - 1); // Max is inclusive. | |
| 147 int cumulative_weight = 0; | |
| 148 for (const Variation& variation : variations) { | |
| 149 if (chosen >= cumulative_weight && | |
| 150 chosen < cumulative_weight + variation.weight) { | |
| 151 return variation.config; | |
| 152 } | |
| 153 cumulative_weight += variation.weight; | |
| 154 } | |
| 155 NOTREACHED(); | |
| 156 } | |
| 157 | |
| 158 return PROFILE_DISABLED; | |
| 159 } | |
| OLD | NEW |