OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "components/task_scheduler_util/common/variations_util.h" | 5 #include "components/task_scheduler_util/common/variations_util.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/ptr_util.h" |
9 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/string_split.h" | 11 #include "base/strings/string_split.h" |
11 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
12 #include "base/task_scheduler/initialization_util.h" | 13 #include "base/task_scheduler/initialization_util.h" |
13 #include "base/time/time.h" | 14 #include "base/time/time.h" |
14 #include "components/variations/variations_associated_data.h" | 15 #include "components/variations/variations_associated_data.h" |
15 | 16 |
16 namespace task_scheduler_util { | 17 namespace task_scheduler_util { |
17 | 18 |
18 namespace { | 19 namespace { |
19 | 20 |
20 struct SchedulerCustomizableWorkerPoolParams { | |
21 base::SchedulerWorkerPoolParams::StandbyThreadPolicy standby_thread_policy; | |
22 int max_threads = 0; | |
23 base::TimeDelta detach_period; | |
24 }; | |
25 | |
26 #if !defined(OS_IOS) | 21 #if !defined(OS_IOS) |
27 constexpr char kTaskSchedulerVariationParamsSwitch[] = | 22 constexpr char kTaskSchedulerVariationParamsSwitch[] = |
28 "task-scheduler-variation-params"; | 23 "task-scheduler-variation-params"; |
29 | 24 |
30 constexpr char kSeparator[] = "|"; | 25 constexpr char kSeparator[] = "|"; |
31 | 26 |
32 bool ContainsSeparator(const std::string& str) { | 27 bool ContainsSeparator(const std::string& str) { |
33 return str.find(kSeparator) != std::string::npos; | 28 return str.find(kSeparator) != std::string::npos; |
34 } | 29 } |
35 #endif // !defined(OS_IOS) | 30 #endif // !defined(OS_IOS) |
36 | 31 |
37 // Converts |pool_descriptor| to a SchedulerWorkerPoolVariableParams. Returns a | 32 // Builds a SchedulerWorkerPoolParams from the pool descriptor in |
38 // default SchedulerWorkerPoolVariableParams on failure. | 33 // |variation_params[variation_param_prefix + pool_name]| and |
| 34 // |backward_compatibility|. Returns an invalid SchedulerWorkerPoolParams on |
| 35 // failure. |
39 // | 36 // |
40 // |pool_descriptor| is a semi-colon separated value string with the following | 37 // The pool descriptor is a semi-colon separated value string with the following |
41 // items: | 38 // items: |
42 // 0. Minimum Thread Count (int) | 39 // 0. Minimum Thread Count (int) |
43 // 1. Maximum Thread Count (int) | 40 // 1. Maximum Thread Count (int) |
44 // 2. Thread Count Multiplier (double) | 41 // 2. Thread Count Multiplier (double) |
45 // 3. Thread Count Offset (int) | 42 // 3. Thread Count Offset (int) |
46 // 4. Detach Time in Milliseconds (int) | 43 // 4. Detach Time in Milliseconds (int) |
47 // 5. Standby Thread Policy (string) | 44 // 5. Standby Thread Policy (string) |
48 // Additional values may appear as necessary and will be ignored. | 45 // Additional values may appear as necessary and will be ignored. |
49 SchedulerCustomizableWorkerPoolParams StringToVariableWorkerPoolParams( | 46 std::unique_ptr<base::SchedulerWorkerPoolParams> GetWorkerPoolParams( |
50 const base::StringPiece pool_descriptor) { | 47 base::StringPiece variation_param_prefix, |
| 48 base::StringPiece pool_name, |
| 49 const std::map<std::string, std::string>& variation_params, |
| 50 base::SchedulerBackwardCompatibility backward_compatibility = |
| 51 base::SchedulerBackwardCompatibility::DISABLED) { |
51 using StandbyThreadPolicy = | 52 using StandbyThreadPolicy = |
52 base::SchedulerWorkerPoolParams::StandbyThreadPolicy; | 53 base::SchedulerWorkerPoolParams::StandbyThreadPolicy; |
| 54 |
| 55 auto pool_descriptor_it = variation_params.find( |
| 56 base::JoinString({variation_param_prefix, pool_name}, "")); |
| 57 if (pool_descriptor_it == variation_params.end()) |
| 58 return nullptr; |
| 59 const auto& pool_descriptor = pool_descriptor_it->second; |
| 60 |
53 const std::vector<base::StringPiece> tokens = SplitStringPiece( | 61 const std::vector<base::StringPiece> tokens = SplitStringPiece( |
54 pool_descriptor, ";", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); | 62 pool_descriptor, ";", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); |
55 // Normally, we wouldn't initialize the values below because we don't read | 63 // Normally, we wouldn't initialize the values below because we don't read |
56 // from them before we write to them. However, some compilers (like MSVC) | 64 // from them before we write to them. However, some compilers (like MSVC) |
57 // complain about uninitialized variables due to the as_string() call below. | 65 // complain about uninitialized variables due to the as_string() call below. |
58 int min = 0; | 66 int min = 0; |
59 int max = 0; | 67 int max = 0; |
60 double cores_multiplier = 0.0; | 68 double cores_multiplier = 0.0; |
61 int offset = 0; | 69 int offset = 0; |
62 int detach_milliseconds = 0; | 70 int detach_milliseconds = 0; |
63 // Checking for a size greater than the expected amount allows us to be | 71 // Checking for a size greater than the expected amount allows us to be |
64 // forward compatible if we add more variation values. | 72 // forward compatible if we add more variation values. |
65 if (tokens.size() >= 5 && base::StringToInt(tokens[0], &min) && | 73 if (tokens.size() < 5 || !base::StringToInt(tokens[0], &min) || |
66 base::StringToInt(tokens[1], &max) && | 74 !base::StringToInt(tokens[1], &max) || |
67 base::StringToDouble(tokens[2].as_string(), &cores_multiplier) && | 75 !base::StringToDouble(tokens[2].as_string(), &cores_multiplier) || |
68 base::StringToInt(tokens[3], &offset) && | 76 !base::StringToInt(tokens[3], &offset) || |
69 base::StringToInt(tokens[4], &detach_milliseconds)) { | 77 !base::StringToInt(tokens[4], &detach_milliseconds)) { |
70 SchedulerCustomizableWorkerPoolParams params; | 78 DLOG(ERROR) << "Invalid Worker Pool Descriptor Format: " << pool_descriptor; |
71 params.max_threads = base::RecommendedMaxNumberOfThreadsInPool( | 79 return nullptr; |
72 min, max, cores_multiplier, offset); | |
73 params.detach_period = | |
74 base::TimeDelta::FromMilliseconds(detach_milliseconds); | |
75 params.standby_thread_policy = (tokens.size() >= 6 && tokens[5] == "lazy") | |
76 ? StandbyThreadPolicy::LAZY | |
77 : StandbyThreadPolicy::ONE; | |
78 return params; | |
79 } | 80 } |
80 DLOG(ERROR) << "Invalid Worker Pool Descriptor: " << pool_descriptor; | 81 |
81 return SchedulerCustomizableWorkerPoolParams(); | 82 auto params = base::MakeUnique<base::SchedulerWorkerPoolParams>( |
| 83 (tokens.size() >= 6 && tokens[5] == "lazy") ? StandbyThreadPolicy::LAZY |
| 84 : StandbyThreadPolicy::ONE, |
| 85 base::RecommendedMaxNumberOfThreadsInPool(min, max, cores_multiplier, |
| 86 offset), |
| 87 base::TimeDelta::FromMilliseconds(detach_milliseconds), |
| 88 backward_compatibility); |
| 89 |
| 90 if (params->max_threads() <= 0) { |
| 91 DLOG(ERROR) << "Invalid max threads in the Worker Pool Descriptor: " |
| 92 << params->max_threads(); |
| 93 return nullptr; |
| 94 } |
| 95 |
| 96 if (params->suggested_reclaim_time() < base::TimeDelta()) { |
| 97 DLOG(ERROR) |
| 98 << "Invalid suggested reclaim time in the Worker Pool Descriptor:" |
| 99 << params->suggested_reclaim_time(); |
| 100 return nullptr; |
| 101 } |
| 102 |
| 103 return params; |
82 } | 104 } |
83 | 105 |
84 } // namespace | 106 } // namespace |
85 | 107 |
86 SchedulerImmutableWorkerPoolParams::SchedulerImmutableWorkerPoolParams( | 108 std::unique_ptr<base::TaskScheduler::InitParams> GetTaskSchedulerInitParams( |
87 const char* name, | 109 base::StringPiece variation_param_prefix, |
88 base::ThreadPriority priority_hint, | 110 const std::map<std::string, std::string>& variation_params, |
89 base::SchedulerBackwardCompatibility backward_compatibility) | 111 base::SchedulerBackwardCompatibility |
90 : name_(name), | 112 foreground_blocking_backward_compatibility) { |
91 priority_hint_(priority_hint), | 113 const auto background_worker_pool_params = GetWorkerPoolParams( |
92 backward_compatibility_(backward_compatibility) {} | 114 variation_param_prefix, "Background", variation_params); |
| 115 const auto background_blocking_worker_pool_params = GetWorkerPoolParams( |
| 116 variation_param_prefix, "BackgroundBlocking", variation_params); |
| 117 const auto foreground_worker_pool_params = GetWorkerPoolParams( |
| 118 variation_param_prefix, "Foreground", variation_params); |
| 119 const auto foreground_blocking_worker_pool_params = GetWorkerPoolParams( |
| 120 variation_param_prefix, "ForegroundBlocking", variation_params, |
| 121 foreground_blocking_backward_compatibility); |
93 | 122 |
94 std::vector<base::SchedulerWorkerPoolParams> GetWorkerPoolParams( | 123 if (!background_worker_pool_params || |
95 const std::vector<SchedulerImmutableWorkerPoolParams>& | 124 !background_blocking_worker_pool_params || |
96 constant_worker_pool_params_vector, | 125 !foreground_worker_pool_params || |
97 const std::map<std::string, std::string>& variation_params) { | 126 !foreground_blocking_worker_pool_params) { |
98 std::vector<base::SchedulerWorkerPoolParams> worker_pool_params_vector; | 127 return nullptr; |
99 for (const auto& constant_worker_pool_params : | |
100 constant_worker_pool_params_vector) { | |
101 const char* const worker_pool_name = constant_worker_pool_params.name(); | |
102 auto it = variation_params.find(worker_pool_name); | |
103 if (it == variation_params.end()) { | |
104 // Non-branded builds don't have access to external worker pool | |
105 // configurations. | |
106 return std::vector<base::SchedulerWorkerPoolParams>(); | |
107 } | |
108 const auto variable_worker_pool_params = | |
109 StringToVariableWorkerPoolParams(it->second); | |
110 if (variable_worker_pool_params.max_threads <= 0 || | |
111 variable_worker_pool_params.detach_period <= base::TimeDelta()) { | |
112 DLOG(ERROR) << "Invalid Worker Pool Configuration: " << worker_pool_name | |
113 << " [" << it->second << "]"; | |
114 return std::vector<base::SchedulerWorkerPoolParams>(); | |
115 } | |
116 worker_pool_params_vector.emplace_back( | |
117 worker_pool_name, constant_worker_pool_params.priority_hint(), | |
118 variable_worker_pool_params.standby_thread_policy, | |
119 variable_worker_pool_params.max_threads, | |
120 variable_worker_pool_params.detach_period, | |
121 constant_worker_pool_params.backward_compatibility()); | |
122 } | 128 } |
123 return worker_pool_params_vector; | 129 |
| 130 return base::MakeUnique<base::TaskScheduler::InitParams>( |
| 131 *background_worker_pool_params, *background_blocking_worker_pool_params, |
| 132 *foreground_worker_pool_params, *foreground_blocking_worker_pool_params); |
124 } | 133 } |
125 | 134 |
126 #if !defined(OS_IOS) | 135 #if !defined(OS_IOS) |
127 void AddVariationParamsToCommandLine(base::StringPiece key_prefix, | 136 void AddVariationParamsToCommandLine(base::StringPiece key_prefix, |
128 base::CommandLine* command_line) { | 137 base::CommandLine* command_line) { |
129 DCHECK(command_line); | 138 DCHECK(command_line); |
130 | 139 |
131 std::map<std::string, std::string> variation_params; | 140 std::map<std::string, std::string> variation_params; |
132 if (!variations::GetVariationParams("BrowserScheduler", &variation_params)) | 141 if (!variations::GetVariationParams("BrowserScheduler", &variation_params)) |
133 return; | 142 return; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 return std::map<std::string, std::string>(); | 179 return std::map<std::string, std::string>(); |
171 } | 180 } |
172 base::StringPiece value = *it; | 181 base::StringPiece value = *it; |
173 variation_params[key.as_string()] = value.as_string(); | 182 variation_params[key.as_string()] = value.as_string(); |
174 } | 183 } |
175 return variation_params; | 184 return variation_params; |
176 } | 185 } |
177 #endif // !defined(OS_IOS) | 186 #endif // !defined(OS_IOS) |
178 | 187 |
179 } // namespace task_scheduler_util | 188 } // namespace task_scheduler_util |
OLD | NEW |