Commit 1e3963fb authored by fdoray's avatar fdoray Committed by Commit bot

Control TaskScheduler initialization params in renderers via field trial.

BUG=664996

Review-Url: https://codereview.chromium.org/2568793003
Cr-Commit-Position: refs/heads/master@{#442109}
parent 91f5b8d2
......@@ -150,6 +150,7 @@
#include "components/signin/core/common/profile_management_switches.h"
#include "components/spellcheck/spellcheck_build_features.h"
#include "components/startup_metric_utils/browser/startup_metric_host_impl.h"
#include "components/task_scheduler_util/common/variations_util.h"
#include "components/task_scheduler_util/initialization/browser_util.h"
#include "components/task_scheduler_util/variations/browser_variations_util.h"
#include "components/translate/core/common/translate_switches.h"
......@@ -1818,6 +1819,11 @@ void ChromeContentBrowserClient::AppendExtraCommandLineSwitches(
StackSamplingConfiguration::Get()->AppendCommandLineSwitchForChildProcess(
process_type,
command_line);
if (process_type == switches::kRendererProcess) {
task_scheduler_util::AddVariationParamsToCommandLine("Renderer",
command_line);
}
}
std::string ChromeContentBrowserClient::GetApplicationLocale() {
......
......@@ -111,6 +111,7 @@ static_library("renderer") {
"//components/spellcheck:build_features",
"//components/startup_metric_utils/common:interfaces",
"//components/subresource_filter/content/renderer",
"//components/task_scheduler_util/renderer",
"//components/translate/content/renderer",
"//components/translate/core/common",
"//components/translate/core/language_detection",
......
......@@ -31,6 +31,7 @@ include_rules = [
"+components/startup_metric_utils/common",
"+components/strings/grit",
"+components/subresource_filter/content/renderer",
"+components/task_scheduler_util/renderer",
"+components/translate/content/common",
"+components/translate/content/renderer",
"+components/translate/core/common",
......
......@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/debug/crash_logging.h"
#include "base/logging.h"
......@@ -80,6 +81,7 @@
#include "components/startup_metric_utils/common/startup_metric.mojom.h"
#include "components/subresource_filter/content/renderer/ruleset_dealer.h"
#include "components/subresource_filter/content/renderer/subresource_filter_agent.h"
#include "components/task_scheduler_util/renderer/initialization.h"
#include "components/version_info/version_info.h"
#include "components/visitedlink/renderer/visitedlink_slave.h"
#include "components/web_cache/renderer/web_cache_impl.h"
......@@ -1474,3 +1476,15 @@ GURL ChromeContentRendererClient::OverrideFlashEmbedWithHTML(const GURL& url) {
RecordYouTubeRewriteUMA(result);
return corrected_url.ReplaceComponents(r);
}
void ChromeContentRendererClient::GetTaskSchedulerInitializationParams(
std::vector<base::SchedulerWorkerPoolParams>* params_vector,
base::TaskScheduler::WorkerPoolIndexForTraitsCallback*
index_to_traits_callback) {
DCHECK(params_vector);
DCHECK(index_to_traits_callback);
// If this call fails, content will fall back to the default params.
*params_vector = task_scheduler_util::GetRendererWorkerPoolParams();
*index_to_traits_callback =
base::Bind(&task_scheduler_util::RendererWorkerPoolIndexForTraits);
}
......@@ -182,6 +182,10 @@ class ChromeContentRendererClient : public content::ContentRendererClient {
const GURL& url) override;
bool ShouldEnforceWebRTCRoutingPreferences() override;
GURL OverrideFlashEmbedWithHTML(const GURL& url) override;
void GetTaskSchedulerInitializationParams(
std::vector<base::SchedulerWorkerPoolParams>* params_vector,
base::TaskScheduler::WorkerPoolIndexForTraitsCallback*
index_to_traits_callback) override;
#if BUILDFLAG(ENABLE_SPELLCHECK)
// Sets a new |spellcheck|. Used for testing only.
......
......@@ -10,6 +10,7 @@ static_library("common") {
deps = [
"//base",
"//components/variations",
]
}
......@@ -21,6 +22,7 @@ source_set("unit_tests") {
deps = [
":common",
"//base",
"//components/variations",
"//testing/gtest",
]
}
include_rules = [
"+components/variations",
]
......@@ -4,12 +4,15 @@
#include "components/task_scheduler_util/common/variations_util.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/task_scheduler/initialization_util.h"
#include "base/time/time.h"
#include "components/variations/variations_associated_data.h"
namespace task_scheduler_util {
......@@ -21,6 +24,17 @@ struct SchedulerCustomizableWorkerPoolParams {
base::TimeDelta detach_period;
};
#if !defined(OS_IOS)
constexpr char kTaskSchedulerVariationParamsSwitch[] =
"task-scheduler-variation-params";
constexpr char kSeparator[] = "|";
bool ContainsSeparator(const std::string& str) {
return str.find(kSeparator) != std::string::npos;
}
#endif // !defined(OS_IOS)
// Converts |pool_descriptor| to a SchedulerWorkerPoolVariableParams. Returns a
// default SchedulerWorkerPoolVariableParams on failure.
//
......@@ -105,4 +119,57 @@ std::vector<base::SchedulerWorkerPoolParams> GetWorkerPoolParams(
return worker_pool_params_vector;
}
#if !defined(OS_IOS)
void AddVariationParamsToCommandLine(base::StringPiece key_prefix,
base::CommandLine* command_line) {
DCHECK(command_line);
std::map<std::string, std::string> variation_params;
if (!variations::GetVariationParams("BrowserScheduler", &variation_params))
return;
std::vector<std::string> parts;
for (const auto& key_value : variation_params) {
if (base::StartsWith(key_value.first, key_prefix,
base::CompareCase::SENSITIVE)) {
if (ContainsSeparator(key_value.first) ||
ContainsSeparator(key_value.second)) {
DLOG(ERROR)
<< "Unexpected Character in Task Scheduler Variation Params: "
<< key_value.first << " [" << key_value.second << "]";
return;
}
parts.push_back(key_value.first);
parts.push_back(key_value.second);
}
}
if (!parts.empty()) {
command_line->AppendSwitchASCII(kTaskSchedulerVariationParamsSwitch,
base::JoinString(parts, kSeparator));
}
}
std::map<std::string, std::string> GetVariationParamsFromCommandLine(
const base::CommandLine& command_line) {
const auto serialized_variation_params =
command_line.GetSwitchValueASCII(kTaskSchedulerVariationParamsSwitch);
const auto parts =
base::SplitStringPiece(serialized_variation_params, kSeparator,
base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
std::map<std::string, std::string> variation_params;
for (auto it = parts.begin(); it != parts.end(); ++it) {
base::StringPiece key = *it;
++it;
if (it == parts.end()) {
NOTREACHED();
return std::map<std::string, std::string>();
}
base::StringPiece value = *it;
variation_params[key.as_string()] = value.as_string();
}
return variation_params;
}
#endif // !defined(OS_IOS)
} // namespace task_scheduler_util
......@@ -9,9 +9,15 @@
#include <string>
#include <vector>
#include "build/build_config.h"
#include "base/strings/string_piece.h"
#include "base/task_scheduler/scheduler_worker_pool_params.h"
#include "base/threading/platform_thread.h"
namespace base {
class CommandLine;
}
namespace task_scheduler_util {
class SchedulerImmutableWorkerPoolParams {
......@@ -36,6 +42,19 @@ std::vector<base::SchedulerWorkerPoolParams> GetWorkerPoolParams(
constant_worker_pool_params_vector,
const std::map<std::string, std::string>& variation_params);
#if !defined(OS_IOS)
// Serializes variation params from the BrowserScheduler field trial whose key
// start with |prefix| to the --task-scheduler-variation-params switch of
// |command_line|.
void AddVariationParamsToCommandLine(base::StringPiece key_prefix,
base::CommandLine* command_line);
// Returns a map of key-value pairs deserialized from the
// --task-scheduler-variation-params switch of |command_line|.
std::map<std::string, std::string> GetVariationParamsFromCommandLine(
const base::CommandLine& command_line);
#endif // !defined(OS_IOS)
} // namespace task_scheduler_util
#endif // COMPONENTS_TASK_SCHEDULER_UTIL_COMMON_VARIATIONS_UTIL_H_
......@@ -8,8 +8,13 @@
#include <string>
#include <vector>
#include "build/build_config.h"
#include "base/command_line.h"
#include "base/macros.h"
#include "base/metrics/field_trial.h"
#include "base/task_scheduler/scheduler_worker_pool_params.h"
#include "base/threading/platform_thread.h"
#include "components/variations/variations_associated_data.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace task_scheduler_util {
......@@ -20,6 +25,13 @@ using StandbyThreadPolicy =
base::SchedulerWorkerPoolParams::StandbyThreadPolicy;
using ThreadPriority = base::ThreadPriority;
#if !defined(OS_IOS)
constexpr char kFieldTrialName[] = "BrowserScheduler";
constexpr char kFieldTrialTestGroup[] = "Test";
constexpr char kTaskSchedulerVariationParamsSwitch[] =
"task-scheduler-variation-params";
#endif // !defined(OS_IOS)
std::vector<SchedulerImmutableWorkerPoolParams> GetImmutableWorkerPoolParams() {
std::vector<SchedulerImmutableWorkerPoolParams> constant_worker_pool_params;
constant_worker_pool_params.emplace_back("Background",
......@@ -33,9 +45,25 @@ std::vector<SchedulerImmutableWorkerPoolParams> GetImmutableWorkerPoolParams() {
return constant_worker_pool_params;
}
class TaskSchedulerUtilVariationsUtilTest : public testing::Test {
public:
TaskSchedulerUtilVariationsUtilTest() : field_trial_list_(nullptr) {}
~TaskSchedulerUtilVariationsUtilTest() override {
// Ensure that the maps are cleared between tests, since they are stored as
// process singletons.
variations::testing::ClearAllVariationIDs();
variations::testing::ClearAllVariationParams();
}
private:
base::FieldTrialList field_trial_list_;
DISALLOW_COPY_AND_ASSIGN(TaskSchedulerUtilVariationsUtilTest);
};
} // namespace
TEST(TaskSchedulerUtilVariationsUtilTest, OrderingParams5) {
TEST_F(TaskSchedulerUtilVariationsUtilTest, OrderingParams5) {
std::map<std::string, std::string> variation_params;
variation_params["Background"] = "1;1;1;0;42";
variation_params["BackgroundFileIO"] = "2;2;1;0;52";
......@@ -75,7 +103,7 @@ TEST(TaskSchedulerUtilVariationsUtilTest, OrderingParams5) {
params_vector[3].suggested_reclaim_time());
}
TEST(TaskSchedulerUtilVariationsUtilTest, OrderingParams6) {
TEST_F(TaskSchedulerUtilVariationsUtilTest, OrderingParams6) {
std::map<std::string, std::string> variation_params;
variation_params["Background"] = "1;1;1;0;42;lazy";
variation_params["BackgroundFileIO"] = "2;2;1;0;52;one";
......@@ -117,13 +145,13 @@ TEST(TaskSchedulerUtilVariationsUtilTest, OrderingParams6) {
params_vector[3].suggested_reclaim_time());
}
TEST(TaskSchedulerUtilVariationsUtilTest, NoData) {
TEST_F(TaskSchedulerUtilVariationsUtilTest, NoData) {
EXPECT_TRUE(GetWorkerPoolParams(GetImmutableWorkerPoolParams(),
std::map<std::string, std::string>())
.empty());
}
TEST(TaskSchedulerUtilVariationsUtilTest, IncompleteParameters) {
TEST_F(TaskSchedulerUtilVariationsUtilTest, IncompleteParameters) {
std::map<std::string, std::string> variation_params;
variation_params["Background"] = "1;1;1;0";
variation_params["BackgroundFileIO"] = "2;2;1;0";
......@@ -134,7 +162,7 @@ TEST(TaskSchedulerUtilVariationsUtilTest, IncompleteParameters) {
.empty());
}
TEST(TaskSchedulerUtilVariationsUtilTest, InvalidParameters) {
TEST_F(TaskSchedulerUtilVariationsUtilTest, InvalidParameters) {
std::map<std::string, std::string> variation_params;
variation_params["Background"] = "a;b;c;d;e";
variation_params["BackgroundFileIO"] = "a;b;c;d;e";
......@@ -145,4 +173,76 @@ TEST(TaskSchedulerUtilVariationsUtilTest, InvalidParameters) {
.empty());
}
#if !defined(OS_IOS)
// Verify that AddVariationParamsToCommandLine() serializes BrowserScheduler
// variation params that start with the specified prefix to the command line and
// that GetVariationParamsFromCommandLine() correctly deserializes them.
TEST_F(TaskSchedulerUtilVariationsUtilTest, CommandLine) {
std::map<std::string, std::string> in_variation_params;
in_variation_params["PrefixFoo"] = "Foo";
in_variation_params["PrefixBar"] = "Bar";
in_variation_params["NoPrefix"] = "NoPrefix";
ASSERT_TRUE(variations::AssociateVariationParams(
kFieldTrialName, kFieldTrialTestGroup, in_variation_params));
base::FieldTrialList::CreateFieldTrial(kFieldTrialName, kFieldTrialTestGroup);
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
AddVariationParamsToCommandLine("Prefix", &command_line);
const std::map<std::string, std::string> out_variation_params =
GetVariationParamsFromCommandLine(command_line);
std::map<std::string, std::string> expected_out_variation_params;
expected_out_variation_params["PrefixFoo"] = "Foo";
expected_out_variation_params["PrefixBar"] = "Bar";
EXPECT_EQ(expected_out_variation_params, out_variation_params);
}
// Verify that AddVariationParamsToCommandLine() doesn't add anything to the
// command line when a BrowserScheduler variation param key contains |. A key
// that contains | wouldn't be deserialized correctly by
// GetVariationParamsFromCommandLine().
TEST_F(TaskSchedulerUtilVariationsUtilTest,
CommandLineSeparatorInVariationParamsKey) {
std::map<std::string, std::string> in_variation_params;
in_variation_params["PrefixFoo"] = "Foo";
in_variation_params["PrefixKey|"] = "Value";
ASSERT_TRUE(variations::AssociateVariationParams(
kFieldTrialName, kFieldTrialTestGroup, in_variation_params));
base::FieldTrialList::CreateFieldTrial(kFieldTrialName, kFieldTrialTestGroup);
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
AddVariationParamsToCommandLine("Prefix", &command_line);
EXPECT_TRUE(
command_line.GetSwitchValueASCII(kTaskSchedulerVariationParamsSwitch)
.empty());
}
// Verify that AddVariationParamsToCommandLine() doesn't add anything to the
// command line when a BrowserScheduler variation param value contains |. A
// value that contains | wouldn't be deserialized correctly by
// GetVariationParamsFromCommandLine().
TEST_F(TaskSchedulerUtilVariationsUtilTest,
CommandLineSeparatorInVariationParamsValue) {
std::map<std::string, std::string> in_variation_params;
in_variation_params["PrefixFoo"] = "Foo";
in_variation_params["PrefixKey"] = "Value|";
ASSERT_TRUE(variations::AssociateVariationParams(
kFieldTrialName, kFieldTrialTestGroup, in_variation_params));
base::FieldTrialList::CreateFieldTrial(kFieldTrialName, kFieldTrialTestGroup);
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
AddVariationParamsToCommandLine("Prefix", &command_line);
EXPECT_TRUE(
command_line.GetSwitchValueASCII(kTaskSchedulerVariationParamsSwitch)
.empty());
}
// Verify that GetVariationParamsFromCommandLine() returns an empty map when the
// command line doesn't have a --task-scheduler-variation-params switch.
TEST_F(TaskSchedulerUtilVariationsUtilTest, CommandLineNoSwitch) {
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
EXPECT_TRUE(GetVariationParamsFromCommandLine(command_line).empty());
}
#endif // !defined(OS_IOS)
} // namespace task_scheduler_util
# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
if (!is_ios) {
static_library("renderer") {
sources = [
"initialization.cc",
"initialization.h",
]
deps = [
"//base",
"//components/task_scheduler_util/common",
]
}
}
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/task_scheduler_util/renderer/initialization.h"
#include <map>
#include <string>
#include "base/command_line.h"
#include "base/logging.h"
#include "base/task_scheduler/task_traits.h"
#include "base/threading/platform_thread.h"
#include "components/task_scheduler_util/common/variations_util.h"
namespace task_scheduler_util {
namespace {
enum WorkerPoolType : size_t {
BACKGROUND = 0,
BACKGROUND_BLOCKING,
FOREGROUND,
FOREGROUND_BLOCKING,
WORKER_POOL_COUNT // Always last.
};
} // namespace
std::vector<base::SchedulerWorkerPoolParams> GetRendererWorkerPoolParams() {
using ThreadPriority = base::ThreadPriority;
std::vector<SchedulerImmutableWorkerPoolParams> immutable_worker_pool_params;
DCHECK_EQ(BACKGROUND, immutable_worker_pool_params.size());
immutable_worker_pool_params.emplace_back("RendererBackground",
ThreadPriority::BACKGROUND);
DCHECK_EQ(BACKGROUND_BLOCKING, immutable_worker_pool_params.size());
immutable_worker_pool_params.emplace_back("RendererBackgroundBlocking",
ThreadPriority::BACKGROUND);
DCHECK_EQ(FOREGROUND, immutable_worker_pool_params.size());
immutable_worker_pool_params.emplace_back("RendererForeground",
ThreadPriority::NORMAL);
DCHECK_EQ(FOREGROUND_BLOCKING, immutable_worker_pool_params.size());
immutable_worker_pool_params.emplace_back("RendererForegroundBlocking",
ThreadPriority::NORMAL);
return GetWorkerPoolParams(immutable_worker_pool_params,
GetVariationParamsFromCommandLine(
*base::CommandLine::ForCurrentProcess()));
}
size_t RendererWorkerPoolIndexForTraits(const base::TaskTraits& traits) {
const bool is_background =
traits.priority() == base::TaskPriority::BACKGROUND;
if (traits.may_block() || traits.with_base_sync_primitives())
return is_background ? BACKGROUND_BLOCKING : FOREGROUND_BLOCKING;
return is_background ? BACKGROUND : FOREGROUND;
}
} // namespace task_scheduler_util
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_TASK_SCHEDULER_UTIL_RENDERER_INITIALIZATION_H_
#define COMPONENTS_TASK_SCHEDULER_UTIL_RENDERER_INITIALIZATION_H_
#include <stddef.h>
#include <vector>
#include "base/task_scheduler/scheduler_worker_pool_params.h"
namespace base {
class TaskTraits;
}
namespace task_scheduler_util {
// Gets a vector of SchedulerWorkerPoolParams to initialize TaskScheduler in a
// renderer based off variation params specified on the command line. Returns an
// empty vector if variation params specified on the command line are incomplete
// or invalid.
std::vector<base::SchedulerWorkerPoolParams> GetRendererWorkerPoolParams();
// Maps |traits| to the index of a renderer worker pool vector provided by
// GetRendererWorkerPoolParams().
size_t RendererWorkerPoolIndexForTraits(const base::TaskTraits& traits);
} // namespace task_scheduler_util
#endif // COMPONENTS_TASK_SCHEDULER_UTIL_RENDERER_INITIALIZATION_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment