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 "chrome/common/stack_sampling_configuration.h" | 5 #include "chrome/common/stack_sampling_configuration.h" |
6 | 6 |
7 #include "base/command_line.h" | |
8 #include "base/lazy_instance.h" | |
7 #include "base/rand_util.h" | 9 #include "base/rand_util.h" |
8 #include "chrome/common/channel_info.h" | 10 #include "chrome/common/channel_info.h" |
11 #include "chrome/common/chrome_switches.h" | |
9 #include "components/version_info/version_info.h" | 12 #include "components/version_info/version_info.h" |
13 #include "content/public/common/content_switches.h" | |
10 | 14 |
11 namespace { | 15 namespace { |
12 | 16 |
17 static base::LazyInstance<StackSamplingConfiguration>::Leaky g_configuration = | |
18 LAZY_INSTANCE_INITIALIZER; | |
19 | |
13 // The profiler is currently only implemented for Windows x64, and only runs on | 20 // The profiler is currently only implemented for Windows x64, and only runs on |
14 // trunk, canary, and dev. | 21 // trunk, canary, and dev. |
15 bool IsProfilerSupported() { | 22 bool IsProfilerSupported() { |
16 #if !defined(_WIN64) | 23 #if !defined(_WIN64) |
17 return false; | 24 return false; |
18 #else | 25 #else |
19 const version_info::Channel channel = chrome::GetChannel(); | 26 const version_info::Channel channel = chrome::GetChannel(); |
20 return (channel == version_info::Channel::UNKNOWN || | 27 return (channel == version_info::Channel::UNKNOWN || |
21 channel == version_info::Channel::CANARY || | 28 channel == version_info::Channel::CANARY || |
22 channel == version_info::Channel::DEV); | 29 channel == version_info::Channel::DEV); |
23 #endif | 30 #endif |
24 } | 31 } |
25 | 32 |
33 bool ExecutingInBrowserProcess() { | |
Ilya Sherman
2016/09/28 01:02:15
nit: I'd prepend an "Is" to this name. And, pleas
Mike Wittman
2016/09/28 19:34:26
Changed to IsBrowserProcess. IsExecutingInBrowserP
| |
34 const base::CommandLine* command_line = | |
35 base::CommandLine::ForCurrentProcess(); | |
36 std::string process_type = | |
37 command_line->GetSwitchValueASCII(switches::kProcessType); | |
38 return process_type.empty(); | |
39 } | |
40 | |
26 } // namespace | 41 } // namespace |
27 | 42 |
28 StackSamplingConfiguration::StackSamplingConfiguration() | 43 StackSamplingConfiguration::StackSamplingConfiguration() |
29 : configuration_(GenerateConfiguration()) { | 44 : configuration_(GenerateConfiguration()) { |
30 } | 45 } |
31 | 46 |
32 base::StackSamplingProfiler::SamplingParams | 47 base::StackSamplingProfiler::SamplingParams |
33 StackSamplingConfiguration::GetSamplingParams() const { | 48 StackSamplingConfiguration::GetSamplingParamsForCurrentProcess() const { |
34 base::StackSamplingProfiler::SamplingParams params; | 49 base::StackSamplingProfiler::SamplingParams params; |
35 params.bursts = 1; | 50 params.bursts = 1; |
36 const base::TimeDelta duration = base::TimeDelta::FromSeconds(30); | 51 params.initial_delay = base::TimeDelta::FromMilliseconds(0); |
52 params.sampling_interval = base::TimeDelta::FromMilliseconds(0); | |
53 params.samples_per_burst = 0; | |
37 | 54 |
38 switch (configuration_) { | 55 if (IsProfilerEnabledForCurrentProcess()) { |
39 case PROFILE_DISABLED: | 56 const base::TimeDelta duration = base::TimeDelta::FromSeconds(30); |
40 case PROFILE_CONTROL: | 57 params.sampling_interval = base::TimeDelta::FromMilliseconds(100); |
41 params.initial_delay = base::TimeDelta::FromMilliseconds(0); | 58 params.samples_per_burst = duration / params.sampling_interval; |
42 params.sampling_interval = base::TimeDelta::FromMilliseconds(0); | 59 } |
43 params.samples_per_burst = 0; | |
44 break; | |
45 | 60 |
46 case PROFILE_NO_SAMPLES: | |
47 params.initial_delay = duration; | |
48 params.sampling_interval = base::TimeDelta::FromMilliseconds(0); | |
49 params.samples_per_burst = 0; | |
50 break; | |
51 | |
52 case PROFILE_5HZ: | |
53 params.initial_delay = base::TimeDelta::FromMilliseconds(0); | |
54 params.sampling_interval = base::TimeDelta::FromMilliseconds(200); | |
55 params.samples_per_burst = duration / params.sampling_interval; | |
56 break; | |
57 | |
58 case PROFILE_10HZ: | |
59 params.initial_delay = base::TimeDelta::FromMilliseconds(0); | |
60 params.sampling_interval = base::TimeDelta::FromMilliseconds(100); | |
61 params.samples_per_burst = duration / params.sampling_interval; | |
62 break; | |
63 | |
64 case PROFILE_100HZ: | |
65 params.initial_delay = base::TimeDelta::FromMilliseconds(0); | |
66 params.sampling_interval = base::TimeDelta::FromMilliseconds(10); | |
67 params.samples_per_burst = duration / params.sampling_interval; | |
68 break; | |
69 } | |
70 return params; | 61 return params; |
71 } | 62 } |
72 | 63 |
73 bool StackSamplingConfiguration::IsProfilerEnabled() const { | 64 bool StackSamplingConfiguration::IsProfilerEnabledForCurrentProcess() const { |
74 return (configuration_ != PROFILE_DISABLED && | 65 if (ExecutingInBrowserProcess()) { |
75 configuration_ != PROFILE_CONTROL); | 66 return configuration_ == PROFILE_BROWSER_PROCESS || |
67 configuration_ == PROFILE_BROWSER_AND_GPU_PROCESS; | |
68 } | |
69 | |
70 DCHECK(configuration_ == PROFILE_FROM_COMMAND_LINE); | |
Ilya Sherman
2016/09/28 01:02:15
nit: DCHECK_EQ
Mike Wittman
2016/09/28 19:34:26
Done.
| |
71 // This is a child process. The kStartStackProfiler switch passed by the | |
72 // browser process determines whether the profiler is enabled for the process. | |
73 const base::CommandLine* command_line = | |
74 base::CommandLine::ForCurrentProcess(); | |
75 return command_line->HasSwitch(switches::kStartStackProfiler); | |
76 } | 76 } |
77 | 77 |
78 void StackSamplingConfiguration::RegisterSyntheticFieldTrial( | 78 void StackSamplingConfiguration::RegisterSyntheticFieldTrial( |
79 const RegisterSyntheticFieldTrialFunction& register_field_trial) const { | 79 const RegisterSyntheticFieldTrialFunction& register_field_trial) const { |
80 DCHECK(ExecutingInBrowserProcess()); | |
81 | |
80 if (!IsProfilerSupported()) | 82 if (!IsProfilerSupported()) |
81 return; | 83 return; |
82 | 84 |
83 std::string group; | 85 std::string group; |
84 switch (configuration_) { | 86 switch (configuration_) { |
85 case PROFILE_DISABLED: | 87 case PROFILE_DISABLED: |
86 group = "Disabled"; | 88 group = "Disabled"; |
87 break; | 89 break; |
88 | 90 |
89 case PROFILE_CONTROL: | 91 case PROFILE_CONTROL: |
90 group = "Control"; | 92 group = "Control"; |
91 break; | 93 break; |
92 | 94 |
93 case PROFILE_NO_SAMPLES: | 95 case PROFILE_BROWSER_PROCESS: |
94 group = "NoSamples"; | 96 group = "BrowserProcess"; |
95 break; | 97 break; |
96 | 98 |
97 case PROFILE_5HZ: | 99 case PROFILE_GPU_PROCESS: |
98 group = "5Hz"; | 100 group = "GpuProcess"; |
99 break; | 101 break; |
100 | 102 |
101 case PROFILE_10HZ: | 103 case PROFILE_BROWSER_AND_GPU_PROCESS: |
102 group = "10Hz"; | 104 group = "BrowserAndGpuProcess"; |
103 break; | 105 break; |
104 | 106 |
105 case PROFILE_100HZ: | 107 case PROFILE_FROM_COMMAND_LINE: |
106 group = "100Hz"; | 108 NOTREACHED(); |
107 break; | 109 break; |
108 } | 110 } |
109 | 111 |
110 register_field_trial.Run("SyntheticStackProfilingConfiguration", group); | 112 register_field_trial.Run("SyntheticStackProfilingConfiguration", group); |
111 } | 113 } |
112 | 114 |
115 void StackSamplingConfiguration::AppendCommandLineSwitchForChildProcess( | |
116 const std::string process_type, | |
117 base::CommandLine* command_line) const { | |
118 DCHECK(ExecutingInBrowserProcess()); | |
119 | |
120 if (process_type == switches::kGpuProcess && | |
121 (configuration_ == PROFILE_GPU_PROCESS || | |
122 configuration_ == PROFILE_BROWSER_AND_GPU_PROCESS)) { | |
123 command_line->AppendSwitch(switches::kStartStackProfiler); | |
124 } | |
125 } | |
126 | |
127 // static | |
128 StackSamplingConfiguration* StackSamplingConfiguration::Get() { | |
129 return g_configuration.Pointer(); | |
130 } | |
131 | |
113 // static | 132 // static |
114 StackSamplingConfiguration::ProfileConfiguration | 133 StackSamplingConfiguration::ProfileConfiguration |
115 StackSamplingConfiguration::GenerateConfiguration() { | 134 StackSamplingConfiguration::GenerateConfiguration() { |
135 if (!ExecutingInBrowserProcess()) | |
136 return PROFILE_FROM_COMMAND_LINE; | |
137 | |
116 if (!IsProfilerSupported()) | 138 if (!IsProfilerSupported()) |
117 return PROFILE_DISABLED; | 139 return PROFILE_DISABLED; |
118 | 140 |
119 // Enable the profiler in the intended ultimate production configuration for | 141 // Enable the profiler in the ultimate production configuration for |
120 // development/waterfall builds. | 142 // development/waterfall builds. |
121 if (chrome::GetChannel() == version_info::Channel::UNKNOWN) | 143 if (chrome::GetChannel() == version_info::Channel::UNKNOWN) |
122 return PROFILE_10HZ; | 144 return PROFILE_BROWSER_AND_GPU_PROCESS; |
123 | 145 |
124 // Enable according to the variations below in canary and dev. | 146 // Enable according to the variations below in canary and dev. |
125 if (chrome::GetChannel() == version_info::Channel::CANARY || | 147 if (chrome::GetChannel() == version_info::Channel::CANARY || |
126 chrome::GetChannel() == version_info::Channel::DEV) { | 148 chrome::GetChannel() == version_info::Channel::DEV) { |
127 struct Variation { | 149 struct Variation { |
128 ProfileConfiguration config; | 150 ProfileConfiguration config; |
129 int weight; | 151 int weight; |
130 }; | 152 }; |
131 | 153 |
132 // Generate a configuration according to the associated weights. | 154 // Generate a configuration according to the associated weights. |
133 const Variation variations[] = { | 155 const Variation variations[] = { |
134 { PROFILE_10HZ, 100}, | 156 { PROFILE_BROWSER_PROCESS, 100}, |
157 { PROFILE_GPU_PROCESS, 0}, | |
158 { PROFILE_BROWSER_AND_GPU_PROCESS, 0}, | |
135 { PROFILE_CONTROL, 0}, | 159 { PROFILE_CONTROL, 0}, |
136 { PROFILE_DISABLED, 0} | 160 { PROFILE_DISABLED, 0} |
137 }; | 161 }; |
138 | 162 |
139 int total_weight = 0; | 163 int total_weight = 0; |
140 for (const Variation& variation : variations) | 164 for (const Variation& variation : variations) |
141 total_weight += variation.weight; | 165 total_weight += variation.weight; |
142 DCHECK_EQ(100, total_weight); | 166 DCHECK_EQ(100, total_weight); |
143 | 167 |
144 int chosen = base::RandInt(0, total_weight - 1); // Max is inclusive. | 168 int chosen = base::RandInt(0, total_weight - 1); // Max is inclusive. |
145 int cumulative_weight = 0; | 169 int cumulative_weight = 0; |
146 for (const Variation& variation : variations) { | 170 for (const Variation& variation : variations) { |
147 if (chosen >= cumulative_weight && | 171 if (chosen >= cumulative_weight && |
148 chosen < cumulative_weight + variation.weight) { | 172 chosen < cumulative_weight + variation.weight) { |
149 return variation.config; | 173 return variation.config; |
150 } | 174 } |
151 cumulative_weight += variation.weight; | 175 cumulative_weight += variation.weight; |
152 } | 176 } |
153 NOTREACHED(); | 177 NOTREACHED(); |
154 } | 178 } |
155 | 179 |
156 return PROFILE_DISABLED; | 180 return PROFILE_DISABLED; |
157 } | 181 } |
OLD | NEW |