Commit 37e79479 authored by fdoray's avatar fdoray Committed by Commit bot

Test SequencedWorkerPool with redirection to the TaskScheduler.

This CL makes most SequencedWorkerPoolTest a TestWithParam. The parameter
controls whether redirection to TaskScheduler is enabled.

BUG=622400

Review-Url: https://codereview.chromium.org/2285633003
Cr-Commit-Position: refs/heads/master@{#419322}
parent 10118bff
...@@ -54,12 +54,16 @@ namespace base { ...@@ -54,12 +54,16 @@ namespace base {
namespace { namespace {
// An enum representing the state of all pools. Any given process should only // An enum representing the state of all pools. Any given non-test process
// ever transition from NONE_ACTIVE to the active states, transitions between // should only ever transition from NONE_ACTIVE to one of the active states.
// actives states are unexpected. The REDIRECTED_TO_TASK_SCHEDULER transition // Transitions between actives states are unexpected. The
// occurs when RedirectSequencedWorkerPoolsToTaskSchedulerForProcess() is called // REDIRECTED_TO_TASK_SCHEDULER transition occurs when
// and the WORKER_CREATED transition occurs when a Worker needs to be created // RedirectToTaskSchedulerForProcess() is called. The WORKER_CREATED transition
// because the first task was posted and the state is still NONE_ACTIVE. // occurs when a Worker needs to be created because the first task was posted
// and the state is still NONE_ACTIVE. In a test process, a transition to
// NONE_ACTIVE occurs when ResetRedirectToTaskSchedulerForProcessForTesting() is
// called.
//
// |g_all_pools_state| uses relaxed atomic operations to ensure no data race // |g_all_pools_state| uses relaxed atomic operations to ensure no data race
// between reads/writes, strict memory ordering isn't required per no other // between reads/writes, strict memory ordering isn't required per no other
// state being inferred from its value. Explicit synchronization (e.g. locks or // state being inferred from its value. Explicit synchronization (e.g. locks or
...@@ -67,6 +71,7 @@ namespace { ...@@ -67,6 +71,7 @@ namespace {
// NONE_ACTIVE after the first Worker was created -- this is not possible for // NONE_ACTIVE after the first Worker was created -- this is not possible for
// REDIRECTED_TO_TASK_SCHEDULER per its API requesting to be invoked while no // REDIRECTED_TO_TASK_SCHEDULER per its API requesting to be invoked while no
// other threads are active). // other threads are active).
//
// TODO(gab): Remove this if http://crbug.com/622400 fails (SequencedWorkerPool // TODO(gab): Remove this if http://crbug.com/622400 fails (SequencedWorkerPool
// will be phased out completely otherwise). // will be phased out completely otherwise).
enum AllPoolsState : subtle::Atomic32 { enum AllPoolsState : subtle::Atomic32 {
...@@ -902,6 +907,8 @@ bool SequencedWorkerPool::Inner::IsRunningSequenceOnCurrentThread( ...@@ -902,6 +907,8 @@ bool SequencedWorkerPool::Inner::IsRunningSequenceOnCurrentThread(
// See https://code.google.com/p/chromium/issues/detail?id=168415 // See https://code.google.com/p/chromium/issues/detail?id=168415
void SequencedWorkerPool::Inner::CleanupForTesting() { void SequencedWorkerPool::Inner::CleanupForTesting() {
DCHECK_NE(subtle::NoBarrier_Load(&g_all_pools_state),
AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER);
DCHECK(!RunsTasksOnCurrentThread()); DCHECK(!RunsTasksOnCurrentThread());
base::ThreadRestrictions::ScopedAllowWait allow_wait; base::ThreadRestrictions::ScopedAllowWait allow_wait;
AutoLock lock(lock_); AutoLock lock(lock_);
...@@ -1449,8 +1456,7 @@ SequencedWorkerPool::GetWorkerPoolForCurrentThread() { ...@@ -1449,8 +1456,7 @@ SequencedWorkerPool::GetWorkerPoolForCurrentThread() {
} }
// static // static
void SequencedWorkerPool:: void SequencedWorkerPool::RedirectToTaskSchedulerForProcess() {
RedirectSequencedWorkerPoolsToTaskSchedulerForProcess() {
DCHECK(TaskScheduler::GetInstance()); DCHECK(TaskScheduler::GetInstance());
// Hitting this DCHECK indicates that a task was posted to a // Hitting this DCHECK indicates that a task was posted to a
// SequencedWorkerPool before the TaskScheduler was initialized and // SequencedWorkerPool before the TaskScheduler was initialized and
...@@ -1462,6 +1468,16 @@ void SequencedWorkerPool:: ...@@ -1462,6 +1468,16 @@ void SequencedWorkerPool::
AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER); AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER);
} }
// static
void SequencedWorkerPool::ResetRedirectToTaskSchedulerForProcessForTesting() {
// This can be called when the current state is REDIRECTED_TO_TASK_SCHEDULER
// to stop redirecting tasks. It can also be called when the current state is
// WORKER_CREATED to allow RedirectToTaskSchedulerForProcess() to be called
// (RedirectToTaskSchedulerForProcess() cannot be called after a worker has
// been created if this isn't called).
subtle::NoBarrier_Store(&g_all_pools_state, AllPoolsState::NONE_ACTIVE);
}
SequencedWorkerPool::SequencedWorkerPool(size_t max_threads, SequencedWorkerPool::SequencedWorkerPool(size_t max_threads,
const std::string& thread_name_prefix, const std::string& thread_name_prefix,
base::TaskPriority task_priority) base::TaskPriority task_priority)
......
...@@ -172,16 +172,27 @@ class BASE_EXPORT SequencedWorkerPool : public TaskRunner { ...@@ -172,16 +172,27 @@ class BASE_EXPORT SequencedWorkerPool : public TaskRunner {
// PostSequencedWorkerTask(). Valid tokens are always nonzero. // PostSequencedWorkerTask(). Valid tokens are always nonzero.
static SequenceToken GetSequenceToken(); static SequenceToken GetSequenceToken();
// Invoke this once on the main thread of a process, before any other threads // Starts redirecting tasks posted to this process' SequencedWorkerPools to
// are created and before any tasks are posted to that process' // the registered TaskScheduler. This cannot be called after a task has been
// SequencedWorkerPools but after TaskScheduler was instantiated, to force all // posted to a SequencedWorkerPool. This is not thread-safe; proper
// SequencedWorkerPools in that process to redirect their tasks to the // synchronization is required to use any SequencedWorkerPool method after
// TaskScheduler. Note: SequencedWorkerPool instances with |max_threads == 1| // calling this. There must be a registered TaskScheduler when this is called.
// will be special cased to send all of their work as // Ideally, call this on the main thread of a process, before any other
// ExecutionMode::SINGLE_THREADED. // threads are created and before any tasks are posted to that process'
// SequencedWorkerPools.
// Note: SequencedWorkerPool instances with |max_threads == 1| will be special
// cased to send all of their work as ExecutionMode::SINGLE_THREADED.
// TODO(gab): Remove this if http://crbug.com/622400 fails // TODO(gab): Remove this if http://crbug.com/622400 fails
// (SequencedWorkerPool will be phased out completely otherwise). // (SequencedWorkerPool will be phased out completely otherwise).
static void RedirectSequencedWorkerPoolsToTaskSchedulerForProcess(); static void RedirectToTaskSchedulerForProcess();
// Stops redirecting tasks posted to this process' SequencedWorkerPools to the
// registered TaskScheduler and allows RedirectToTaskSchedulerForProcess() to
// be called even if tasks have already posted to a SequencedWorkerPool in
// this process. Calling this while there are active SequencedWorkerPools is
// not supported. This is not thread-safe; proper synchronization is required
// to use any SequencedWorkerPool method after calling this.
static void ResetRedirectToTaskSchedulerForProcessForTesting();
// When constructing a SequencedWorkerPool, there must be a // When constructing a SequencedWorkerPool, there must be a
// ThreadTaskRunnerHandle on the current thread unless you plan to // ThreadTaskRunnerHandle on the current thread unless you plan to
......
...@@ -450,8 +450,7 @@ void MaybeInitializeTaskScheduler() { ...@@ -450,8 +450,7 @@ void MaybeInitializeTaskScheduler() {
variation_params.find("RedirectSequencedWorkerPools"); variation_params.find("RedirectSequencedWorkerPools");
if (sequenced_worker_pool_param != variation_params.end() && if (sequenced_worker_pool_param != variation_params.end() &&
sequenced_worker_pool_param->second == "true") { sequenced_worker_pool_param->second == "true") {
base::SequencedWorkerPool:: base::SequencedWorkerPool::RedirectToTaskSchedulerForProcess();
RedirectSequencedWorkerPoolsToTaskSchedulerForProcess();
} }
} }
......
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