Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/browser/chrome_browser_main.h" | 5 #include "chrome/browser/chrome_browser_main.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | |
| 11 #include <map> | |
| 10 #include <set> | 12 #include <set> |
| 11 #include <string> | 13 #include <string> |
| 12 #include <utility> | 14 #include <utility> |
| 13 #include <vector> | 15 #include <vector> |
| 14 | 16 |
| 15 #include "base/at_exit.h" | 17 #include "base/at_exit.h" |
| 16 #include "base/base_switches.h" | 18 #include "base/base_switches.h" |
| 17 #include "base/bind.h" | 19 #include "base/bind.h" |
| 18 #include "base/command_line.h" | 20 #include "base/command_line.h" |
| 19 #include "base/debug/crash_logging.h" | 21 #include "base/debug/crash_logging.h" |
| 20 #include "base/debug/debugger.h" | 22 #include "base/debug/debugger.h" |
| 21 #include "base/feature_list.h" | 23 #include "base/feature_list.h" |
| 22 #include "base/files/file_path.h" | 24 #include "base/files/file_path.h" |
| 23 #include "base/files/file_util.h" | 25 #include "base/files/file_util.h" |
| 26 #include "base/logging.h" | |
| 24 #include "base/memory/ptr_util.h" | 27 #include "base/memory/ptr_util.h" |
| 25 #include "base/metrics/field_trial.h" | 28 #include "base/metrics/field_trial.h" |
| 26 #include "base/metrics/histogram_macros.h" | 29 #include "base/metrics/histogram_macros.h" |
| 27 #include "base/path_service.h" | 30 #include "base/path_service.h" |
| 28 #include "base/profiler/scoped_tracker.h" | 31 #include "base/profiler/scoped_tracker.h" |
| 29 #include "base/run_loop.h" | 32 #include "base/run_loop.h" |
| 30 #include "base/strings/string_number_conversions.h" | 33 #include "base/strings/string_number_conversions.h" |
| 31 #include "base/strings/string_piece.h" | 34 #include "base/strings/string_piece.h" |
| 32 #include "base/strings/string_split.h" | 35 #include "base/strings/string_split.h" |
| 33 #include "base/strings/sys_string_conversions.h" | 36 #include "base/strings/sys_string_conversions.h" |
| 34 #include "base/strings/utf_string_conversions.h" | 37 #include "base/strings/utf_string_conversions.h" |
| 35 #include "base/sys_info.h" | 38 #include "base/sys_info.h" |
| 39 #include "base/task_scheduler/scheduler_worker_pool_params.h" | |
| 40 #include "base/task_scheduler/task_scheduler.h" | |
| 41 #include "base/task_scheduler/task_traits.h" | |
| 36 #include "base/threading/platform_thread.h" | 42 #include "base/threading/platform_thread.h" |
| 37 #include "base/time/default_tick_clock.h" | 43 #include "base/time/default_tick_clock.h" |
| 38 #include "base/time/time.h" | 44 #include "base/time/time.h" |
| 39 #include "base/trace_event/trace_event.h" | 45 #include "base/trace_event/trace_event.h" |
| 40 #include "base/values.h" | 46 #include "base/values.h" |
| 41 #include "build/build_config.h" | 47 #include "build/build_config.h" |
| 42 #include "cc/base/switches.h" | 48 #include "cc/base/switches.h" |
| 43 #include "chrome/browser/about_flags.h" | 49 #include "chrome/browser/about_flags.h" |
| 44 #include "chrome/browser/after_startup_task_utils.h" | 50 #include "chrome/browser/after_startup_task_utils.h" |
| 45 #include "chrome/browser/browser_process.h" | 51 #include "chrome/browser/browser_process.h" |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 310 void AddFirstRunNewTabs(StartupBrowserCreator* browser_creator, | 316 void AddFirstRunNewTabs(StartupBrowserCreator* browser_creator, |
| 311 const std::vector<GURL>& new_tabs) { | 317 const std::vector<GURL>& new_tabs) { |
| 312 for (std::vector<GURL>::const_iterator it = new_tabs.begin(); | 318 for (std::vector<GURL>::const_iterator it = new_tabs.begin(); |
| 313 it != new_tabs.end(); ++it) { | 319 it != new_tabs.end(); ++it) { |
| 314 if (it->is_valid()) | 320 if (it->is_valid()) |
| 315 browser_creator->AddFirstRunTab(*it); | 321 browser_creator->AddFirstRunTab(*it); |
| 316 } | 322 } |
| 317 } | 323 } |
| 318 #endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS) | 324 #endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS) |
| 319 | 325 |
| 326 enum WorkerPoolType : size_t { | |
| 327 BACKGROUND_WORKER_POOL = 0, | |
| 328 BACKGROUND_FILE_IO_WORKER_POOL, | |
| 329 FOREGROUND_WORKER_POOL, | |
| 330 FOREGROUND_FILE_IO_WORKER_POOL, | |
| 331 WORKER_POOL_COUNT, | |
| 332 }; | |
| 333 | |
| 334 struct WorkerPoolVariationValues { | |
| 335 int threads = 0; | |
| 336 base::TimeDelta detach_period; | |
| 337 }; | |
| 338 | |
| 339 // Converts |pool_descriptor| to a WorkerPoolVariationValues. Returns a default | |
| 340 // WorkerPoolVariationValues on failure. | |
| 341 // | |
| 342 // |pool_descriptor| is a comma separated value string with the following items: | |
| 343 // 1. Minimum Thread Count (int) | |
| 344 // 2. Maximum Thread Count (int) | |
| 345 // 3. Thread Count Multiplier (double) | |
| 346 // 4. Thread Count Offset (int) | |
| 347 // 5. Detach Time in Milliseconds (milliseconds) | |
| 348 // Additional values may appear as necessary and will be ignored. | |
| 349 WorkerPoolVariationValues StringToWorkerPoolVariationValues( | |
| 350 const base::StringPiece& pool_descriptor) { | |
| 351 const std::vector<std::string> tokens = | |
| 352 SplitString(pool_descriptor, ",", | |
| 353 base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); | |
| 354 int minimum; | |
| 355 int maximum; | |
| 356 double multiplier; | |
| 357 int offset; | |
| 358 int detach_milliseconds; | |
| 359 // Checking for a size greater than the expected amount allows us to be | |
| 360 // forward compatible if we add more variation values. | |
| 361 if (tokens.size() >= 5 && | |
| 362 base::StringToInt(tokens[0], &minimum) && | |
| 363 base::StringToInt(tokens[1], &maximum) && | |
| 364 base::StringToDouble(tokens[2], &multiplier) && | |
| 365 base::StringToInt(tokens[3], &offset) && | |
| 366 base::StringToInt(tokens[4], &detach_milliseconds)) { | |
| 367 const int num_of_cores = base::SysInfo::NumberOfProcessors(); | |
| 368 const int threads = std::round<int>(num_of_cores * multiplier) + offset; | |
| 369 WorkerPoolVariationValues values; | |
| 370 values.threads = std::min(maximum, std::max(minimum, threads)); | |
| 371 values.detach_period = | |
| 372 base::TimeDelta::FromMilliseconds(detach_milliseconds); | |
| 373 return values; | |
| 374 } | |
| 375 LOG(WARNING) << "Invalid Worker Pool Descriptor: " << pool_descriptor; | |
| 376 return WorkerPoolVariationValues(); | |
| 377 } | |
| 378 | |
| 379 // Returns the worker pool index for |traits| defaulting to | |
| 380 // FOREGROUND_WORKER_POOL or FOREGROUND_FILE_IO_WORKER_POOL on unknown | |
| 381 // priorities. | |
| 382 size_t WorkerPoolIndexForTraits(const base::TaskTraits& traits) { | |
| 383 if (traits.with_file_io()) { | |
| 384 return traits.priority() == base::TaskPriority::BACKGROUND | |
| 385 ? BACKGROUND_FILE_IO_WORKER_POOL | |
| 386 : FOREGROUND_FILE_IO_WORKER_POOL; | |
| 387 } | |
| 388 return traits.priority() == base::TaskPriority::BACKGROUND | |
| 389 ? BACKGROUND_WORKER_POOL | |
| 390 : FOREGROUND_WORKER_POOL; | |
| 391 } | |
| 392 | |
| 393 // Initializes the Default Browser Task Scheduler if there is a valid variation | |
| 394 // parameter for the field trial. | |
| 395 void MaybeInitializeTaskScheduler() { | |
| 396 static constexpr char kFieldTrialName[] = "BrowserScheduler"; | |
| 397 std::map<std::string, std::string> variation_params; | |
| 398 if (!variations::GetVariationParams(kFieldTrialName, &variation_params)) | |
| 399 return; | |
| 400 | |
| 401 // Order matches WorkerPoolType above. | |
| 402 static const char* kWorkerPoolNames[] = { | |
| 403 "Background", | |
| 404 "BackgroundFileIO", | |
| 405 "Foreground", | |
| 406 "ForegroundFileIO", | |
| 407 }; | |
| 408 static_assert(arraysize(kWorkerPoolNames) == WORKER_POOL_COUNT, | |
|
fdoray
2016/08/05 22:59:12
What do you think of this?
struct SchedulerWorker
robliao
2016/08/05 23:45:38
Went one further and just used a static const stru
| |
| 409 "Mismatched Worker Pool Types and Names"); | |
| 410 | |
| 411 std::vector<WorkerPoolVariationValues> values; | |
| 412 for (size_t i = 0; i < arraysize(kWorkerPoolNames); i++) { | |
|
fdoray
2016/08/05 22:59:12
for (const char* worker_pool_name : kWorkerPoolNam
robliao
2016/08/05 23:45:38
Done.
| |
| 413 const char* current = kWorkerPoolNames[i]; | |
| 414 const auto pair = variation_params.find(current); | |
| 415 if (pair == variation_params.end()) { | |
| 416 LOG(WARNING) << "Missing Worker Pool Configuration: " << current; | |
| 417 return; | |
| 418 } | |
| 419 | |
| 420 const WorkerPoolVariationValues variation_value = | |
| 421 StringToWorkerPoolVariationValues(pair->second); | |
| 422 | |
| 423 if (variation_value.threads == 0 || | |
| 424 variation_value.detach_period.is_zero()) { | |
| 425 LOG(WARNING) << "Invalid Worker Pool Configuration: " << current << | |
| 426 " [" << pair->second << "]"; | |
| 427 return; | |
| 428 } | |
| 429 | |
| 430 values.push_back(variation_value); | |
| 431 } | |
| 432 | |
| 433 DCHECK_EQ(values.size(), WORKER_POOL_COUNT); | |
| 434 | |
| 435 using ThreadPriority = base::ThreadPriority; | |
| 436 using IORestriction = base::SchedulerWorkerPoolParams::IORestriction; | |
| 437 std::vector<base::SchedulerWorkerPoolParams> params_vector; | |
| 438 DCHECK_EQ(params_vector.size(), BACKGROUND_WORKER_POOL); | |
| 439 params_vector.emplace_back( | |
| 440 kWorkerPoolNames[BACKGROUND_WORKER_POOL], | |
| 441 ThreadPriority::BACKGROUND, | |
| 442 IORestriction::DISALLOWED, | |
| 443 values[BACKGROUND_WORKER_POOL].threads, | |
| 444 values[BACKGROUND_WORKER_POOL].detach_period); | |
| 445 | |
| 446 DCHECK_EQ(params_vector.size(), BACKGROUND_FILE_IO_WORKER_POOL); | |
| 447 params_vector.emplace_back( | |
| 448 kWorkerPoolNames[BACKGROUND_FILE_IO_WORKER_POOL], | |
| 449 ThreadPriority::BACKGROUND, | |
| 450 IORestriction::ALLOWED, | |
| 451 values[BACKGROUND_FILE_IO_WORKER_POOL].threads, | |
| 452 values[BACKGROUND_FILE_IO_WORKER_POOL].detach_period); | |
| 453 | |
| 454 DCHECK_EQ(params_vector.size(), FOREGROUND_WORKER_POOL); | |
| 455 params_vector.emplace_back( | |
| 456 kWorkerPoolNames[FOREGROUND_WORKER_POOL], | |
| 457 ThreadPriority::NORMAL, | |
| 458 IORestriction::DISALLOWED, | |
| 459 values[FOREGROUND_WORKER_POOL].threads, | |
| 460 values[FOREGROUND_WORKER_POOL].detach_period); | |
| 461 | |
| 462 DCHECK_EQ(params_vector.size(), FOREGROUND_FILE_IO_WORKER_POOL); | |
| 463 params_vector.emplace_back( | |
| 464 kWorkerPoolNames[FOREGROUND_FILE_IO_WORKER_POOL], | |
| 465 ThreadPriority::NORMAL, | |
| 466 IORestriction::ALLOWED, | |
| 467 values[FOREGROUND_FILE_IO_WORKER_POOL].threads, | |
| 468 values[FOREGROUND_FILE_IO_WORKER_POOL].detach_period); | |
| 469 | |
| 470 DCHECK_EQ(params_vector.size(), WORKER_POOL_COUNT); | |
| 471 | |
| 472 base::TaskScheduler::CreateAndSetDefaultTaskScheduler( | |
| 473 params_vector, base::Bind(WorkerPoolIndexForTraits)); | |
| 474 } | |
| 475 | |
| 320 // Returns the new local state object, guaranteed non-NULL. | 476 // Returns the new local state object, guaranteed non-NULL. |
| 321 // |local_state_task_runner| must be a shutdown-blocking task runner. | 477 // |local_state_task_runner| must be a shutdown-blocking task runner. |
| 322 PrefService* InitializeLocalState( | 478 PrefService* InitializeLocalState( |
| 323 base::SequencedTaskRunner* local_state_task_runner, | 479 base::SequencedTaskRunner* local_state_task_runner, |
| 324 const base::CommandLine& parsed_command_line) { | 480 const base::CommandLine& parsed_command_line) { |
| 325 TRACE_EVENT0("startup", "ChromeBrowserMainParts::InitializeLocalState") | 481 TRACE_EVENT0("startup", "ChromeBrowserMainParts::InitializeLocalState") |
| 326 | 482 |
| 327 // Load local state. This includes the application locale so we know which | 483 // Load local state. This includes the application locale so we know which |
| 328 // locale dll to load. This also causes local state prefs to be registered. | 484 // locale dll to load. This also causes local state prefs to be registered. |
| 329 PrefService* local_state = g_browser_process->local_state(); | 485 PrefService* local_state = g_browser_process->local_state(); |
| (...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1207 chromeos::CrosSettings::Initialize(); | 1363 chromeos::CrosSettings::Initialize(); |
| 1208 #endif // defined(OS_CHROMEOS) | 1364 #endif // defined(OS_CHROMEOS) |
| 1209 | 1365 |
| 1210 SetupOriginTrialsCommandLine(); | 1366 SetupOriginTrialsCommandLine(); |
| 1211 | 1367 |
| 1212 // Now the command line has been mutated based on about:flags, we can setup | 1368 // Now the command line has been mutated based on about:flags, we can setup |
| 1213 // metrics and initialize field trials. The field trials are needed by | 1369 // metrics and initialize field trials. The field trials are needed by |
| 1214 // IOThread's initialization which happens in BrowserProcess:PreCreateThreads. | 1370 // IOThread's initialization which happens in BrowserProcess:PreCreateThreads. |
| 1215 SetupMetricsAndFieldTrials(); | 1371 SetupMetricsAndFieldTrials(); |
| 1216 | 1372 |
| 1373 MaybeInitializeTaskScheduler(); | |
| 1374 | |
| 1217 // ChromeOS needs ResourceBundle::InitSharedInstance to be called before this. | 1375 // ChromeOS needs ResourceBundle::InitSharedInstance to be called before this. |
| 1218 browser_process_->PreCreateThreads(); | 1376 browser_process_->PreCreateThreads(); |
| 1219 | 1377 |
| 1220 device::GeolocationProvider::SetGeolocationDelegate( | 1378 device::GeolocationProvider::SetGeolocationDelegate( |
| 1221 new ChromeGeolocationDelegate()); | 1379 new ChromeGeolocationDelegate()); |
| 1222 | 1380 |
| 1223 return content::RESULT_CODE_NORMAL_EXIT; | 1381 return content::RESULT_CODE_NORMAL_EXIT; |
| 1224 } | 1382 } |
| 1225 | 1383 |
| 1226 void ChromeBrowserMainParts::PreMainMessageLoopRun() { | 1384 void ChromeBrowserMainParts::PreMainMessageLoopRun() { |
| (...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2068 chromeos::CrosSettings::Shutdown(); | 2226 chromeos::CrosSettings::Shutdown(); |
| 2069 #endif // defined(OS_CHROMEOS) | 2227 #endif // defined(OS_CHROMEOS) |
| 2070 #endif // defined(OS_ANDROID) | 2228 #endif // defined(OS_ANDROID) |
| 2071 } | 2229 } |
| 2072 | 2230 |
| 2073 // Public members: | 2231 // Public members: |
| 2074 | 2232 |
| 2075 void ChromeBrowserMainParts::AddParts(ChromeBrowserMainExtraParts* parts) { | 2233 void ChromeBrowserMainParts::AddParts(ChromeBrowserMainExtraParts* parts) { |
| 2076 chrome_extra_parts_.push_back(parts); | 2234 chrome_extra_parts_.push_back(parts); |
| 2077 } | 2235 } |
| OLD | NEW |