Avi Drissman | 4e1b7bc3 | 2022-09-15 14:03:50 | [diff] [blame] | 1 | // Copyright 2018 The Chromium Authors |
Xi Han | 636c7ca5 | 2018-10-04 16:56:29 | [diff] [blame] | 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 "content/browser/startup_helper.h" |
| 6 | |
Alexei Svitkine | 8724ea50 | 2019-06-14 21:51:46 | [diff] [blame] | 7 | #include <algorithm> |
| 8 | #include <memory> |
| 9 | #include <set> |
| 10 | #include <string> |
| 11 | |
Xi Han | 636c7ca5 | 2018-10-04 16:56:29 | [diff] [blame] | 12 | #include "base/base_switches.h" |
| 13 | #include "base/command_line.h" |
Sebastien Marchand | 75a7cdf | 2018-11-13 23:47:03 | [diff] [blame] | 14 | #include "base/system/sys_info.h" |
Gabriel Charette | 52fa3ae | 2019-04-15 21:44:37 | [diff] [blame] | 15 | #include "base/task/thread_pool/initialization_util.h" |
Gabriel Charette | eadf5886 | 2019-08-29 05:20:27 | [diff] [blame] | 16 | #include "base/task/thread_pool/thread_pool_instance.h" |
Xi Han | 8012e46 | 2018-10-05 19:52:30 | [diff] [blame] | 17 | #include "build/build_config.h" |
Gabriel Charette | 52fa3ae | 2019-04-15 21:44:37 | [diff] [blame] | 18 | #include "content/common/thread_pool_util.h" |
Lily Chen | d49e375 | 2019-08-09 19:05:24 | [diff] [blame] | 19 | #include "content/public/common/content_switch_dependent_feature_overrides.h" |
Xi Han | 8012e46 | 2018-10-05 19:52:30 | [diff] [blame] | 20 | #include "content/public/common/content_switches.h" |
Xi Han | 636c7ca5 | 2018-10-04 16:56:29 | [diff] [blame] | 21 | |
| 22 | namespace content { |
| 23 | |
| 24 | std::unique_ptr<base::FieldTrialList> SetUpFieldTrialsAndFeatureList() { |
Alexei Svitkine | 8724ea50 | 2019-06-14 21:51:46 | [diff] [blame] | 25 | std::unique_ptr<base::FieldTrialList> field_trial_list; |
Josh Berenhaus | 0f3893f | 2023-11-08 00:57:33 | [diff] [blame] | 26 | if (!base::FieldTrialList::GetInstance()) { |
Steven Holte | a84bc22 | 2022-09-29 07:11:46 | [diff] [blame] | 27 | field_trial_list = std::make_unique<base::FieldTrialList>(); |
Josh Berenhaus | 0f3893f | 2023-11-08 00:57:33 | [diff] [blame] | 28 | } |
| 29 | |
Xi Han | 636c7ca5 | 2018-10-04 16:56:29 | [diff] [blame] | 30 | const base::CommandLine* command_line = |
| 31 | base::CommandLine::ForCurrentProcess(); |
| 32 | |
| 33 | // Ensure any field trials specified on the command line are initialized. |
| 34 | if (command_line->HasSwitch(::switches::kForceFieldTrials)) { |
| 35 | // Create field trials without activating them, so that this behaves in a |
| 36 | // consistent manner with field trials created from the server. |
| 37 | bool result = base::FieldTrialList::CreateTrialsFromString( |
Ilya Sherman | 7633f36 | 2020-06-23 21:54:41 | [diff] [blame] | 38 | command_line->GetSwitchValueASCII(::switches::kForceFieldTrials)); |
Xi Han | 636c7ca5 | 2018-10-04 16:56:29 | [diff] [blame] | 39 | CHECK(result) << "Invalid --" << ::switches::kForceFieldTrials |
| 40 | << " list specified."; |
| 41 | } |
| 42 | |
Gabriel Gauthier-Shalom | 89627a67a | 2023-11-29 22:11:19 | [diff] [blame] | 43 | base::FeatureList::InitInstance( |
Xi Han | 636c7ca5 | 2018-10-04 16:56:29 | [diff] [blame] | 44 | command_line->GetSwitchValueASCII(switches::kEnableFeatures), |
Lily Chen | d49e375 | 2019-08-09 19:05:24 | [diff] [blame] | 45 | command_line->GetSwitchValueASCII(switches::kDisableFeatures), |
| 46 | GetSwitchDependentFeatureOverrides(*command_line)); |
Xi Han | 636c7ca5 | 2018-10-04 16:56:29 | [diff] [blame] | 47 | return field_trial_list; |
| 48 | } |
| 49 | |
Ben Kelly | 874806f | 2020-05-08 14:12:47 | [diff] [blame] | 50 | namespace { |
Ben Kelly | 874806f | 2020-05-08 14:12:47 | [diff] [blame] | 51 | |
Minoru Chikamune | 1b266e3 | 2024-09-04 09:43:26 | [diff] [blame] | 52 | #if BUILDFLAG(IS_ANDROID) |
| 53 | // Mobile config, for iOS see ios/web/app/web_main_loop.cc. |
| 54 | constexpr size_t kThreadPoolDefaultMin = 6; |
| 55 | constexpr size_t kThreadPoolMax = 8; |
| 56 | constexpr double kThreadPoolCoresMultiplier = 0.6; |
| 57 | constexpr int kThreadPoolOffset = 0; |
| 58 | #else |
| 59 | // Desktop config. |
| 60 | constexpr size_t kThreadPoolDefaultMin = 16; |
| 61 | constexpr size_t kThreadPoolMax = 32; |
| 62 | constexpr double kThreadPoolCoresMultiplier = 0.6; |
| 63 | constexpr int kThreadPoolOffset = 0; |
| 64 | #endif |
| 65 | |
Daniel Cheng | 0abd9f3 | 2022-09-22 04:20:11 | [diff] [blame] | 66 | BASE_FEATURE(kBrowserThreadPoolAdjustment, |
| 67 | "BrowserThreadPoolAdjustment", |
Minoru Chikamune | 1b266e3 | 2024-09-04 09:43:26 | [diff] [blame] | 68 | base::FEATURE_DISABLED_BY_DEFAULT); |
Ben Kelly | 874806f | 2020-05-08 14:12:47 | [diff] [blame] | 69 | |
Minoru Chikamune | 1b266e3 | 2024-09-04 09:43:26 | [diff] [blame] | 70 | const base::FeatureParam<int> kBrowserThreadPoolMin{ |
| 71 | &kBrowserThreadPoolAdjustment, "min", kThreadPoolDefaultMin}; |
Minoru Chikamune | 1e34115 | 2023-09-04 10:20:44 | [diff] [blame] | 72 | |
Ben Kelly | 874806f | 2020-05-08 14:12:47 | [diff] [blame] | 73 | } // namespace |
| 74 | |
Francois Doray | 7f77731 | 2019-05-16 12:26:31 | [diff] [blame] | 75 | // TODO(scheduler-dev): Standardize thread pool logic and remove the need for |
| 76 | // specifying thread count manually. |
Gabriel Charette | 52fa3ae | 2019-04-15 21:44:37 | [diff] [blame] | 77 | void StartBrowserThreadPool() { |
Ben Kelly | 874806f | 2020-05-08 14:12:47 | [diff] [blame] | 78 | // Ensure we always support at least one thread regardless of the field trial |
| 79 | // param setting. |
Minoru Chikamune | 900c9ad | 2024-05-21 12:56:20 | [diff] [blame] | 80 | size_t min = |
Minoru Chikamune | 1b266e3 | 2024-09-04 09:43:26 | [diff] [blame] | 81 | base::checked_cast<size_t>(std::max(kBrowserThreadPoolMin.Get(), 1)); |
Gabriel Charette | 43fd370 | 2019-05-29 16:36:51 | [diff] [blame] | 82 | base::ThreadPoolInstance::InitParams thread_pool_init_params = { |
Ben Kelly | 874806f | 2020-05-08 14:12:47 | [diff] [blame] | 83 | base::RecommendedMaxNumberOfThreadsInThreadGroup( |
Minoru Chikamune | 1b266e3 | 2024-09-04 09:43:26 | [diff] [blame] | 84 | min, kThreadPoolMax, kThreadPoolCoresMultiplier, kThreadPoolOffset)}; |
Francois Doray | 7f77731 | 2019-05-16 12:26:31 | [diff] [blame] | 85 | |
Xiaohan Wang | 1ecfd00 | 2022-01-19 22:33:10 | [diff] [blame] | 86 | #if BUILDFLAG(IS_WIN) |
Gabriel Charette | 43fd370 | 2019-05-29 16:36:51 | [diff] [blame] | 87 | thread_pool_init_params.common_thread_pool_environment = base:: |
| 88 | ThreadPoolInstance::InitParams::CommonThreadPoolEnvironment::COM_MTA; |
Francois Doray | 7f77731 | 2019-05-16 12:26:31 | [diff] [blame] | 89 | #endif |
Xi Han | 8012e46 | 2018-10-05 19:52:30 | [diff] [blame] | 90 | |
| 91 | // If a renderer lives in the browser process, adjust the number of |
| 92 | // threads in the foreground pool. |
| 93 | if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 94 | switches::kSingleProcess)) { |
Francois Doray | 7f77731 | 2019-05-16 12:26:31 | [diff] [blame] | 95 | thread_pool_init_params.max_num_foreground_threads = |
| 96 | std::max(GetMinForegroundThreadsInRendererThreadPool(), |
| 97 | thread_pool_init_params.max_num_foreground_threads); |
Xi Han | 8012e46 | 2018-10-05 19:52:30 | [diff] [blame] | 98 | } |
| 99 | |
Gabriel Charette | 43fd370 | 2019-05-29 16:36:51 | [diff] [blame] | 100 | base::ThreadPoolInstance::Get()->Start(thread_pool_init_params); |
Xi Han | 8012e46 | 2018-10-05 19:52:30 | [diff] [blame] | 101 | } |
| 102 | |
Xi Han | 636c7ca5 | 2018-10-04 16:56:29 | [diff] [blame] | 103 | } // namespace content |