Initialize TaskScheduler in renderers.
This CL initializes TaskScheduler in renderers using
default arguments. ContentRenderClient may provide
different arguments.
Initially, no threads will be created by TaskScheduler
in renderers because no tasks are posted to it and
pools are initialized with StandbyThreadPolicy::LAZY.
In a separate, we will start running v8 tasks in
TaskScheduler rather than WorkerPool
(https://cs.chromium.org/chromium/src/gin/v8_platform.cc?sq=package:chromium&l=70&dr=C).
BUG=664996
Review-Url: https://codereview.chromium.org/2491823005
Cr-Commit-Position: refs/heads/master@{#438202}
diff --git a/content/renderer/render_process_impl.cc b/content/renderer/render_process_impl.cc
index 0ad4d1b..20f71e1ed 100644
--- a/content/renderer/render_process_impl.cc
+++ b/content/renderer/render_process_impl.cc
@@ -12,11 +12,23 @@
#include <mlang.h>
#endif
+#include <stddef.h>
+
+#include <vector>
+
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/feature_list.h"
#include "base/sys_info.h"
+#include "base/task_scheduler/initialization_util.h"
+#include "base/task_scheduler/scheduler_worker_pool_params.h"
+#include "base/task_scheduler/task_scheduler.h"
+#include "base/task_scheduler/task_traits.h"
+#include "base/threading/platform_thread.h"
+#include "base/time/time.h"
#include "content/child/site_isolation_stats_gatherer.h"
+#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/renderer/content_renderer_client.h"
@@ -25,6 +37,14 @@
namespace {
+enum WorkerPoolType : size_t {
+ BACKGROUND = 0,
+ BACKGROUND_FILE_IO,
+ FOREGROUND,
+ FOREGROUND_FILE_IO,
+ WORKER_POOL_COUNT // Always last.
+};
+
const base::Feature kV8_ES2015_TailCalls_Feature {
"V8_ES2015_TailCalls", base::FEATURE_DISABLED_BY_DEFAULT
};
@@ -50,6 +70,84 @@
}
}
+std::vector<base::SchedulerWorkerPoolParams>
+GetDefaultSchedulerWorkerPoolParams() {
+ using StandbyThreadPolicy =
+ base::SchedulerWorkerPoolParams::StandbyThreadPolicy;
+ using ThreadPriority = base::ThreadPriority;
+ constexpr size_t kMaxNumThreadsInBackgroundPool = 1;
+ constexpr size_t kMaxNumThreadsInBackgroundFileIOPool = 1;
+ constexpr int kMaxNumThreadsInForegroundPoolLowerBound = 2;
+ constexpr int kMaxNumThreadsInForegroundPoolUpperBound = 4;
+ constexpr double kMaxNumThreadsInForegroundPoolCoresMultiplier = 1;
+ constexpr int kMaxNumThreadsInForegroundPoolOffset = 0;
+ constexpr size_t kMaxNumThreadsInForegroundFileIOPool = 1;
+ constexpr auto kSuggestedReclaimTime = base::TimeDelta::FromSeconds(30);
+
+ std::vector<base::SchedulerWorkerPoolParams> params_vector;
+ params_vector.emplace_back("RendererBackground", ThreadPriority::BACKGROUND,
+ StandbyThreadPolicy::LAZY,
+ kMaxNumThreadsInBackgroundPool,
+ kSuggestedReclaimTime);
+ params_vector.emplace_back(
+ "RendererBackgroundFileIO", ThreadPriority::BACKGROUND,
+ StandbyThreadPolicy::LAZY, kMaxNumThreadsInBackgroundFileIOPool,
+ kSuggestedReclaimTime);
+ params_vector.emplace_back("RendererForeground", ThreadPriority::NORMAL,
+ StandbyThreadPolicy::LAZY,
+ base::RecommendedMaxNumberOfThreadsInPool(
+ kMaxNumThreadsInForegroundPoolLowerBound,
+ kMaxNumThreadsInForegroundPoolUpperBound,
+ kMaxNumThreadsInForegroundPoolCoresMultiplier,
+ kMaxNumThreadsInForegroundPoolOffset),
+ kSuggestedReclaimTime);
+ params_vector.emplace_back("RendererForegroundFileIO", ThreadPriority::NORMAL,
+ StandbyThreadPolicy::LAZY,
+ kMaxNumThreadsInForegroundFileIOPool,
+ kSuggestedReclaimTime);
+ DCHECK_EQ(WORKER_POOL_COUNT, params_vector.size());
+ return params_vector;
+}
+
+// Returns the worker pool index for |traits| defaulting to FOREGROUND or
+// FOREGROUND_FILE_IO on any other priorities based off of worker pools defined
+// in GetDefaultSchedulerWorkerPoolParams().
+size_t DefaultRendererWorkerPoolIndexForTraits(const base::TaskTraits& traits) {
+ const bool is_background =
+ traits.priority() == base::TaskPriority::BACKGROUND;
+ if (traits.with_file_io())
+ return is_background ? BACKGROUND_FILE_IO : FOREGROUND_FILE_IO;
+
+ return is_background ? BACKGROUND : FOREGROUND;
+}
+
+void InitializeTaskScheduler() {
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSingleProcess)) {
+ // There should already be a TaskScheduler when the renderer runs inside the
+ // browser process.
+ DCHECK(base::TaskScheduler::GetInstance());
+ return;
+ }
+ DCHECK(!base::TaskScheduler::GetInstance());
+
+ std::vector<base::SchedulerWorkerPoolParams> params_vector;
+ base::TaskScheduler::WorkerPoolIndexForTraitsCallback
+ index_to_traits_callback;
+ content::GetContentClient()->renderer()->GetTaskSchedulerInitializationParams(
+ ¶ms_vector, &index_to_traits_callback);
+
+ if (params_vector.empty()) {
+ params_vector = GetDefaultSchedulerWorkerPoolParams();
+ index_to_traits_callback =
+ base::Bind(&DefaultRendererWorkerPoolIndexForTraits);
+ }
+ DCHECK(index_to_traits_callback);
+
+ base::TaskScheduler::CreateAndSetDefaultTaskScheduler(
+ params_vector, index_to_traits_callback);
+}
+
} // namespace
namespace content {
@@ -103,6 +201,8 @@
SiteIsolationStatsGatherer::SetEnabled(
GetContentClient()->renderer()->ShouldGatherSiteIsolationStats());
+
+ InitializeTaskScheduler();
}
RenderProcessImpl::~RenderProcessImpl() {
@@ -112,6 +212,12 @@
DLOG(ERROR) << "WebFrame LEAKED " << count << " TIMES";
#endif
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSingleProcess)) {
+ DCHECK(base::TaskScheduler::GetInstance());
+ base::TaskScheduler::GetInstance()->Shutdown();
+ }
+
GetShutDownEvent()->Signal();
}