summaryrefslogtreecommitdiff
path: root/chromium/components/scheduler/base
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/components/scheduler/base')
-rw-r--r--chromium/components/scheduler/base/DEPS9
-rw-r--r--chromium/components/scheduler/base/cancelable_closure_holder.cc28
-rw-r--r--chromium/components/scheduler/base/cancelable_closure_holder.h40
-rw-r--r--chromium/components/scheduler/base/enqueue_order.cc20
-rw-r--r--chromium/components/scheduler/base/enqueue_order.h32
-rw-r--r--chromium/components/scheduler/base/lazy_now.cc17
-rw-r--r--chromium/components/scheduler/base/lazy_now.h36
-rw-r--r--chromium/components/scheduler/base/pollable_thread_safe_flag.cc19
-rw-r--r--chromium/components/scheduler/base/pollable_thread_safe_flag.h36
-rw-r--r--chromium/components/scheduler/base/real_time_domain.cc73
-rw-r--r--chromium/components/scheduler/base/real_time_domain.h44
-rw-r--r--chromium/components/scheduler/base/task_queue.h216
-rw-r--r--chromium/components/scheduler/base/task_queue_impl.cc705
-rw-r--r--chromium/components/scheduler/base/task_queue_impl.h309
-rw-r--r--chromium/components/scheduler/base/task_queue_manager.cc418
-rw-r--r--chromium/components/scheduler/base/task_queue_manager.h257
-rw-r--r--chromium/components/scheduler/base/task_queue_manager_delegate.h34
-rw-r--r--chromium/components/scheduler/base/task_queue_manager_delegate_for_test.cc56
-rw-r--r--chromium/components/scheduler/base/task_queue_manager_delegate_for_test.h48
-rw-r--r--chromium/components/scheduler/base/task_queue_manager_perftest.cc163
-rw-r--r--chromium/components/scheduler/base/task_queue_manager_unittest.cc1929
-rw-r--r--chromium/components/scheduler/base/task_queue_selector.cc380
-rw-r--r--chromium/components/scheduler/base/task_queue_selector.h206
-rw-r--r--chromium/components/scheduler/base/task_queue_selector_unittest.cc494
-rw-r--r--chromium/components/scheduler/base/test_always_fail_time_source.cc21
-rw-r--r--chromium/components/scheduler/base/test_always_fail_time_source.h26
-rw-r--r--chromium/components/scheduler/base/test_time_source.cc20
-rw-r--r--chromium/components/scheduler/base/test_time_source.h31
-rw-r--r--chromium/components/scheduler/base/time_domain.cc215
-rw-r--r--chromium/components/scheduler/base/time_domain.h156
-rw-r--r--chromium/components/scheduler/base/time_domain_unittest.cc230
-rw-r--r--chromium/components/scheduler/base/virtual_time_domain.cc64
-rw-r--r--chromium/components/scheduler/base/virtual_time_domain.h55
-rw-r--r--chromium/components/scheduler/base/work_queue.cc105
-rw-r--r--chromium/components/scheduler/base/work_queue.h96
-rw-r--r--chromium/components/scheduler/base/work_queue_sets.cc146
-rw-r--r--chromium/components/scheduler/base/work_queue_sets.h68
-rw-r--r--chromium/components/scheduler/base/work_queue_sets_unittest.cc259
38 files changed, 0 insertions, 7061 deletions
diff --git a/chromium/components/scheduler/base/DEPS b/chromium/components/scheduler/base/DEPS
deleted file mode 100644
index 5d86a1bc60e..00000000000
--- a/chromium/components/scheduler/base/DEPS
+++ /dev/null
@@ -1,9 +0,0 @@
-include_rules = [
- "+components/scheduler/scheduler_export.h",
-]
-
-specific_include_rules = {
- "(test_time_source|.*test)\.cc": [
- "+cc/test",
- ],
-}
diff --git a/chromium/components/scheduler/base/cancelable_closure_holder.cc b/chromium/components/scheduler/base/cancelable_closure_holder.cc
deleted file mode 100644
index 54c1462f5d3..00000000000
--- a/chromium/components/scheduler/base/cancelable_closure_holder.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2014 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/scheduler/base/cancelable_closure_holder.h"
-
-namespace scheduler {
-
-CancelableClosureHolder::CancelableClosureHolder() {}
-
-CancelableClosureHolder::~CancelableClosureHolder() {}
-
-void CancelableClosureHolder::Reset(const base::Closure& callback) {
- callback_ = callback;
- cancelable_callback_.Reset(callback_);
-}
-
-void CancelableClosureHolder::Cancel() {
- DCHECK(!callback_.is_null());
- cancelable_callback_.Reset(callback_);
-}
-
-const base::Closure& CancelableClosureHolder::callback() const {
- DCHECK(!callback_.is_null());
- return cancelable_callback_.callback();
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/base/cancelable_closure_holder.h b/chromium/components/scheduler/base/cancelable_closure_holder.h
deleted file mode 100644
index 5254cd490a5..00000000000
--- a/chromium/components/scheduler/base/cancelable_closure_holder.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2014 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_SCHEDULER_BASE_CANCELABLE_CLOSURE_HOLDER_H_
-#define COMPONENTS_SCHEDULER_BASE_CANCELABLE_CLOSURE_HOLDER_H_
-
-#include "base/cancelable_callback.h"
-#include "base/macros.h"
-
-namespace scheduler {
-
-// A CancelableClosureHolder is a CancelableCallback which resets its wrapped
-// callback with a cached closure whenever it is canceled.
-class CancelableClosureHolder {
- public:
- CancelableClosureHolder();
- ~CancelableClosureHolder();
-
- // Resets the closure to be wrapped by the cancelable callback. Cancels any
- // outstanding callbacks.
- void Reset(const base::Closure& callback);
-
- // Cancels any outstanding closures returned by callback().
- void Cancel();
-
- // Returns a callback that will be disabled by calling Cancel(). Callback
- // must have been set using Reset() before calling this function.
- const base::Closure& callback() const;
-
- private:
- base::Closure callback_;
- base::CancelableClosure cancelable_callback_;
-
- DISALLOW_COPY_AND_ASSIGN(CancelableClosureHolder);
-};
-
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_BASE_CANCELABLE_CLOSURE_HOLDER_H_
diff --git a/chromium/components/scheduler/base/enqueue_order.cc b/chromium/components/scheduler/base/enqueue_order.cc
deleted file mode 100644
index dd04bbd4023..00000000000
--- a/chromium/components/scheduler/base/enqueue_order.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2015 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/scheduler/base/enqueue_order.h"
-
-namespace scheduler {
-namespace internal {
-
-EnqueueOrderGenerator::EnqueueOrderGenerator() : enqueue_order_(0) {}
-
-EnqueueOrderGenerator::~EnqueueOrderGenerator() {}
-
-EnqueueOrder EnqueueOrderGenerator::GenerateNext() {
- base::AutoLock lock(lock_);
- return enqueue_order_++;
-}
-
-} // namespace internal
-} // namespace scheduler
diff --git a/chromium/components/scheduler/base/enqueue_order.h b/chromium/components/scheduler/base/enqueue_order.h
deleted file mode 100644
index 21001ffc284..00000000000
--- a/chromium/components/scheduler/base/enqueue_order.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2015 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_SCHEDULER_BASE_ENQUEUE_ORDER_H_
-#define COMPONENTS_SCHEDULER_BASE_ENQUEUE_ORDER_H_
-
-#include <stdint.h>
-
-#include "base/synchronization/lock.h"
-
-namespace scheduler {
-namespace internal {
-
-using EnqueueOrder = uint64_t;
-
-class EnqueueOrderGenerator {
- public:
- EnqueueOrderGenerator();
- ~EnqueueOrderGenerator();
-
- EnqueueOrder GenerateNext();
-
- private:
- base::Lock lock_;
- EnqueueOrder enqueue_order_;
-};
-
-} // namespace internal
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_BASE_ENQUEUE_ORDER_H_
diff --git a/chromium/components/scheduler/base/lazy_now.cc b/chromium/components/scheduler/base/lazy_now.cc
deleted file mode 100644
index 3492ca6766d..00000000000
--- a/chromium/components/scheduler/base/lazy_now.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2015 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/scheduler/base/lazy_now.h"
-
-#include "base/time/tick_clock.h"
-#include "components/scheduler/base/task_queue_manager.h"
-
-namespace scheduler {
-base::TimeTicks LazyNow::Now() {
- if (now_.is_null())
- now_ = tick_clock_->NowTicks();
- return now_;
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/base/lazy_now.h b/chromium/components/scheduler/base/lazy_now.h
deleted file mode 100644
index 959a2450947..00000000000
--- a/chromium/components/scheduler/base/lazy_now.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2015 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_SCHEDULER_BASE_LAZY_NOW_H_
-#define COMPONENTS_SCHEDULER_BASE_LAZY_NOW_H_
-
-#include "base/time/time.h"
-#include "components/scheduler/scheduler_export.h"
-
-namespace base {
-class TickClock;
-}
-
-namespace scheduler {
-
-// Now() is somewhat expensive so it makes sense not to call Now() unless we
-// really need to.
-class SCHEDULER_EXPORT LazyNow {
- public:
- explicit LazyNow(base::TimeTicks now) : tick_clock_(nullptr), now_(now) {
- DCHECK(!now.is_null());
- }
-
- explicit LazyNow(base::TickClock* tick_clock) : tick_clock_(tick_clock) {}
-
- base::TimeTicks Now();
-
- private:
- base::TickClock* tick_clock_; // NOT OWNED
- base::TimeTicks now_;
-};
-
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_BASE_LAZY_NOW_H_
diff --git a/chromium/components/scheduler/base/pollable_thread_safe_flag.cc b/chromium/components/scheduler/base/pollable_thread_safe_flag.cc
deleted file mode 100644
index 13d5b6f5ec8..00000000000
--- a/chromium/components/scheduler/base/pollable_thread_safe_flag.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2015 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/scheduler/base/pollable_thread_safe_flag.h"
-
-PollableThreadSafeFlag::PollableThreadSafeFlag(base::Lock* write_lock_)
- : flag_(false), write_lock_(write_lock_) {}
-
-PollableThreadSafeFlag::~PollableThreadSafeFlag() {}
-
-void PollableThreadSafeFlag::SetWhileLocked(bool value) {
- write_lock_->AssertAcquired();
- base::subtle::Release_Store(&flag_, value);
-}
-
-bool PollableThreadSafeFlag::IsSet() const {
- return base::subtle::Acquire_Load(&flag_) != false;
-}
diff --git a/chromium/components/scheduler/base/pollable_thread_safe_flag.h b/chromium/components/scheduler/base/pollable_thread_safe_flag.h
deleted file mode 100644
index 8e37b690595..00000000000
--- a/chromium/components/scheduler/base/pollable_thread_safe_flag.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2015 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_SCHEDULER_BASE_POLLABLE_THREAD_SAFE_FLAG_H_
-#define COMPONENTS_SCHEDULER_BASE_POLLABLE_THREAD_SAFE_FLAG_H_
-
-#include "base/atomicops.h"
-#include "base/macros.h"
-#include "base/synchronization/lock.h"
-
-// A PollableThreadSafeFlag can be polled without requiring a lock, but can only
-// be updated if a lock is held. This enables lock-free checking as to whether a
-// condition has changed, while protecting operations which update the condition
-// with a lock. You must ensure that the flag is only updated within the same
-// lock-protected critical section as any other variables on which the condition
-// depends.
-class PollableThreadSafeFlag {
- public:
- explicit PollableThreadSafeFlag(base::Lock* write_lock);
- ~PollableThreadSafeFlag();
-
- // Set the flag. May only be called if |write_lock| is held.
- void SetWhileLocked(bool value);
-
- // Returns true iff the flag is set to true.
- bool IsSet() const;
-
- private:
- base::subtle::Atomic32 flag_;
- base::Lock* write_lock_; // Not owned.
-
- DISALLOW_COPY_AND_ASSIGN(PollableThreadSafeFlag);
-};
-
-#endif // COMPONENTS_SCHEDULER_BASE_POLLABLE_THREAD_SAFE_FLAG_H_
diff --git a/chromium/components/scheduler/base/real_time_domain.cc b/chromium/components/scheduler/base/real_time_domain.cc
deleted file mode 100644
index a452b978e91..00000000000
--- a/chromium/components/scheduler/base/real_time_domain.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2015 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/scheduler/base/real_time_domain.h"
-
-#include "base/bind.h"
-#include "components/scheduler/base/task_queue_impl.h"
-#include "components/scheduler/base/task_queue_manager.h"
-#include "components/scheduler/base/task_queue_manager_delegate.h"
-
-namespace scheduler {
-
-RealTimeDomain::RealTimeDomain(const char* tracing_category)
- : TimeDomain(nullptr),
- tracing_category_(tracing_category),
- task_queue_manager_(nullptr) {}
-
-RealTimeDomain::RealTimeDomain(TimeDomain::Observer* observer,
- const char* tracing_category)
- : TimeDomain(observer),
- tracing_category_(tracing_category),
- task_queue_manager_(nullptr) {}
-
-RealTimeDomain::~RealTimeDomain() {}
-
-void RealTimeDomain::OnRegisterWithTaskQueueManager(
- TaskQueueManager* task_queue_manager) {
- task_queue_manager_ = task_queue_manager;
- DCHECK(task_queue_manager_);
-}
-
-LazyNow RealTimeDomain::CreateLazyNow() const {
- return task_queue_manager_->CreateLazyNow();
-}
-
-base::TimeTicks RealTimeDomain::Now() const {
- return task_queue_manager_->delegate()->NowTicks();
-}
-
-void RealTimeDomain::RequestWakeup(base::TimeTicks now, base::TimeDelta delay) {
- // NOTE this is only called if the scheduled runtime is sooner than any
- // previously scheduled runtime, or there is no (outstanding) previously
- // scheduled runtime.
- task_queue_manager_->MaybeScheduleDelayedWork(FROM_HERE, now, delay);
-}
-
-bool RealTimeDomain::MaybeAdvanceTime() {
- base::TimeTicks next_run_time;
- if (!NextScheduledRunTime(&next_run_time))
- return false;
-
- base::TimeTicks now = Now();
- if (now >= next_run_time)
- return true; // Causes DoWork to post a continuation.
-
- base::TimeDelta delay = next_run_time - now;
- TRACE_EVENT1(tracing_category_, "RealTimeDomain::MaybeAdvanceTime",
- "delay_ms", delay.InMillisecondsF());
-
- // The next task is sometime in the future, make sure we schedule a DoWork to
- // run it.
- task_queue_manager_->MaybeScheduleDelayedWork(FROM_HERE, now, delay);
- return false;
-}
-
-void RealTimeDomain::AsValueIntoInternal(
- base::trace_event::TracedValue* state) const {}
-
-const char* RealTimeDomain::GetName() const {
- return "RealTimeDomain";
-}
-} // namespace scheduler
diff --git a/chromium/components/scheduler/base/real_time_domain.h b/chromium/components/scheduler/base/real_time_domain.h
deleted file mode 100644
index fa20ba7a077..00000000000
--- a/chromium/components/scheduler/base/real_time_domain.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2015 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_SCHEDULER_BASE_REAL_TIME_DOMAIN_H_
-#define COMPONENTS_SCHEDULER_BASE_REAL_TIME_DOMAIN_H_
-
-#include <set>
-
-#include "base/macros.h"
-#include "components/scheduler/base/time_domain.h"
-#include "components/scheduler/scheduler_export.h"
-
-namespace scheduler {
-
-class SCHEDULER_EXPORT RealTimeDomain : public TimeDomain {
- public:
- explicit RealTimeDomain(const char* tracing_category);
- RealTimeDomain(TimeDomain::Observer* observer, const char* tracing_category);
- ~RealTimeDomain() override;
-
- // TimeDomain implementation:
- LazyNow CreateLazyNow() const override;
- base::TimeTicks Now() const override;
- bool MaybeAdvanceTime() override;
- const char* GetName() const override;
-
- protected:
- void OnRegisterWithTaskQueueManager(
- TaskQueueManager* task_queue_manager) override;
- void RequestWakeup(base::TimeTicks now, base::TimeDelta delay) override;
- void AsValueIntoInternal(
- base::trace_event::TracedValue* state) const override;
-
- private:
- const char* tracing_category_; // NOT OWNED
- TaskQueueManager* task_queue_manager_; // NOT OWNED
-
- DISALLOW_COPY_AND_ASSIGN(RealTimeDomain);
-};
-
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_BASE_REAL_TIME_DOMAIN_H_
diff --git a/chromium/components/scheduler/base/task_queue.h b/chromium/components/scheduler/base/task_queue.h
deleted file mode 100644
index b3a316362ce..00000000000
--- a/chromium/components/scheduler/base/task_queue.h
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright 2015 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_SCHEDULER_BASE_TASK_QUEUE_H_
-#define COMPONENTS_SCHEDULER_BASE_TASK_QUEUE_H_
-
-#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
-#include "base/single_thread_task_runner.h"
-#include "base/trace_event/trace_event.h"
-#include "components/scheduler/scheduler_export.h"
-
-namespace base {
-namespace trace_event {
-class BlameContext;
-}
-}
-
-namespace scheduler {
-class LazyNow;
-class TimeDomain;
-
-class SCHEDULER_EXPORT TaskQueue : public base::SingleThreadTaskRunner {
- public:
- TaskQueue() {}
-
- // Unregisters the task queue after which no tasks posted to it will run and
- // the TaskQueueManager's reference to it will be released soon.
- virtual void UnregisterTaskQueue() = 0;
-
- enum QueuePriority {
- // Queues with control priority will run before any other queue, and will
- // explicitly starve other queues. Typically this should only be used for
- // private queues which perform control operations.
- CONTROL_PRIORITY,
- // Queues with high priority will be selected preferentially over normal or
- // best effort queues. The selector will ensure that high priority queues
- // cannot completely starve normal priority queues.
- HIGH_PRIORITY,
- // Queues with normal priority are the default.
- NORMAL_PRIORITY,
- // Queues with best effort priority will only be run if all other queues are
- // empty. They can be starved by the other queues.
- BEST_EFFORT_PRIORITY,
- // Must be the last entry.
- QUEUE_PRIORITY_COUNT,
- FIRST_QUEUE_PRIORITY = CONTROL_PRIORITY,
- };
-
- // Keep TaskQueue::PumpPolicyToString in sync with this enum.
- enum class PumpPolicy {
- // Tasks posted to an incoming queue with an AUTO pump policy will be
- // automatically scheduled for execution or transferred to the work queue
- // automatically.
- AUTO,
- // Tasks posted to an incoming queue with an AFTER_WAKEUP pump policy
- // will be scheduled for execution or transferred to the work queue
- // automatically but only after another queue has executed a task.
- AFTER_WAKEUP,
- // Tasks posted to an incoming queue with a MANUAL will not be
- // automatically scheduled for execution or transferred to the work queue.
- // Instead, the selector should call PumpQueue() when necessary to bring
- // in new tasks for execution.
- MANUAL,
- // Must be last entry.
- PUMP_POLICY_COUNT,
- FIRST_PUMP_POLICY = AUTO,
- };
-
- // Keep TaskQueue::WakeupPolicyToString in sync with this enum.
- enum class WakeupPolicy {
- // Tasks run on a queue with CAN_WAKE_OTHER_QUEUES wakeup policy can
- // cause queues with the AFTER_WAKEUP PumpPolicy to be woken up.
- CAN_WAKE_OTHER_QUEUES,
- // Tasks run on a queue with DONT_WAKE_OTHER_QUEUES won't cause queues
- // with the AFTER_WAKEUP PumpPolicy to be woken up.
- DONT_WAKE_OTHER_QUEUES,
- // Must be last entry.
- WAKEUP_POLICY_COUNT,
- FIRST_WAKEUP_POLICY = CAN_WAKE_OTHER_QUEUES,
- };
-
- // Options for constructing a TaskQueue. Once set the |name|,
- // |should_monitor_quiescence| and |wakeup_policy| are immutable. The
- // |pump_policy| can be mutated with |SetPumpPolicy()|.
- struct Spec {
- // Note |name| must have application lifetime.
- explicit Spec(const char* name)
- : name(name),
- should_monitor_quiescence(false),
- pump_policy(TaskQueue::PumpPolicy::AUTO),
- wakeup_policy(TaskQueue::WakeupPolicy::CAN_WAKE_OTHER_QUEUES),
- time_domain(nullptr),
- should_notify_observers(true),
- should_report_when_execution_blocked(false) {}
-
- Spec SetShouldMonitorQuiescence(bool should_monitor) {
- should_monitor_quiescence = should_monitor;
- return *this;
- }
-
- Spec SetPumpPolicy(PumpPolicy policy) {
- pump_policy = policy;
- return *this;
- }
-
- Spec SetWakeupPolicy(WakeupPolicy policy) {
- wakeup_policy = policy;
- return *this;
- }
-
- Spec SetShouldNotifyObservers(bool run_observers) {
- should_notify_observers = run_observers;
- return *this;
- }
-
- Spec SetTimeDomain(TimeDomain* domain) {
- time_domain = domain;
- return *this;
- }
-
- // See TaskQueueManager::Observer::OnTriedToExecuteBlockedTask.
- Spec SetShouldReportWhenExecutionBlocked(bool should_report) {
- should_report_when_execution_blocked = should_report;
- return *this;
- }
-
- const char* name;
- bool should_monitor_quiescence;
- TaskQueue::PumpPolicy pump_policy;
- TaskQueue::WakeupPolicy wakeup_policy;
- TimeDomain* time_domain;
- bool should_notify_observers;
- bool should_report_when_execution_blocked;
- };
-
- // Enable or disable task execution for this queue. NOTE this must be called
- // on the thread this TaskQueue was created by.
- virtual void SetQueueEnabled(bool enabled) = 0;
-
- // NOTE this must be called on the thread this TaskQueue was created by.
- virtual bool IsQueueEnabled() const = 0;
-
- // Returns true if the queue is completely empty.
- virtual bool IsEmpty() const = 0;
-
- // Returns true if the queue has work that's ready to execute now, or if it
- // would have if the queue was pumped. NOTE this must be called on the thread
- // this TaskQueue was created by.
- virtual bool HasPendingImmediateWork() const = 0;
-
- // Returns true if tasks can't run now but could if the queue was pumped.
- virtual bool NeedsPumping() const = 0;
-
- // Can be called on any thread.
- virtual const char* GetName() const = 0;
-
- // Set the priority of the queue to |priority|. NOTE this must be called on
- // the thread this TaskQueue was created by.
- virtual void SetQueuePriority(QueuePriority priority) = 0;
-
- // Returns the current queue priority.
- virtual QueuePriority GetQueuePriority() const = 0;
-
- // Set the pumping policy of the queue to |pump_policy|. NOTE this must be
- // called on the thread this TaskQueue was created by.
- virtual void SetPumpPolicy(PumpPolicy pump_policy) = 0;
-
- // Returns the current PumpPolicy. NOTE this must be called on the thread this
- // TaskQueue was created by.
- virtual PumpPolicy GetPumpPolicy() const = 0;
-
- // Reloads new tasks from the incoming queue into the work queue, regardless
- // of whether the work queue is empty or not. After this, the function ensures
- // that the tasks in the work queue, if any, are scheduled for execution.
- //
- // This function only needs to be called if automatic pumping is disabled.
- // By default automatic pumping is enabled for all queues. NOTE this must be
- // called on the thread this TaskQueue was created by.
- //
- // The |may_post_dowork| parameter controls whether or not PumpQueue calls
- // TaskQueueManager::MaybeScheduleImmediateWork.
- // TODO(alexclarke): Add a base::RunLoop observer so we can get rid of
- // |may_post_dowork|.
- virtual void PumpQueue(LazyNow* lazy_now, bool may_post_dowork) = 0;
-
- // These functions can only be called on the same thread that the task queue
- // manager executes its tasks on.
- virtual void AddTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) = 0;
- virtual void RemoveTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) = 0;
-
- // Set the blame context which is entered and left while executing tasks from
- // this task queue. |blame_context| must be null or outlive this task queue.
- // Must be called on the thread this TaskQueue was created by.
- virtual void SetBlameContext(
- base::trace_event::BlameContext* blame_context) = 0;
-
- // Removes the task queue from the previous TimeDomain and adds it to
- // |domain|. This is a moderately expensive operation.
- virtual void SetTimeDomain(TimeDomain* domain) = 0;
-
- // Returns the queue's current TimeDomain. Can be called from any thread.
- virtual TimeDomain* GetTimeDomain() const = 0;
-
- protected:
- ~TaskQueue() override {}
-
- DISALLOW_COPY_AND_ASSIGN(TaskQueue);
-};
-
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_BASE_TASK_QUEUE_H_
diff --git a/chromium/components/scheduler/base/task_queue_impl.cc b/chromium/components/scheduler/base/task_queue_impl.cc
deleted file mode 100644
index 0dc5f648000..00000000000
--- a/chromium/components/scheduler/base/task_queue_impl.cc
+++ /dev/null
@@ -1,705 +0,0 @@
-// Copyright 2015 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/scheduler/base/task_queue_impl.h"
-
-#include "base/trace_event/blame_context.h"
-#include "components/scheduler/base/task_queue_manager.h"
-#include "components/scheduler/base/task_queue_manager_delegate.h"
-#include "components/scheduler/base/time_domain.h"
-#include "components/scheduler/base/work_queue.h"
-
-namespace scheduler {
-namespace internal {
-
-TaskQueueImpl::TaskQueueImpl(
- TaskQueueManager* task_queue_manager,
- TimeDomain* time_domain,
- const Spec& spec,
- const char* disabled_by_default_tracing_category,
- const char* disabled_by_default_verbose_tracing_category)
- : thread_id_(base::PlatformThread::CurrentId()),
- any_thread_(task_queue_manager, spec.pump_policy, time_domain),
- name_(spec.name),
- disabled_by_default_tracing_category_(
- disabled_by_default_tracing_category),
- disabled_by_default_verbose_tracing_category_(
- disabled_by_default_verbose_tracing_category),
- main_thread_only_(task_queue_manager,
- spec.pump_policy,
- this,
- time_domain),
- wakeup_policy_(spec.wakeup_policy),
- should_monitor_quiescence_(spec.should_monitor_quiescence),
- should_notify_observers_(spec.should_notify_observers),
- should_report_when_execution_blocked_(
- spec.should_report_when_execution_blocked) {
- DCHECK(time_domain);
- time_domain->RegisterQueue(this);
-}
-
-TaskQueueImpl::~TaskQueueImpl() {
-#if DCHECK_IS_ON()
- base::AutoLock lock(any_thread_lock_);
- // NOTE this check shouldn't fire because |TaskQueueManager::queues_|
- // contains a strong reference to this TaskQueueImpl and the TaskQueueManager
- // destructor calls UnregisterTaskQueue on all task queues.
- DCHECK(any_thread().task_queue_manager == nullptr)
- << "UnregisterTaskQueue must be called first!";
-
-#endif
-}
-
-TaskQueueImpl::Task::Task()
- : PendingTask(tracked_objects::Location(),
- base::Closure(),
- base::TimeTicks(),
- true),
-#ifndef NDEBUG
- enqueue_order_set_(false),
-#endif
- enqueue_order_(0) {
- sequence_num = 0;
-}
-
-TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from,
- const base::Closure& task,
- base::TimeTicks desired_run_time,
- EnqueueOrder sequence_number,
- bool nestable)
- : PendingTask(posted_from, task, desired_run_time, nestable),
-#ifndef NDEBUG
- enqueue_order_set_(false),
-#endif
- enqueue_order_(0) {
- sequence_num = sequence_number;
-}
-
-TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from,
- const base::Closure& task,
- base::TimeTicks desired_run_time,
- EnqueueOrder sequence_number,
- bool nestable,
- EnqueueOrder enqueue_order)
- : PendingTask(posted_from, task, desired_run_time, nestable),
-#ifndef NDEBUG
- enqueue_order_set_(true),
-#endif
- enqueue_order_(enqueue_order) {
- sequence_num = sequence_number;
-}
-
-TaskQueueImpl::AnyThread::AnyThread(TaskQueueManager* task_queue_manager,
- PumpPolicy pump_policy,
- TimeDomain* time_domain)
- : task_queue_manager(task_queue_manager),
- pump_policy(pump_policy),
- time_domain(time_domain) {}
-
-TaskQueueImpl::AnyThread::~AnyThread() {}
-
-TaskQueueImpl::MainThreadOnly::MainThreadOnly(
- TaskQueueManager* task_queue_manager,
- PumpPolicy pump_policy,
- TaskQueueImpl* task_queue,
- TimeDomain* time_domain)
- : task_queue_manager(task_queue_manager),
- pump_policy(pump_policy),
- time_domain(time_domain),
- delayed_work_queue(new WorkQueue(task_queue, "delayed")),
- immediate_work_queue(new WorkQueue(task_queue, "immediate")),
- set_index(0),
- is_enabled(true),
- blame_context(nullptr) {}
-
-TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {}
-
-void TaskQueueImpl::UnregisterTaskQueue() {
- base::AutoLock lock(any_thread_lock_);
- if (main_thread_only().time_domain)
- main_thread_only().time_domain->UnregisterQueue(this);
- if (!any_thread().task_queue_manager)
- return;
- any_thread().time_domain = nullptr;
- main_thread_only().time_domain = nullptr;
- any_thread().task_queue_manager->UnregisterTaskQueue(this);
-
- any_thread().task_queue_manager = nullptr;
- main_thread_only().task_queue_manager = nullptr;
- main_thread_only().delayed_incoming_queue = std::priority_queue<Task>();
- any_thread().immediate_incoming_queue = std::queue<Task>();
- main_thread_only().immediate_work_queue.reset();
- main_thread_only().delayed_work_queue.reset();
-}
-
-bool TaskQueueImpl::RunsTasksOnCurrentThread() const {
- base::AutoLock lock(any_thread_lock_);
- return base::PlatformThread::CurrentId() == thread_id_;
-}
-
-bool TaskQueueImpl::PostDelayedTask(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) {
- if (delay.is_zero())
- return PostImmediateTaskImpl(from_here, task, TaskType::NORMAL);
-
- return PostDelayedTaskImpl(from_here, task, delay, TaskType::NORMAL);
-}
-
-bool TaskQueueImpl::PostNonNestableDelayedTask(
- const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) {
- if (delay.is_zero())
- return PostImmediateTaskImpl(from_here, task, TaskType::NON_NESTABLE);
-
- return PostDelayedTaskImpl(from_here, task, delay, TaskType::NON_NESTABLE);
-}
-
-bool TaskQueueImpl::PostImmediateTaskImpl(
- const tracked_objects::Location& from_here,
- const base::Closure& task,
- TaskType task_type) {
- base::AutoLock lock(any_thread_lock_);
- if (!any_thread().task_queue_manager)
- return false;
-
- EnqueueOrder sequence_number =
- any_thread().task_queue_manager->GetNextSequenceNumber();
-
- PushOntoImmediateIncomingQueueLocked(
- Task(from_here, task, base::TimeTicks(), sequence_number,
- task_type != TaskType::NON_NESTABLE, sequence_number));
- return true;
-}
-
-bool TaskQueueImpl::PostDelayedTaskImpl(
- const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay,
- TaskType task_type) {
- DCHECK_GT(delay, base::TimeDelta());
- if (base::PlatformThread::CurrentId() == thread_id_) {
- // Lock-free fast path for delayed tasks posted from the main thread.
- if (!main_thread_only().task_queue_manager)
- return false;
-
- EnqueueOrder sequence_number =
- main_thread_only().task_queue_manager->GetNextSequenceNumber();
-
- base::TimeTicks time_domain_now = main_thread_only().time_domain->Now();
- base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay;
- PushOntoDelayedIncomingQueueFromMainThread(
- Task(from_here, task, time_domain_delayed_run_time, sequence_number,
- task_type != TaskType::NON_NESTABLE),
- time_domain_now);
- } else {
- // NOTE posting a delayed task from a different thread is not expected to
- // be common. This pathway is less optimal than perhaps it could be
- // because it causes two main thread tasks to be run. Should this
- // assumption prove to be false in future, we may need to revisit this.
- base::AutoLock lock(any_thread_lock_);
- if (!any_thread().task_queue_manager)
- return false;
-
- EnqueueOrder sequence_number =
- any_thread().task_queue_manager->GetNextSequenceNumber();
-
- base::TimeTicks time_domain_now = any_thread().time_domain->Now();
- base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay;
- PushOntoDelayedIncomingQueueLocked(
- Task(from_here, task, time_domain_delayed_run_time, sequence_number,
- task_type != TaskType::NON_NESTABLE));
- }
- return true;
-}
-
-void TaskQueueImpl::PushOntoDelayedIncomingQueueFromMainThread(
- const Task& pending_task,
- base::TimeTicks now) {
- main_thread_only().task_queue_manager->DidQueueTask(pending_task);
-
- // Schedule a later call to MoveReadyDelayedTasksToDelayedWorkQueue.
- main_thread_only().delayed_incoming_queue.push(pending_task);
- main_thread_only().time_domain->ScheduleDelayedWork(
- this, pending_task.delayed_run_time, now);
- TraceQueueSize(false);
-}
-
-void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(
- const Task& pending_task) {
- any_thread().task_queue_manager->DidQueueTask(pending_task);
-
- int thread_hop_task_sequence_number =
- any_thread().task_queue_manager->GetNextSequenceNumber();
- PushOntoImmediateIncomingQueueLocked(Task(
- FROM_HERE,
- base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, this, pending_task),
- base::TimeTicks(), thread_hop_task_sequence_number, false,
- thread_hop_task_sequence_number));
-}
-
-void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked(
- const Task& pending_task) {
- if (any_thread().immediate_incoming_queue.empty())
- any_thread().time_domain->RegisterAsUpdatableTaskQueue(this);
- if (any_thread().pump_policy == PumpPolicy::AUTO &&
- any_thread().immediate_incoming_queue.empty()) {
- any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE);
- }
- any_thread().task_queue_manager->DidQueueTask(pending_task);
- any_thread().immediate_incoming_queue.push(pending_task);
- TraceQueueSize(true);
-}
-
-void TaskQueueImpl::ScheduleDelayedWorkTask(const Task& pending_task) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- main_thread_only().delayed_incoming_queue.push(pending_task);
- main_thread_only().time_domain->ScheduleDelayedWork(
- this, pending_task.delayed_run_time,
- main_thread_only().time_domain->Now());
-}
-
-void TaskQueueImpl::SetQueueEnabled(bool enabled) {
- if (main_thread_only().is_enabled == enabled)
- return;
- main_thread_only().is_enabled = enabled;
- if (!main_thread_only().task_queue_manager)
- return;
- if (enabled) {
- main_thread_only().task_queue_manager->selector_.EnableQueue(this);
- } else {
- main_thread_only().task_queue_manager->selector_.DisableQueue(this);
- }
-}
-
-bool TaskQueueImpl::IsQueueEnabled() const {
- return main_thread_only().is_enabled;
-}
-
-bool TaskQueueImpl::IsEmpty() const {
- if (!main_thread_only().delayed_work_queue->Empty() ||
- !main_thread_only().immediate_work_queue->Empty()) {
- return false;
- }
-
- base::AutoLock lock(any_thread_lock_);
- return any_thread().immediate_incoming_queue.empty() &&
- main_thread_only().delayed_incoming_queue.empty();
-}
-
-bool TaskQueueImpl::HasPendingImmediateWork() const {
- if (!main_thread_only().delayed_work_queue->Empty() ||
- !main_thread_only().immediate_work_queue->Empty()) {
- return true;
- }
-
- return NeedsPumping();
-}
-
-bool TaskQueueImpl::NeedsPumping() const {
- if (!main_thread_only().immediate_work_queue->Empty())
- return false;
-
- base::AutoLock lock(any_thread_lock_);
- if (!any_thread().immediate_incoming_queue.empty())
- return true;
-
- // If there's no immediate Incoming work then we only need pumping if there
- // is a delayed task that should be running now.
- if (main_thread_only().delayed_incoming_queue.empty())
- return false;
-
- return main_thread_only().delayed_incoming_queue.top().delayed_run_time <=
- main_thread_only().time_domain->CreateLazyNow().Now();
-}
-
-bool TaskQueueImpl::TaskIsOlderThanQueuedImmediateTasksLocked(
- const Task* task) {
- // A null task is passed when UpdateQueue is called before any task is run.
- // In this case we don't want to pump an after_wakeup queue, so return true
- // here.
- if (!task)
- return true;
-
- // Return false if task is newer than the oldest immediate task.
- if (!any_thread().immediate_incoming_queue.empty() &&
- task->enqueue_order() >
- any_thread().immediate_incoming_queue.front().enqueue_order()) {
- return false;
- }
- return true;
-}
-
-bool TaskQueueImpl::TaskIsOlderThanQueuedDelayedTasks(const Task* task) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- // A null task is passed when UpdateQueue is called before any task is run.
- // In this case we don't want to pump an after_wakeup queue, so return true
- // here.
- if (!task)
- return true;
-
- EnqueueOrder enqueue_order;
- if (!main_thread_only().delayed_work_queue->GetFrontTaskEnqueueOrder(
- &enqueue_order)) {
- return true;
- }
-
- return task->enqueue_order() < enqueue_order;
-}
-
-bool TaskQueueImpl::ShouldAutoPumpImmediateQueueLocked(
- bool should_trigger_wakeup,
- const Task* previous_task) {
- if (main_thread_only().pump_policy == PumpPolicy::MANUAL)
- return false;
- if (main_thread_only().pump_policy == PumpPolicy::AFTER_WAKEUP &&
- (!should_trigger_wakeup ||
- TaskIsOlderThanQueuedImmediateTasksLocked(previous_task)))
- return false;
- return true;
-}
-
-bool TaskQueueImpl::ShouldAutoPumpDelayedQueue(bool should_trigger_wakeup,
- const Task* previous_task) {
- if (main_thread_only().pump_policy == PumpPolicy::MANUAL)
- return false;
- if (main_thread_only().pump_policy == PumpPolicy::AFTER_WAKEUP &&
- (!should_trigger_wakeup ||
- TaskIsOlderThanQueuedDelayedTasks(previous_task)))
- return false;
- return true;
-}
-
-void TaskQueueImpl::MoveReadyDelayedTasksToDelayedWorkQueue(LazyNow* lazy_now) {
- // Enqueue all delayed tasks that should be running now.
- while (!main_thread_only().delayed_incoming_queue.empty() &&
- main_thread_only().delayed_incoming_queue.top().delayed_run_time <=
- lazy_now->Now()) {
- // Note: the const_cast is needed because there is no direct way to move
- // elements out of a priority queue. The queue must not be modified between
- // the top() and the pop().
- main_thread_only().delayed_work_queue->PushAndSetEnqueueOrder(
- std::move(
- const_cast<Task&>(main_thread_only().delayed_incoming_queue.top())),
- main_thread_only().task_queue_manager->GetNextSequenceNumber());
- main_thread_only().delayed_incoming_queue.pop();
- }
-}
-
-void TaskQueueImpl::UpdateDelayedWorkQueue(LazyNow* lazy_now,
- bool should_trigger_wakeup,
- const Task* previous_task) {
- if (!main_thread_only().task_queue_manager)
- return;
- if (!ShouldAutoPumpDelayedQueue(should_trigger_wakeup, previous_task))
- return;
- MoveReadyDelayedTasksToDelayedWorkQueue(lazy_now);
- TraceQueueSize(false);
-}
-
-void TaskQueueImpl::UpdateImmediateWorkQueue(bool should_trigger_wakeup,
- const Task* previous_task) {
- DCHECK(main_thread_only().immediate_work_queue->Empty());
- base::AutoLock lock(any_thread_lock_);
- if (!main_thread_only().task_queue_manager)
- return;
- if (!ShouldAutoPumpImmediateQueueLocked(should_trigger_wakeup, previous_task))
- return;
-
- main_thread_only().immediate_work_queue->SwapLocked(
- any_thread().immediate_incoming_queue);
-
- // |any_thread().immediate_incoming_queue| is now empty so
- // TimeDomain::UpdateQueues no longer needs to consider this queue for
- // reloading.
- main_thread_only().time_domain->UnregisterAsUpdatableTaskQueue(this);
-}
-
-void TaskQueueImpl::TraceQueueSize(bool is_locked) const {
- bool is_tracing;
- TRACE_EVENT_CATEGORY_GROUP_ENABLED(disabled_by_default_tracing_category_,
- &is_tracing);
- if (!is_tracing)
- return;
-
- // It's only safe to access the work queues from the main thread.
- // TODO(alexclarke): We should find another way of tracing this
- if (base::PlatformThread::CurrentId() != thread_id_)
- return;
-
- if (!is_locked)
- any_thread_lock_.Acquire();
- else
- any_thread_lock_.AssertAcquired();
- TRACE_COUNTER1(disabled_by_default_tracing_category_, GetName(),
- any_thread().immediate_incoming_queue.size() +
- main_thread_only().immediate_work_queue->Size() +
- main_thread_only().delayed_work_queue->Size() +
- main_thread_only().delayed_incoming_queue.size());
- if (!is_locked)
- any_thread_lock_.Release();
-}
-
-void TaskQueueImpl::SetPumpPolicy(PumpPolicy pump_policy) {
- base::AutoLock lock(any_thread_lock_);
- if (pump_policy == PumpPolicy::AUTO &&
- any_thread().pump_policy != PumpPolicy::AUTO) {
- LazyNow lazy_now(main_thread_only().time_domain->CreateLazyNow());
- PumpQueueLocked(&lazy_now, true);
- }
- any_thread().pump_policy = pump_policy;
- main_thread_only().pump_policy = pump_policy;
-}
-
-TaskQueue::PumpPolicy TaskQueueImpl::GetPumpPolicy() const {
- return main_thread_only().pump_policy;
-}
-
-void TaskQueueImpl::PumpQueueLocked(LazyNow* lazy_now, bool may_post_dowork) {
- TRACE_EVENT1(disabled_by_default_tracing_category_,
- "TaskQueueImpl::PumpQueueLocked", "queue", name_);
- TaskQueueManager* task_queue_manager = any_thread().task_queue_manager;
- if (!task_queue_manager)
- return;
-
- MoveReadyDelayedTasksToDelayedWorkQueue(lazy_now);
-
- while (!any_thread().immediate_incoming_queue.empty()) {
- main_thread_only().immediate_work_queue->Push(
- std::move(any_thread().immediate_incoming_queue.front()));
- any_thread().immediate_incoming_queue.pop();
- }
-
- // |immediate_incoming_queue| is now empty so TimeDomain::UpdateQueues no
- // longer needs to consider this queue for reloading.
- main_thread_only().time_domain->UnregisterAsUpdatableTaskQueue(this);
-
- if (main_thread_only().immediate_work_queue->Empty() &&
- main_thread_only().delayed_work_queue->Empty()) {
- return;
- }
-
- if (may_post_dowork)
- task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE);
-}
-
-void TaskQueueImpl::PumpQueue(LazyNow* lazy_now, bool may_post_dowork) {
- base::AutoLock lock(any_thread_lock_);
- PumpQueueLocked(lazy_now, may_post_dowork);
-}
-
-const char* TaskQueueImpl::GetName() const {
- return name_;
-}
-
-void TaskQueueImpl::SetQueuePriority(QueuePriority priority) {
- if (!main_thread_only().task_queue_manager || priority == GetQueuePriority())
- return;
- main_thread_only().task_queue_manager->selector_.SetQueuePriority(this,
- priority);
-}
-
-TaskQueueImpl::QueuePriority TaskQueueImpl::GetQueuePriority() const {
- size_t set_index = immediate_work_queue()->work_queue_set_index();
- DCHECK_EQ(set_index, delayed_work_queue()->work_queue_set_index());
- return static_cast<TaskQueue::QueuePriority>(set_index);
-}
-
-// static
-const char* TaskQueueImpl::PumpPolicyToString(
- TaskQueue::PumpPolicy pump_policy) {
- switch (pump_policy) {
- case TaskQueue::PumpPolicy::AUTO:
- return "auto";
- case TaskQueue::PumpPolicy::AFTER_WAKEUP:
- return "after_wakeup";
- case TaskQueue::PumpPolicy::MANUAL:
- return "manual";
- default:
- NOTREACHED();
- return nullptr;
- }
-}
-
-// static
-const char* TaskQueueImpl::WakeupPolicyToString(
- TaskQueue::WakeupPolicy wakeup_policy) {
- switch (wakeup_policy) {
- case TaskQueue::WakeupPolicy::CAN_WAKE_OTHER_QUEUES:
- return "can_wake_other_queues";
- case TaskQueue::WakeupPolicy::DONT_WAKE_OTHER_QUEUES:
- return "dont_wake_other_queues";
- default:
- NOTREACHED();
- return nullptr;
- }
-}
-
-// static
-const char* TaskQueueImpl::PriorityToString(QueuePriority priority) {
- switch (priority) {
- case CONTROL_PRIORITY:
- return "control";
- case HIGH_PRIORITY:
- return "high";
- case NORMAL_PRIORITY:
- return "normal";
- case BEST_EFFORT_PRIORITY:
- return "best_effort";
- default:
- NOTREACHED();
- return nullptr;
- }
-}
-
-void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const {
- base::AutoLock lock(any_thread_lock_);
- state->BeginDictionary();
- state->SetString("name", GetName());
- state->SetBoolean("enabled", main_thread_only().is_enabled);
- state->SetString("time_domain_name",
- main_thread_only().time_domain->GetName());
- state->SetString("pump_policy", PumpPolicyToString(any_thread().pump_policy));
- state->SetString("wakeup_policy", WakeupPolicyToString(wakeup_policy_));
- bool verbose_tracing_enabled = false;
- TRACE_EVENT_CATEGORY_GROUP_ENABLED(
- disabled_by_default_verbose_tracing_category_, &verbose_tracing_enabled);
- state->SetInteger("immediate_incoming_queue_size",
- any_thread().immediate_incoming_queue.size());
- state->SetInteger("delayed_incoming_queue_size",
- main_thread_only().delayed_incoming_queue.size());
- state->SetInteger("immediate_work_queue_size",
- main_thread_only().immediate_work_queue->Size());
- state->SetInteger("delayed_work_queue_size",
- main_thread_only().delayed_work_queue->Size());
- if (!main_thread_only().delayed_incoming_queue.empty()) {
- base::TimeDelta delay_to_next_task =
- (main_thread_only().delayed_incoming_queue.top().delayed_run_time -
- main_thread_only().time_domain->CreateLazyNow().Now());
- state->SetDouble("delay_to_next_task_ms",
- delay_to_next_task.InMillisecondsF());
- }
- if (verbose_tracing_enabled) {
- state->BeginArray("immediate_incoming_queue");
- QueueAsValueInto(any_thread().immediate_incoming_queue, state);
- state->EndArray();
- state->BeginArray("delayed_work_queue");
- main_thread_only().delayed_work_queue->AsValueInto(state);
- state->EndArray();
- state->BeginArray("immediate_work_queue");
- main_thread_only().immediate_work_queue->AsValueInto(state);
- state->EndArray();
- state->BeginArray("delayed_incoming_queue");
- QueueAsValueInto(main_thread_only().delayed_incoming_queue, state);
- state->EndArray();
- }
- state->SetString("priority", PriorityToString(GetQueuePriority()));
- state->EndDictionary();
-}
-
-void TaskQueueImpl::AddTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) {
- main_thread_only().task_observers.AddObserver(task_observer);
-}
-
-void TaskQueueImpl::RemoveTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) {
- main_thread_only().task_observers.RemoveObserver(task_observer);
-}
-
-void TaskQueueImpl::NotifyWillProcessTask(
- const base::PendingTask& pending_task) {
- DCHECK(should_notify_observers_);
- if (main_thread_only().blame_context)
- main_thread_only().blame_context->Enter();
- FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver,
- main_thread_only().task_observers,
- WillProcessTask(pending_task));
-}
-
-void TaskQueueImpl::NotifyDidProcessTask(
- const base::PendingTask& pending_task) {
- DCHECK(should_notify_observers_);
- FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver,
- main_thread_only().task_observers,
- DidProcessTask(pending_task));
- if (main_thread_only().blame_context)
- main_thread_only().blame_context->Leave();
-}
-
-void TaskQueueImpl::SetTimeDomain(TimeDomain* time_domain) {
- base::AutoLock lock(any_thread_lock_);
- DCHECK(time_domain);
- // NOTE this is similar to checking |any_thread().task_queue_manager| but the
- // TaskQueueSelectorTests constructs TaskQueueImpl directly with a null
- // task_queue_manager. Instead we check |any_thread().time_domain| which is
- // another way of asserting that UnregisterTaskQueue has not been called.
- DCHECK(any_thread().time_domain);
- if (!any_thread().time_domain)
- return;
- DCHECK(main_thread_checker_.CalledOnValidThread());
- if (time_domain == main_thread_only().time_domain)
- return;
-
- main_thread_only().time_domain->MigrateQueue(this, time_domain);
- main_thread_only().time_domain = time_domain;
- any_thread().time_domain = time_domain;
-}
-
-TimeDomain* TaskQueueImpl::GetTimeDomain() const {
- if (base::PlatformThread::CurrentId() == thread_id_)
- return main_thread_only().time_domain;
-
- base::AutoLock lock(any_thread_lock_);
- return any_thread().time_domain;
-}
-
-void TaskQueueImpl::SetBlameContext(
- base::trace_event::BlameContext* blame_context) {
- main_thread_only().blame_context = blame_context;
-}
-
-// static
-void TaskQueueImpl::QueueAsValueInto(const std::queue<Task>& queue,
- base::trace_event::TracedValue* state) {
- std::queue<Task> queue_copy(queue);
- while (!queue_copy.empty()) {
- TaskAsValueInto(queue_copy.front(), state);
- queue_copy.pop();
- }
-}
-
-// static
-void TaskQueueImpl::QueueAsValueInto(const std::priority_queue<Task>& queue,
- base::trace_event::TracedValue* state) {
- std::priority_queue<Task> queue_copy(queue);
- while (!queue_copy.empty()) {
- TaskAsValueInto(queue_copy.top(), state);
- queue_copy.pop();
- }
-}
-
-// static
-void TaskQueueImpl::TaskAsValueInto(const Task& task,
- base::trace_event::TracedValue* state) {
- state->BeginDictionary();
- state->SetString("posted_from", task.posted_from.ToString());
-#ifndef NDEBUG
- if (task.enqueue_order_set())
- state->SetInteger("enqueue_order", task.enqueue_order());
-#else
- state->SetInteger("enqueue_order", task.enqueue_order());
-#endif
- state->SetInteger("sequence_num", task.sequence_num);
- state->SetBoolean("nestable", task.nestable);
- state->SetBoolean("is_high_res", task.is_high_res);
- state->SetDouble(
- "delayed_run_time",
- (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L);
- state->EndDictionary();
-}
-
-} // namespace internal
-} // namespace scheduler
diff --git a/chromium/components/scheduler/base/task_queue_impl.h b/chromium/components/scheduler/base/task_queue_impl.h
deleted file mode 100644
index 0e7f007204a..00000000000
--- a/chromium/components/scheduler/base/task_queue_impl.h
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright 2015 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 CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_IMPL_H_
-#define CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_IMPL_H_
-
-#include <stddef.h>
-
-#include <memory>
-#include <set>
-
-#include "base/macros.h"
-#include "base/pending_task.h"
-#include "base/threading/thread_checker.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "components/scheduler/base/enqueue_order.h"
-#include "components/scheduler/base/task_queue.h"
-#include "components/scheduler/scheduler_export.h"
-
-namespace scheduler {
-class LazyNow;
-class TimeDomain;
-class TaskQueueManager;
-
-namespace internal {
-class WorkQueue;
-class WorkQueueSets;
-
-class SCHEDULER_EXPORT TaskQueueImpl final : public TaskQueue {
- public:
- TaskQueueImpl(TaskQueueManager* task_queue_manager,
- TimeDomain* time_domain,
- const Spec& spec,
- const char* disabled_by_default_tracing_category,
- const char* disabled_by_default_verbose_tracing_category);
-
- class SCHEDULER_EXPORT Task : public base::PendingTask {
- public:
- Task();
- Task(const tracked_objects::Location& posted_from,
- const base::Closure& task,
- base::TimeTicks desired_run_time,
- EnqueueOrder sequence_number,
- bool nestable);
-
- Task(const tracked_objects::Location& posted_from,
- const base::Closure& task,
- base::TimeTicks desired_run_time,
- EnqueueOrder sequence_number,
- bool nestable,
- EnqueueOrder enqueue_order);
-
- EnqueueOrder enqueue_order() const {
-#ifndef NDEBUG
- DCHECK(enqueue_order_set_);
-#endif
- return enqueue_order_;
- }
-
- void set_enqueue_order(EnqueueOrder enqueue_order) {
-#ifndef NDEBUG
- DCHECK(!enqueue_order_set_);
- enqueue_order_set_ = true;
-#endif
- enqueue_order_ = enqueue_order;
- }
-
-#ifndef NDEBUG
- bool enqueue_order_set() const { return enqueue_order_set_; }
-#endif
-
- private:
-#ifndef NDEBUG
- bool enqueue_order_set_;
-#endif
- // Similar to sequence number, but the |enqueue_order| is set by
- // EnqueueTasksLocked and is not initially defined for delayed tasks until
- // they are enqueued on the |immediate_incoming_queue_|.
- EnqueueOrder enqueue_order_;
- };
-
- // TaskQueue implementation.
- void UnregisterTaskQueue() override;
- bool RunsTasksOnCurrentThread() const override;
- bool PostDelayedTask(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) override;
- bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) override;
-
- void SetQueueEnabled(bool enabled) override;
- bool IsQueueEnabled() const override;
- bool IsEmpty() const override;
- bool HasPendingImmediateWork() const override;
- bool NeedsPumping() const override;
- void SetQueuePriority(QueuePriority priority) override;
- QueuePriority GetQueuePriority() const override;
- void PumpQueue(LazyNow* lazy_now, bool may_post_dowork) override;
- void SetPumpPolicy(PumpPolicy pump_policy) override;
- PumpPolicy GetPumpPolicy() const override;
- void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer) override;
- void RemoveTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) override;
- void SetTimeDomain(TimeDomain* time_domain) override;
- TimeDomain* GetTimeDomain() const override;
- void SetBlameContext(base::trace_event::BlameContext* blame_context) override;
-
- void UpdateImmediateWorkQueue(bool should_trigger_wakeup,
- const Task* previous_task);
- void UpdateDelayedWorkQueue(LazyNow* lazy_now,
- bool should_trigger_wakeup,
- const Task* previous_task);
-
- WakeupPolicy wakeup_policy() const {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- return wakeup_policy_;
- }
-
- const char* GetName() const override;
-
- void AsValueInto(base::trace_event::TracedValue* state) const;
-
- bool GetQuiescenceMonitored() const { return should_monitor_quiescence_; }
- bool GetShouldNotifyObservers() const {
- return should_notify_observers_;
- }
-
- void NotifyWillProcessTask(const base::PendingTask& pending_task);
- void NotifyDidProcessTask(const base::PendingTask& pending_task);
-
- // Can be called on any thread.
- static const char* PumpPolicyToString(TaskQueue::PumpPolicy pump_policy);
-
- // Can be called on any thread.
- static const char* WakeupPolicyToString(
- TaskQueue::WakeupPolicy wakeup_policy);
-
- // Can be called on any thread.
- static const char* PriorityToString(TaskQueue::QueuePriority priority);
-
- WorkQueue* delayed_work_queue() {
- return main_thread_only().delayed_work_queue.get();
- }
-
- const WorkQueue* delayed_work_queue() const {
- return main_thread_only().delayed_work_queue.get();
- }
-
- WorkQueue* immediate_work_queue() {
- return main_thread_only().immediate_work_queue.get();
- }
-
- const WorkQueue* immediate_work_queue() const {
- return main_thread_only().immediate_work_queue.get();
- }
-
- bool should_report_when_execution_blocked() const {
- return should_report_when_execution_blocked_;
- }
-
- private:
- friend class WorkQueue;
-
- enum class TaskType {
- NORMAL,
- NON_NESTABLE,
- };
-
- struct AnyThread {
- AnyThread(TaskQueueManager* task_queue_manager,
- PumpPolicy pump_policy,
- TimeDomain* time_domain);
- ~AnyThread();
-
- // TaskQueueManager, PumpPolicy and TimeDomain are maintained in two copies:
- // inside AnyThread and inside MainThreadOnly. They can be changed only from
- // main thread, so it should be locked before accessing from other threads.
- TaskQueueManager* task_queue_manager;
- PumpPolicy pump_policy;
- TimeDomain* time_domain;
-
- std::queue<Task> immediate_incoming_queue;
- };
-
- struct MainThreadOnly {
- MainThreadOnly(TaskQueueManager* task_queue_manager,
- PumpPolicy pump_policy,
- TaskQueueImpl* task_queue,
- TimeDomain* time_domain);
- ~MainThreadOnly();
-
- // Another copy of TaskQueueManager, PumpPolicy and TimeDomain for lock-free
- // access from the main thread. See description inside struct AnyThread for
- // details.
- TaskQueueManager* task_queue_manager;
- PumpPolicy pump_policy;
- TimeDomain* time_domain;
-
- std::unique_ptr<WorkQueue> delayed_work_queue;
- std::unique_ptr<WorkQueue> immediate_work_queue;
- std::priority_queue<Task> delayed_incoming_queue;
- base::ObserverList<base::MessageLoop::TaskObserver> task_observers;
- size_t set_index;
- bool is_enabled;
- base::trace_event::BlameContext* blame_context; // Not owned.
- };
-
- ~TaskQueueImpl() override;
-
- bool PostImmediateTaskImpl(const tracked_objects::Location& from_here,
- const base::Closure& task,
- TaskType task_type);
- bool PostDelayedTaskImpl(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay,
- TaskType task_type);
-
- // Push the task onto the |delayed_incoming_queue|. Lock-free main thread
- // only fast path.
- void PushOntoDelayedIncomingQueueFromMainThread(const Task& pending_task,
- base::TimeTicks now);
-
- // Push the task onto the |delayed_incoming_queue|. Slow path from other
- // threads.
- void PushOntoDelayedIncomingQueueLocked(const Task& pending_task);
-
- void ScheduleDelayedWorkTask(const Task& pending_task);
-
- // Enqueues any delayed tasks which should be run now on the
- // |delayed_work_queue|. Must be called from the main thread.
- void MoveReadyDelayedTasksToDelayedWorkQueue(LazyNow* lazy_now);
-
- void MoveReadyImmediateTasksToImmediateWorkQueueLocked();
-
- // Note this does nothing if its not called from the main thread.
- void PumpQueueLocked(LazyNow* lazy_now, bool may_post_dowork);
-
- // Returns true if |task| is older than the oldest incoming immediate task.
- // NOTE |any_thread_lock_| must be locked.
- bool TaskIsOlderThanQueuedImmediateTasksLocked(const Task* task);
-
- // Returns true if |task| is older than the oldest delayed task. Must be
- // called from the main thread.
- bool TaskIsOlderThanQueuedDelayedTasks(const Task* task);
-
- // NOTE |any_thread_lock_| must be locked.
- bool ShouldAutoPumpImmediateQueueLocked(bool should_trigger_wakeup,
- const Task* previous_task);
-
- // Must be called from the main thread.
- bool ShouldAutoPumpDelayedQueue(bool should_trigger_wakeup,
- const Task* previous_task);
-
- // Push the task onto the |immediate_incoming_queue| and for auto pumped
- // queues it calls MaybePostDoWorkOnMainRunner if the Incoming queue was
- // empty.
- void PushOntoImmediateIncomingQueueLocked(const Task& pending_task);
-
- void TraceQueueSize(bool is_locked) const;
- static void QueueAsValueInto(const std::queue<Task>& queue,
- base::trace_event::TracedValue* state);
- static void QueueAsValueInto(const std::priority_queue<Task>& queue,
- base::trace_event::TracedValue* state);
- static void TaskAsValueInto(const Task& task,
- base::trace_event::TracedValue* state);
-
- const base::PlatformThreadId thread_id_;
-
- mutable base::Lock any_thread_lock_;
- AnyThread any_thread_;
- struct AnyThread& any_thread() {
- any_thread_lock_.AssertAcquired();
- return any_thread_;
- }
- const struct AnyThread& any_thread() const {
- any_thread_lock_.AssertAcquired();
- return any_thread_;
- }
-
- const char* name_;
- const char* disabled_by_default_tracing_category_;
- const char* disabled_by_default_verbose_tracing_category_;
-
- base::ThreadChecker main_thread_checker_;
- MainThreadOnly main_thread_only_;
- MainThreadOnly& main_thread_only() {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- return main_thread_only_;
- }
- const MainThreadOnly& main_thread_only() const {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- return main_thread_only_;
- }
-
- const WakeupPolicy wakeup_policy_;
- const bool should_monitor_quiescence_;
- const bool should_notify_observers_;
- const bool should_report_when_execution_blocked_;
-
- DISALLOW_COPY_AND_ASSIGN(TaskQueueImpl);
-};
-
-} // namespace internal
-} // namespace scheduler
-
-#endif // CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_IMPL_H_
diff --git a/chromium/components/scheduler/base/task_queue_manager.cc b/chromium/components/scheduler/base/task_queue_manager.cc
deleted file mode 100644
index 36f08de540f..00000000000
--- a/chromium/components/scheduler/base/task_queue_manager.cc
+++ /dev/null
@@ -1,418 +0,0 @@
-// Copyright 2014 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/scheduler/base/task_queue_manager.h"
-
-#include <queue>
-#include <set>
-
-#include "base/bind.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/trace_event/trace_event.h"
-#include "components/scheduler/base/real_time_domain.h"
-#include "components/scheduler/base/task_queue_impl.h"
-#include "components/scheduler/base/task_queue_manager_delegate.h"
-#include "components/scheduler/base/task_queue_selector.h"
-#include "components/scheduler/base/work_queue.h"
-#include "components/scheduler/base/work_queue_sets.h"
-
-namespace scheduler {
-
-namespace {
-const size_t kRecordRecordTaskDelayHistogramsEveryNTasks = 10;
-
-void RecordDelayedTaskLateness(base::TimeDelta lateness) {
- UMA_HISTOGRAM_TIMES("RendererScheduler.TaskQueueManager.DelayedTaskLateness",
- lateness);
-}
-
-void RecordImmediateTaskQueueingDuration(tracked_objects::Duration duration) {
- UMA_HISTOGRAM_TIMES(
- "RendererScheduler.TaskQueueManager.ImmediateTaskQueueingDuration",
- base::TimeDelta::FromMilliseconds(duration.InMilliseconds()));
-}
-}
-
-TaskQueueManager::TaskQueueManager(
- scoped_refptr<TaskQueueManagerDelegate> delegate,
- const char* tracing_category,
- const char* disabled_by_default_tracing_category,
- const char* disabled_by_default_verbose_tracing_category)
- : real_time_domain_(new RealTimeDomain(tracing_category)),
- delegate_(delegate),
- task_was_run_on_quiescence_monitored_queue_(false),
- work_batch_size_(1),
- task_count_(0),
- tracing_category_(tracing_category),
- disabled_by_default_tracing_category_(
- disabled_by_default_tracing_category),
- disabled_by_default_verbose_tracing_category_(
- disabled_by_default_verbose_tracing_category),
- currently_executing_task_queue_(nullptr),
- observer_(nullptr),
- deletion_sentinel_(new DeletionSentinel()),
- weak_factory_(this) {
- DCHECK(delegate->RunsTasksOnCurrentThread());
- TRACE_EVENT_OBJECT_CREATED_WITH_ID(disabled_by_default_tracing_category,
- "TaskQueueManager", this);
- selector_.SetTaskQueueSelectorObserver(this);
-
- from_main_thread_immediate_do_work_closure_ =
- base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(),
- base::TimeTicks(), true);
- from_other_thread_immediate_do_work_closure_ =
- base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(),
- base::TimeTicks(), false);
-
- // TODO(alexclarke): Change this to be a parameter that's passed in.
- RegisterTimeDomain(real_time_domain_.get());
-}
-
-TaskQueueManager::~TaskQueueManager() {
- TRACE_EVENT_OBJECT_DELETED_WITH_ID(disabled_by_default_tracing_category_,
- "TaskQueueManager", this);
-
- while (!queues_.empty())
- (*queues_.begin())->UnregisterTaskQueue();
-
- selector_.SetTaskQueueSelectorObserver(nullptr);
-}
-
-void TaskQueueManager::RegisterTimeDomain(TimeDomain* time_domain) {
- time_domains_.insert(time_domain);
- time_domain->OnRegisterWithTaskQueueManager(this);
-}
-
-void TaskQueueManager::UnregisterTimeDomain(TimeDomain* time_domain) {
- time_domains_.erase(time_domain);
-}
-
-scoped_refptr<internal::TaskQueueImpl> TaskQueueManager::NewTaskQueue(
- const TaskQueue::Spec& spec) {
- TRACE_EVENT1(tracing_category_,
- "TaskQueueManager::NewTaskQueue", "queue_name", spec.name);
- DCHECK(main_thread_checker_.CalledOnValidThread());
- TimeDomain* time_domain =
- spec.time_domain ? spec.time_domain : real_time_domain_.get();
- DCHECK(time_domains_.find(time_domain) != time_domains_.end());
- scoped_refptr<internal::TaskQueueImpl> queue(
- make_scoped_refptr(new internal::TaskQueueImpl(
- this, time_domain, spec, disabled_by_default_tracing_category_,
- disabled_by_default_verbose_tracing_category_)));
- queues_.insert(queue);
- selector_.AddQueue(queue.get());
- return queue;
-}
-
-void TaskQueueManager::SetObserver(Observer* observer) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- observer_ = observer;
-}
-
-void TaskQueueManager::UnregisterTaskQueue(
- scoped_refptr<internal::TaskQueueImpl> task_queue) {
- TRACE_EVENT1(tracing_category_,
- "TaskQueueManager::UnregisterTaskQueue", "queue_name",
- task_queue->GetName());
- DCHECK(main_thread_checker_.CalledOnValidThread());
- if (observer_)
- observer_->OnUnregisterTaskQueue(task_queue);
-
- // Add |task_queue| to |queues_to_delete_| so we can prevent it from being
- // freed while any of our structures hold hold a raw pointer to it.
- queues_to_delete_.insert(task_queue);
- queues_.erase(task_queue);
- selector_.RemoveQueue(task_queue.get());
-}
-
-void TaskQueueManager::UpdateWorkQueues(
- bool should_trigger_wakeup,
- const internal::TaskQueueImpl::Task* previous_task) {
- TRACE_EVENT0(disabled_by_default_tracing_category_,
- "TaskQueueManager::UpdateWorkQueues");
-
- for (TimeDomain* time_domain : time_domains_) {
- time_domain->UpdateWorkQueues(should_trigger_wakeup, previous_task);
- }
-}
-
-void TaskQueueManager::MaybeScheduleImmediateWork(
- const tracked_objects::Location& from_here) {
- bool on_main_thread = delegate_->BelongsToCurrentThread();
- // De-duplicate DoWork posts.
- if (on_main_thread) {
- if (!main_thread_pending_wakeups_.insert(base::TimeTicks()).second) {
- return;
- }
- delegate_->PostTask(from_here, from_main_thread_immediate_do_work_closure_);
- } else {
- {
- base::AutoLock lock(other_thread_lock_);
- if (!other_thread_pending_wakeups_.insert(base::TimeTicks()).second)
- return;
- }
- delegate_->PostTask(from_here,
- from_other_thread_immediate_do_work_closure_);
- }
-}
-
-void TaskQueueManager::MaybeScheduleDelayedWork(
- const tracked_objects::Location& from_here,
- base::TimeTicks now,
- base::TimeDelta delay) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- DCHECK_GE(delay, base::TimeDelta());
- base::TimeTicks run_time = now + delay;
- // De-duplicate DoWork posts.
- if (!main_thread_pending_wakeups_.insert(run_time).second)
- return;
- delegate_->PostDelayedTask(
- from_here, base::Bind(&TaskQueueManager::DoWork,
- weak_factory_.GetWeakPtr(), run_time, true),
- delay);
-}
-
-void TaskQueueManager::DoWork(base::TimeTicks run_time, bool from_main_thread) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- TRACE_EVENT1(tracing_category_, "TaskQueueManager::DoWork",
- "from_main_thread", from_main_thread);
- if (from_main_thread) {
- main_thread_pending_wakeups_.erase(run_time);
- } else {
- base::AutoLock lock(other_thread_lock_);
- other_thread_pending_wakeups_.erase(run_time);
- }
-
- if (!delegate_->IsNested())
- queues_to_delete_.clear();
-
- // Pass false and nullptr to UpdateWorkQueues here to prevent waking up a
- // pump-after-wakeup queue.
- UpdateWorkQueues(false, nullptr);
-
- internal::TaskQueueImpl::Task previous_task;
- for (int i = 0; i < work_batch_size_; i++) {
- internal::WorkQueue* work_queue;
- if (!SelectWorkQueueToService(&work_queue)) {
- break;
- }
-
- bool should_trigger_wakeup = work_queue->task_queue()->wakeup_policy() ==
- TaskQueue::WakeupPolicy::CAN_WAKE_OTHER_QUEUES;
- switch (ProcessTaskFromWorkQueue(work_queue, &previous_task)) {
- case ProcessTaskResult::DEFERRED:
- // If a task was deferred, try again with another task. Note that this
- // means deferred tasks (i.e. non-nestable tasks) will never trigger
- // queue wake-ups.
- continue;
- case ProcessTaskResult::EXECUTED:
- break;
- case ProcessTaskResult::TASK_QUEUE_MANAGER_DELETED:
- return; // The TaskQueueManager got deleted, we must bail out.
- }
- work_queue = nullptr; // The queue may have been unregistered.
-
- UpdateWorkQueues(should_trigger_wakeup, &previous_task);
-
- // Only run a single task per batch in nested run loops so that we can
- // properly exit the nested loop when someone calls RunLoop::Quit().
- if (delegate_->IsNested())
- break;
- }
-
- // TODO(alexclarke): Consider refactoring the above loop to terminate only
- // when there's no more work left to be done, rather than posting a
- // continuation task.
- if (!selector_.EnabledWorkQueuesEmpty() || TryAdvanceTimeDomains())
- MaybeScheduleImmediateWork(FROM_HERE);
-}
-
-bool TaskQueueManager::TryAdvanceTimeDomains() {
- bool can_advance = false;
- for (TimeDomain* time_domain : time_domains_) {
- can_advance |= time_domain->MaybeAdvanceTime();
- }
- return can_advance;
-}
-
-bool TaskQueueManager::SelectWorkQueueToService(
- internal::WorkQueue** out_work_queue) {
- bool should_run = selector_.SelectWorkQueueToService(out_work_queue);
- TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
- disabled_by_default_tracing_category_, "TaskQueueManager", this,
- AsValueWithSelectorResult(should_run, *out_work_queue));
- return should_run;
-}
-
-void TaskQueueManager::DidQueueTask(
- const internal::TaskQueueImpl::Task& pending_task) {
- task_annotator_.DidQueueTask("TaskQueueManager::PostTask", pending_task);
-}
-
-TaskQueueManager::ProcessTaskResult TaskQueueManager::ProcessTaskFromWorkQueue(
- internal::WorkQueue* work_queue,
- internal::TaskQueueImpl::Task* out_previous_task) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- scoped_refptr<DeletionSentinel> protect(deletion_sentinel_);
- internal::TaskQueueImpl* queue = work_queue->task_queue();
-
- if (queue->GetQuiescenceMonitored())
- task_was_run_on_quiescence_monitored_queue_ = true;
-
- internal::TaskQueueImpl::Task pending_task =
- work_queue->TakeTaskFromWorkQueue();
- if (!pending_task.nestable && delegate_->IsNested()) {
- // Defer non-nestable work to the main task runner. NOTE these tasks can be
- // arbitrarily delayed so the additional delay should not be a problem.
- // TODO(skyostil): Figure out a way to not forget which task queue the
- // task is associated with. See http://crbug.com/522843.
- delegate_->PostNonNestableTask(pending_task.posted_from, pending_task.task);
- return ProcessTaskResult::DEFERRED;
- }
-
- MaybeRecordTaskDelayHistograms(pending_task, queue);
-
- TRACE_TASK_EXECUTION("TaskQueueManager::ProcessTaskFromWorkQueue",
- pending_task);
- if (queue->GetShouldNotifyObservers()) {
- FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, task_observers_,
- WillProcessTask(pending_task));
- queue->NotifyWillProcessTask(pending_task);
- }
- TRACE_EVENT1(tracing_category_,
- "TaskQueueManager::RunTask", "queue", queue->GetName());
- // NOTE when TaskQueues get unregistered a reference ends up getting retained
- // by |queues_to_delete_| which is cleared at the top of |DoWork|. This means
- // we are OK to use raw pointers here.
- internal::TaskQueueImpl* prev_executing_task_queue =
- currently_executing_task_queue_;
- currently_executing_task_queue_ = queue;
- task_annotator_.RunTask("TaskQueueManager::PostTask", pending_task);
-
- // Detect if the TaskQueueManager just got deleted. If this happens we must
- // not access any member variables after this point.
- if (protect->HasOneRef())
- return ProcessTaskResult::TASK_QUEUE_MANAGER_DELETED;
-
- currently_executing_task_queue_ = prev_executing_task_queue;
-
- if (queue->GetShouldNotifyObservers()) {
- FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, task_observers_,
- DidProcessTask(pending_task));
- queue->NotifyDidProcessTask(pending_task);
- }
-
- pending_task.task.Reset();
- *out_previous_task = pending_task;
- return ProcessTaskResult::EXECUTED;
-}
-
-void TaskQueueManager::MaybeRecordTaskDelayHistograms(
- const internal::TaskQueueImpl::Task& pending_task,
- const internal::TaskQueueImpl* queue) {
- if ((task_count_++ % kRecordRecordTaskDelayHistogramsEveryNTasks) != 0)
- return;
-
- // Record delayed task lateness and immediate task queueing durations, but
- // only for auto-pumped queues. Manually pumped and after wakeup queues can
- // have arbitarially large delayes, which would cloud any analysis.
- if (queue->GetPumpPolicy() == TaskQueue::PumpPolicy::AUTO) {
- if (!pending_task.delayed_run_time.is_null()) {
- RecordDelayedTaskLateness(delegate_->NowTicks() -
- pending_task.delayed_run_time);
- } else if (!pending_task.time_posted.is_null()) {
- RecordImmediateTaskQueueingDuration(tracked_objects::TrackedTime::Now() -
- pending_task.time_posted);
- }
- }
-}
-
-bool TaskQueueManager::RunsTasksOnCurrentThread() const {
- return delegate_->RunsTasksOnCurrentThread();
-}
-
-void TaskQueueManager::SetWorkBatchSize(int work_batch_size) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- DCHECK_GE(work_batch_size, 1);
- work_batch_size_ = work_batch_size;
-}
-
-void TaskQueueManager::AddTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- task_observers_.AddObserver(task_observer);
-}
-
-void TaskQueueManager::RemoveTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- task_observers_.RemoveObserver(task_observer);
-}
-
-bool TaskQueueManager::GetAndClearSystemIsQuiescentBit() {
- bool task_was_run = task_was_run_on_quiescence_monitored_queue_;
- task_was_run_on_quiescence_monitored_queue_ = false;
- return !task_was_run;
-}
-
-const scoped_refptr<TaskQueueManagerDelegate>& TaskQueueManager::delegate()
- const {
- return delegate_;
-}
-
-internal::EnqueueOrder TaskQueueManager::GetNextSequenceNumber() {
- return enqueue_order_generator_.GenerateNext();
-}
-
-LazyNow TaskQueueManager::CreateLazyNow() const {
- return LazyNow(delegate_.get());
-}
-
-std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
-TaskQueueManager::AsValueWithSelectorResult(
- bool should_run,
- internal::WorkQueue* selected_work_queue) const {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- std::unique_ptr<base::trace_event::TracedValue> state(
- new base::trace_event::TracedValue());
- state->BeginArray("queues");
- for (auto& queue : queues_)
- queue->AsValueInto(state.get());
- state->EndArray();
- state->BeginDictionary("selector");
- selector_.AsValueInto(state.get());
- state->EndDictionary();
- if (should_run) {
- state->SetString("selected_queue",
- selected_work_queue->task_queue()->GetName());
- state->SetString("work_queue_name", selected_work_queue->name());
- }
-
- state->BeginArray("time_domains");
- for (auto& time_domain : time_domains_)
- time_domain->AsValueInto(state.get());
- state->EndArray();
- return std::move(state);
-}
-
-void TaskQueueManager::OnTaskQueueEnabled(internal::TaskQueueImpl* queue) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- // Only schedule DoWork if there's something to do.
- if (!queue->immediate_work_queue()->Empty() ||
- !queue->delayed_work_queue()->Empty()) {
- MaybeScheduleImmediateWork(FROM_HERE);
- }
-}
-
-void TaskQueueManager::OnTriedToSelectBlockedWorkQueue(
- internal::WorkQueue* work_queue) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- DCHECK(!work_queue->Empty());
- if (observer_) {
- observer_->OnTriedToExecuteBlockedTask(*work_queue->task_queue(),
- *work_queue->GetFrontTask());
- }
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/base/task_queue_manager.h b/chromium/components/scheduler/base/task_queue_manager.h
deleted file mode 100644
index 1e9eef4d281..00000000000
--- a/chromium/components/scheduler/base/task_queue_manager.h
+++ /dev/null
@@ -1,257 +0,0 @@
-// Copyright 2014 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 CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_
-#define CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_
-
-#include <map>
-
-#include "base/atomic_sequence_num.h"
-#include "base/debug/task_annotator.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/pending_task.h"
-#include "base/synchronization/lock.h"
-#include "base/threading/thread_checker.h"
-#include "components/scheduler/base/enqueue_order.h"
-#include "components/scheduler/base/task_queue_impl.h"
-#include "components/scheduler/base/task_queue_selector.h"
-#include "components/scheduler/scheduler_export.h"
-
-namespace base {
-class TickClock;
-
-namespace trace_event {
-class ConvertableToTraceFormat;
-class TracedValue;
-} // namespace trace_event
-} // namespace base
-
-namespace scheduler {
-namespace internal {
-class TaskQueueImpl;
-} // namespace internal
-
-class LazyNow;
-class RealTimeDomain;
-class TimeDomain;
-class TaskQueueManagerDelegate;
-
-// The task queue manager provides N task queues and a selector interface for
-// choosing which task queue to service next. Each task queue consists of two
-// sub queues:
-//
-// 1. Incoming task queue. Tasks that are posted get immediately appended here.
-// When a task is appended into an empty incoming queue, the task manager
-// work function (DoWork) is scheduled to run on the main task runner.
-//
-// 2. Work queue. If a work queue is empty when DoWork() is entered, tasks from
-// the incoming task queue (if any) are moved here. The work queues are
-// registered with the selector as input to the scheduling decision.
-//
-class SCHEDULER_EXPORT TaskQueueManager
- : public internal::TaskQueueSelector::Observer {
- public:
- // Create a task queue manager where |delegate| identifies the thread
- // on which where the tasks are eventually run. Category strings must have
- // application lifetime (statics or literals). They may not include " chars.
- TaskQueueManager(scoped_refptr<TaskQueueManagerDelegate> delegate,
- const char* tracing_category,
- const char* disabled_by_default_tracing_category,
- const char* disabled_by_default_verbose_tracing_category);
- ~TaskQueueManager() override;
-
- // Requests that a task to process work is posted on the main task runner.
- // These tasks are de-duplicated in two buckets: main-thread and all other
- // threads. This distinction is done to reduce the overehead from locks, we
- // assume the main-thread path will be hot.
- void MaybeScheduleImmediateWork(const tracked_objects::Location& from_here);
-
- // Requests that a delayed task to process work is posted on the main task
- // runner. These delayed tasks are de-duplicated. Must be called on the thread
- // this class was created on.
- void MaybeScheduleDelayedWork(const tracked_objects::Location& from_here,
- base::TimeTicks now,
- base::TimeDelta delay);
-
- // Set the number of tasks executed in a single invocation of the task queue
- // manager. Increasing the batch size can reduce the overhead of yielding
- // back to the main message loop -- at the cost of potentially delaying other
- // tasks posted to the main loop. The batch size is 1 by default.
- void SetWorkBatchSize(int work_batch_size);
-
- // These functions can only be called on the same thread that the task queue
- // manager executes its tasks on.
- void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer);
- void RemoveTaskObserver(base::MessageLoop::TaskObserver* task_observer);
-
- // Returns true if any task from a monitored task queue was was run since the
- // last call to GetAndClearSystemIsQuiescentBit.
- bool GetAndClearSystemIsQuiescentBit();
-
- // Creates a task queue with the given |spec|. Must be called on the thread
- // this class was created on.
- scoped_refptr<internal::TaskQueueImpl> NewTaskQueue(
- const TaskQueue::Spec& spec);
-
- class SCHEDULER_EXPORT Observer {
- public:
- virtual ~Observer() {}
-
- // Called when |queue| is unregistered.
- virtual void OnUnregisterTaskQueue(
- const scoped_refptr<TaskQueue>& queue) = 0;
-
- // Called when the manager tried to execute a task from a disabled
- // queue. See TaskQueue::Spec::SetShouldReportWhenExecutionBlocked.
- virtual void OnTriedToExecuteBlockedTask(const TaskQueue& queue,
- const base::PendingTask& task) = 0;
- };
-
- // Called once to set the Observer. This function is called on the main
- // thread. If |observer| is null, then no callbacks will occur.
- // Note |observer| is expected to outlive the SchedulerHelper.
- void SetObserver(Observer* observer);
-
- // Returns the delegate used by the TaskQueueManager.
- const scoped_refptr<TaskQueueManagerDelegate>& delegate() const;
-
- // Time domains must be registered for the task queues to get updated.
- void RegisterTimeDomain(TimeDomain* time_domain);
- void UnregisterTimeDomain(TimeDomain* time_domain);
-
- RealTimeDomain* real_time_domain() const { return real_time_domain_.get(); }
-
- LazyNow CreateLazyNow() const;
-
- // Returns the currently executing TaskQueue if any. Must be called on the
- // thread this class was created on.
- TaskQueue* currently_executing_task_queue() const {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- return currently_executing_task_queue_;
- }
-
- private:
- friend class LazyNow;
- friend class internal::TaskQueueImpl;
- friend class TaskQueueManagerTest;
-
- class DeletionSentinel : public base::RefCounted<DeletionSentinel> {
- private:
- friend class base::RefCounted<DeletionSentinel>;
- ~DeletionSentinel() {}
- };
-
- // Unregisters a TaskQueue previously created by |NewTaskQueue()|.
- // NOTE we have to flush the queue from |newly_updatable_| which means as a
- // side effect MoveNewlyUpdatableQueuesIntoUpdatableQueueSet is called by this
- // function.
- void UnregisterTaskQueue(scoped_refptr<internal::TaskQueueImpl> task_queue);
-
- // TaskQueueSelector::Observer implementation:
- void OnTaskQueueEnabled(internal::TaskQueueImpl* queue) override;
- void OnTriedToSelectBlockedWorkQueue(
- internal::WorkQueue* work_queue) override;
-
- // Called by the task queue to register a new pending task.
- void DidQueueTask(const internal::TaskQueueImpl::Task& pending_task);
-
- // Use the selector to choose a pending task and run it.
- void DoWork(base::TimeTicks run_time, bool from_main_thread);
-
- // Delayed Tasks with run_times <= Now() are enqueued onto the work queue.
- // Reloads any empty work queues which have automatic pumping enabled and
- // which are eligible to be auto pumped based on the |previous_task| which was
- // run and |should_trigger_wakeup|. Call with an empty |previous_task| if no
- // task was just run.
- void UpdateWorkQueues(bool should_trigger_wakeup,
- const internal::TaskQueueImpl::Task* previous_task);
-
- // Chooses the next work queue to service. Returns true if |out_queue|
- // indicates the queue from which the next task should be run, false to
- // avoid running any tasks.
- bool SelectWorkQueueToService(internal::WorkQueue** out_work_queue);
-
- // Runs a single nestable task from the |queue|. On exit, |out_task| will
- // contain the task which was executed. Non-nestable task are reposted on the
- // run loop. The queue must not be empty.
- enum class ProcessTaskResult {
- DEFERRED,
- EXECUTED,
- TASK_QUEUE_MANAGER_DELETED
- };
- ProcessTaskResult ProcessTaskFromWorkQueue(
- internal::WorkQueue* work_queue,
- internal::TaskQueueImpl::Task* out_previous_task);
-
- bool RunsTasksOnCurrentThread() const;
- bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay);
-
- internal::EnqueueOrder GetNextSequenceNumber();
-
- // Calls MaybeAdvanceTime on all time domains and returns true if one of them
- // was able to advance.
- bool TryAdvanceTimeDomains();
-
- void MaybeRecordTaskDelayHistograms(
- const internal::TaskQueueImpl::Task& pending_task,
- const internal::TaskQueueImpl* queue);
-
- std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
- AsValueWithSelectorResult(bool should_run,
- internal::WorkQueue* selected_work_queue) const;
-
- std::set<TimeDomain*> time_domains_;
- std::unique_ptr<RealTimeDomain> real_time_domain_;
-
- std::set<scoped_refptr<internal::TaskQueueImpl>> queues_;
-
- // We have to be careful when deleting a queue because some of the code uses
- // raw pointers and doesn't expect the rug to be pulled out from underneath.
- std::set<scoped_refptr<internal::TaskQueueImpl>> queues_to_delete_;
-
- internal::EnqueueOrderGenerator enqueue_order_generator_;
- base::debug::TaskAnnotator task_annotator_;
-
- base::ThreadChecker main_thread_checker_;
- scoped_refptr<TaskQueueManagerDelegate> delegate_;
- internal::TaskQueueSelector selector_;
-
- base::Closure from_main_thread_immediate_do_work_closure_;
- base::Closure from_other_thread_immediate_do_work_closure_;
-
- bool task_was_run_on_quiescence_monitored_queue_;
-
- // To reduce locking overhead we track pending calls to DoWork seperatly for
- // the main thread and other threads.
- std::set<base::TimeTicks> main_thread_pending_wakeups_;
-
- // Protects |other_thread_pending_wakeups_|.
- mutable base::Lock other_thread_lock_;
- std::set<base::TimeTicks> other_thread_pending_wakeups_;
-
- int work_batch_size_;
- size_t task_count_;
-
- base::ObserverList<base::MessageLoop::TaskObserver> task_observers_;
-
- const char* tracing_category_;
- const char* disabled_by_default_tracing_category_;
- const char* disabled_by_default_verbose_tracing_category_;
-
- internal::TaskQueueImpl* currently_executing_task_queue_; // NOT OWNED
-
- Observer* observer_; // NOT OWNED
- scoped_refptr<DeletionSentinel> deletion_sentinel_;
- base::WeakPtrFactory<TaskQueueManager> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(TaskQueueManager);
-};
-
-} // namespace scheduler
-
-#endif // CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_
diff --git a/chromium/components/scheduler/base/task_queue_manager_delegate.h b/chromium/components/scheduler/base/task_queue_manager_delegate.h
deleted file mode 100644
index 1bb405015f4..00000000000
--- a/chromium/components/scheduler/base/task_queue_manager_delegate.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2015 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_SCHEDULER_BASE_TASK_QUEUE_MANAGER_DELEGATE_H_
-#define COMPONENTS_SCHEDULER_BASE_TASK_QUEUE_MANAGER_DELEGATE_H_
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
-#include "base/time/tick_clock.h"
-#include "components/scheduler/scheduler_export.h"
-
-namespace scheduler {
-
-class SCHEDULER_EXPORT TaskQueueManagerDelegate
- : public base::SingleThreadTaskRunner,
- public base::TickClock {
- public:
- TaskQueueManagerDelegate() {}
-
- // Returns true if the task runner is nested (i.e., running a run loop within
- // a nested task).
- virtual bool IsNested() const = 0;
-
- protected:
- ~TaskQueueManagerDelegate() override {}
-
- DISALLOW_COPY_AND_ASSIGN(TaskQueueManagerDelegate);
-};
-
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_BASE_TASK_QUEUE_MANAGER_DELEGATE_H_
diff --git a/chromium/components/scheduler/base/task_queue_manager_delegate_for_test.cc b/chromium/components/scheduler/base/task_queue_manager_delegate_for_test.cc
deleted file mode 100644
index 56380307db4..00000000000
--- a/chromium/components/scheduler/base/task_queue_manager_delegate_for_test.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2015 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/scheduler/base/task_queue_manager_delegate_for_test.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-
-namespace scheduler {
-
-// static
-scoped_refptr<TaskQueueManagerDelegateForTest>
-TaskQueueManagerDelegateForTest::Create(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- std::unique_ptr<base::TickClock> time_source) {
- return make_scoped_refptr(
- new TaskQueueManagerDelegateForTest(task_runner, std::move(time_source)));
-}
-
-TaskQueueManagerDelegateForTest::TaskQueueManagerDelegateForTest(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- std::unique_ptr<base::TickClock> time_source)
- : task_runner_(task_runner), time_source_(std::move(time_source)) {}
-
-TaskQueueManagerDelegateForTest::~TaskQueueManagerDelegateForTest() {}
-
-bool TaskQueueManagerDelegateForTest::PostDelayedTask(
- const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) {
- return task_runner_->PostDelayedTask(from_here, task, delay);
-}
-
-bool TaskQueueManagerDelegateForTest::PostNonNestableDelayedTask(
- const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) {
- return task_runner_->PostNonNestableDelayedTask(from_here, task, delay);
-}
-
-bool TaskQueueManagerDelegateForTest::RunsTasksOnCurrentThread() const {
- return task_runner_->RunsTasksOnCurrentThread();
-}
-
-bool TaskQueueManagerDelegateForTest::IsNested() const {
- return false;
-}
-
-base::TimeTicks TaskQueueManagerDelegateForTest::NowTicks() {
- return time_source_->NowTicks();
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/base/task_queue_manager_delegate_for_test.h b/chromium/components/scheduler/base/task_queue_manager_delegate_for_test.h
deleted file mode 100644
index cb97e474e7f..00000000000
--- a/chromium/components/scheduler/base/task_queue_manager_delegate_for_test.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2015 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_SCHEDULER_BASE_TASK_QUEUE_MANAGER_DELEGATE_FOR_TEST_H_
-#define COMPONENTS_SCHEDULER_BASE_TASK_QUEUE_MANAGER_DELEGATE_FOR_TEST_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/time/tick_clock.h"
-#include "components/scheduler/base/task_queue_manager_delegate.h"
-
-namespace scheduler {
-
-class TaskQueueManagerDelegateForTest : public TaskQueueManagerDelegate {
- public:
- static scoped_refptr<TaskQueueManagerDelegateForTest> Create(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- std::unique_ptr<base::TickClock> time_source);
-
- // NestableSingleThreadTaskRunner implementation
- bool PostDelayedTask(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) override;
- bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) override;
- bool RunsTasksOnCurrentThread() const override;
- bool IsNested() const override;
- base::TimeTicks NowTicks() override;
-
- protected:
- ~TaskQueueManagerDelegateForTest() override;
- TaskQueueManagerDelegateForTest(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- std::unique_ptr<base::TickClock> time_source);
-
- private:
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- std::unique_ptr<base::TickClock> time_source_;
-
- DISALLOW_COPY_AND_ASSIGN(TaskQueueManagerDelegateForTest);
-};
-
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_BASE_TASK_QUEUE_MANAGER_DELEGATE_FOR_TEST_H_
diff --git a/chromium/components/scheduler/base/task_queue_manager_perftest.cc b/chromium/components/scheduler/base/task_queue_manager_perftest.cc
deleted file mode 100644
index a81fea329dc..00000000000
--- a/chromium/components/scheduler/base/task_queue_manager_perftest.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2015 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/scheduler/base/task_queue_manager.h"
-
-#include <stddef.h>
-
-#include "base/bind.h"
-#include "base/memory/ptr_util.h"
-#include "base/threading/thread.h"
-#include "base/time/default_tick_clock.h"
-#include "components/scheduler/base/task_queue_impl.h"
-#include "components/scheduler/base/task_queue_manager_delegate_for_test.h"
-#include "components/scheduler/base/task_queue_selector.h"
-#include "components/scheduler/base/work_queue_sets.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/perf/perf_test.h"
-
-namespace scheduler {
-
-class TaskQueueManagerPerfTest : public testing::Test {
- public:
- TaskQueueManagerPerfTest()
- : num_queues_(0),
- max_tasks_in_flight_(0),
- num_tasks_in_flight_(0),
- num_tasks_to_post_(0),
- num_tasks_to_run_(0) {}
-
- void SetUp() override {
- if (base::ThreadTicks::IsSupported())
- base::ThreadTicks::WaitUntilInitialized();
- }
-
- void Initialize(size_t num_queues) {
- num_queues_ = num_queues;
- message_loop_.reset(new base::MessageLoop());
- manager_ = base::WrapUnique(new TaskQueueManager(
- TaskQueueManagerDelegateForTest::Create(
- message_loop_->task_runner(),
- base::WrapUnique(new base::DefaultTickClock())),
- "fake.category", "fake.category", "fake.category.debug"));
- for (size_t i = 0; i < num_queues; i++)
- queues_.push_back(manager_->NewTaskQueue(TaskQueue::Spec("test")));
- }
-
- void TestDelayedTask() {
- if (--num_tasks_to_run_ == 0) {
- message_loop_->QuitWhenIdle();
- }
-
- num_tasks_in_flight_--;
- // NOTE there are only up to max_tasks_in_flight_ pending delayed tasks at
- // any one time. Thanks to the lower_num_tasks_to_post going to zero if
- // there are a lot of tasks in flight, the total number of task in flight at
- // any one time is very variable.
- unsigned int lower_num_tasks_to_post =
- num_tasks_in_flight_ < (max_tasks_in_flight_ / 2) ? 1 : 0;
- unsigned int max_tasks_to_post =
- num_tasks_to_post_ % 2 ? lower_num_tasks_to_post : 10;
- for (unsigned int i = 0;
- i < max_tasks_to_post && num_tasks_in_flight_ < max_tasks_in_flight_ &&
- num_tasks_to_post_ > 0;
- i++) {
- // Choose a queue weighted towards queue 0.
- unsigned int queue = num_tasks_to_post_ % (num_queues_ + 1);
- if (queue == num_queues_) {
- queue = 0;
- }
- // Simulate a mix of short and longer delays.
- unsigned int delay =
- num_tasks_to_post_ % 2 ? 1 : (10 + num_tasks_to_post_ % 10);
- queues_[queue]->PostDelayedTask(
- FROM_HERE, base::Bind(&TaskQueueManagerPerfTest::TestDelayedTask,
- base::Unretained(this)),
- base::TimeDelta::FromMicroseconds(delay));
- num_tasks_in_flight_++;
- num_tasks_to_post_--;
- }
- }
-
- void ResetAndCallTestDelayedTask(unsigned int num_tasks_to_run) {
- num_tasks_in_flight_ = 1;
- num_tasks_to_post_ = num_tasks_to_run;
- num_tasks_to_run_ = num_tasks_to_run;
- TestDelayedTask();
- }
-
- void Benchmark(const std::string& trace, const base::Closure& test_task) {
- base::ThreadTicks start = base::ThreadTicks::Now();
- base::ThreadTicks now;
- unsigned long long num_iterations = 0;
- do {
- test_task.Run();
- message_loop_->Run();
- now = base::ThreadTicks::Now();
- num_iterations++;
- } while (now - start < base::TimeDelta::FromSeconds(5));
- perf_test::PrintResult(
- "task", "", trace,
- (now - start).InMicroseconds() / static_cast<double>(num_iterations),
- "us/run", true);
- }
-
- size_t num_queues_;
- unsigned int max_tasks_in_flight_;
- unsigned int num_tasks_in_flight_;
- unsigned int num_tasks_to_post_;
- unsigned int num_tasks_to_run_;
- std::unique_ptr<TaskQueueManager> manager_;
- std::unique_ptr<base::MessageLoop> message_loop_;
- std::vector<scoped_refptr<base::SingleThreadTaskRunner>> queues_;
-};
-
-TEST_F(TaskQueueManagerPerfTest, RunTenThousandDelayedTasks_OneQueue) {
- if (!base::ThreadTicks::IsSupported())
- return;
- Initialize(1u);
-
- max_tasks_in_flight_ = 200;
- Benchmark("run 10000 delayed tasks with one queue",
- base::Bind(&TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask,
- base::Unretained(this), 10000));
-}
-
-TEST_F(TaskQueueManagerPerfTest, RunTenThousandDelayedTasks_FourQueues) {
- if (!base::ThreadTicks::IsSupported())
- return;
- Initialize(4u);
-
- max_tasks_in_flight_ = 200;
- Benchmark("run 10000 delayed tasks with four queues",
- base::Bind(&TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask,
- base::Unretained(this), 10000));
-}
-
-TEST_F(TaskQueueManagerPerfTest, RunTenThousandDelayedTasks_EightQueues) {
- if (!base::ThreadTicks::IsSupported())
- return;
- Initialize(8u);
-
- max_tasks_in_flight_ = 200;
- Benchmark("run 10000 delayed tasks with eight queues",
- base::Bind(&TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask,
- base::Unretained(this), 10000));
-}
-
-TEST_F(TaskQueueManagerPerfTest, RunTenThousandDelayedTasks_ThirtyTwoQueues) {
- if (!base::ThreadTicks::IsSupported())
- return;
- Initialize(32u);
-
- max_tasks_in_flight_ = 200;
- Benchmark("run 10000 delayed tasks with eight queues",
- base::Bind(&TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask,
- base::Unretained(this), 10000));
-}
-
-// TODO(alexclarke): Add additional tests with different mixes of non-delayed vs
-// delayed tasks.
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/base/task_queue_manager_unittest.cc b/chromium/components/scheduler/base/task_queue_manager_unittest.cc
deleted file mode 100644
index fef14d2fe57..00000000000
--- a/chromium/components/scheduler/base/task_queue_manager_unittest.cc
+++ /dev/null
@@ -1,1929 +0,0 @@
-// Copyright 2014 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/scheduler/base/task_queue_manager.h"
-
-#include <stddef.h>
-
-#include <utility>
-
-#include "base/location.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "base/test/trace_event_analyzer.h"
-#include "base/threading/thread.h"
-#include "base/trace_event/blame_context.h"
-#include "base/trace_event/trace_buffer.h"
-#include "cc/test/ordered_simple_task_runner.h"
-#include "components/scheduler/base/real_time_domain.h"
-#include "components/scheduler/base/task_queue_impl.h"
-#include "components/scheduler/base/task_queue_manager_delegate_for_test.h"
-#include "components/scheduler/base/task_queue_selector.h"
-#include "components/scheduler/base/test_always_fail_time_source.h"
-#include "components/scheduler/base/test_time_source.h"
-#include "components/scheduler/base/virtual_time_domain.h"
-#include "components/scheduler/base/work_queue.h"
-#include "components/scheduler/base/work_queue_sets.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-using testing::ElementsAre;
-using testing::ElementsAreArray;
-using testing::_;
-using scheduler::internal::EnqueueOrder;
-
-namespace scheduler {
-
-class MessageLoopTaskRunner : public TaskQueueManagerDelegateForTest {
- public:
- static scoped_refptr<MessageLoopTaskRunner> Create(
- std::unique_ptr<base::TickClock> tick_clock) {
- return make_scoped_refptr(new MessageLoopTaskRunner(std::move(tick_clock)));
- }
-
- // NestableTaskRunner implementation.
- bool IsNested() const override {
- return base::MessageLoop::current()->IsNested();
- }
-
- private:
- explicit MessageLoopTaskRunner(std::unique_ptr<base::TickClock> tick_clock)
- : TaskQueueManagerDelegateForTest(
- base::MessageLoop::current()->task_runner(),
- std::move(tick_clock)) {}
- ~MessageLoopTaskRunner() override {}
-};
-
-class TaskQueueManagerTest : public testing::Test {
- public:
- void DeleteTaskQueueManager() { manager_.reset(); }
-
- protected:
- void InitializeWithClock(size_t num_queues,
- std::unique_ptr<base::TickClock> test_time_source) {
- test_task_runner_ = make_scoped_refptr(
- new cc::OrderedSimpleTaskRunner(now_src_.get(), false));
- main_task_runner_ = TaskQueueManagerDelegateForTest::Create(
- test_task_runner_.get(),
- base::WrapUnique(new TestTimeSource(now_src_.get())));
- manager_ = base::WrapUnique(
- new TaskQueueManager(main_task_runner_, "test.scheduler",
- "test.scheduler", "test.scheduler.debug"));
-
- for (size_t i = 0; i < num_queues; i++)
- runners_.push_back(manager_->NewTaskQueue(TaskQueue::Spec("test_queue")));
- }
-
- void Initialize(size_t num_queues) {
- now_src_.reset(new base::SimpleTestTickClock());
- now_src_->Advance(base::TimeDelta::FromMicroseconds(1000));
- InitializeWithClock(num_queues,
- base::WrapUnique(new TestTimeSource(now_src_.get())));
- }
-
- void InitializeWithRealMessageLoop(size_t num_queues) {
- now_src_.reset(new base::SimpleTestTickClock());
- message_loop_.reset(new base::MessageLoop());
- manager_ = base::WrapUnique(new TaskQueueManager(
- MessageLoopTaskRunner::Create(
- base::WrapUnique(new TestTimeSource(now_src_.get()))),
- "test.scheduler", "test.scheduler", "test.scheduler.debug"));
-
- for (size_t i = 0; i < num_queues; i++)
- runners_.push_back(manager_->NewTaskQueue(TaskQueue::Spec("test_queue")));
- }
-
- std::unique_ptr<base::MessageLoop> message_loop_;
- std::unique_ptr<base::SimpleTestTickClock> now_src_;
- scoped_refptr<TaskQueueManagerDelegateForTest> main_task_runner_;
- scoped_refptr<cc::OrderedSimpleTaskRunner> test_task_runner_;
- std::unique_ptr<TaskQueueManager> manager_;
- std::vector<scoped_refptr<internal::TaskQueueImpl>> runners_;
-};
-
-void PostFromNestedRunloop(base::MessageLoop* message_loop,
- base::SingleThreadTaskRunner* runner,
- std::vector<std::pair<base::Closure, bool>>* tasks) {
- base::MessageLoop::ScopedNestableTaskAllower allow(message_loop);
- for (std::pair<base::Closure, bool>& pair : *tasks) {
- if (pair.second) {
- runner->PostTask(FROM_HERE, pair.first);
- } else {
- runner->PostNonNestableTask(FROM_HERE, pair.first);
- }
- }
- base::RunLoop().RunUntilIdle();
-}
-
-void NopTask() {}
-
-TEST_F(TaskQueueManagerTest, NowNotCalledWhenThereAreNoDelayedTasks) {
- message_loop_.reset(new base::MessageLoop());
- manager_ = base::WrapUnique(new TaskQueueManager(
- MessageLoopTaskRunner::Create(
- base::WrapUnique(new TestAlwaysFailTimeSource())),
- "test.scheduler", "test.scheduler", "test.scheduler.debug"));
-
- for (size_t i = 0; i < 3; i++)
- runners_.push_back(manager_->NewTaskQueue(TaskQueue::Spec("test_queue")));
-
- runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
- runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
- runners_[1]->PostTask(FROM_HERE, base::Bind(&NopTask));
- runners_[1]->PostTask(FROM_HERE, base::Bind(&NopTask));
- runners_[2]->PostTask(FROM_HERE, base::Bind(&NopTask));
- runners_[2]->PostTask(FROM_HERE, base::Bind(&NopTask));
-
- message_loop_->RunUntilIdle();
-}
-
-void NullTask() {}
-
-void TestTask(EnqueueOrder value, std::vector<EnqueueOrder>* out_result) {
- out_result->push_back(value);
-}
-
-TEST_F(TaskQueueManagerTest, SingleQueuePosting) {
- Initialize(1u);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
-
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1, 2, 3));
-}
-
-TEST_F(TaskQueueManagerTest, MultiQueuePosting) {
- Initialize(3u);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
- runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order));
- runners_[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 5, &run_order));
- runners_[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 6, &run_order));
-
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4, 5, 6));
-}
-
-TEST_F(TaskQueueManagerTest, NonNestableTaskPosting) {
- InitializeWithRealMessageLoop(1u);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostNonNestableTask(FROM_HERE,
- base::Bind(&TestTask, 1, &run_order));
-
- message_loop_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1));
-}
-
-TEST_F(TaskQueueManagerTest, NonNestableTaskExecutesInExpectedOrder) {
- InitializeWithRealMessageLoop(1u);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order));
- runners_[0]->PostNonNestableTask(FROM_HERE,
- base::Bind(&TestTask, 5, &run_order));
-
- message_loop_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4, 5));
-}
-
-TEST_F(TaskQueueManagerTest, NonNestableTaskDoesntExecuteInNestedLoop) {
- InitializeWithRealMessageLoop(1u);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
-
- std::vector<std::pair<base::Closure, bool>> tasks_to_post_from_nested_loop;
- tasks_to_post_from_nested_loop.push_back(
- std::make_pair(base::Bind(&TestTask, 3, &run_order), false));
- tasks_to_post_from_nested_loop.push_back(
- std::make_pair(base::Bind(&TestTask, 4, &run_order), true));
- tasks_to_post_from_nested_loop.push_back(
- std::make_pair(base::Bind(&TestTask, 5, &run_order), true));
-
- runners_[0]->PostTask(
- FROM_HERE, base::Bind(&PostFromNestedRunloop, message_loop_.get(),
- base::RetainedRef(runners_[0]),
- base::Unretained(&tasks_to_post_from_nested_loop)));
-
- message_loop_->RunUntilIdle();
- // Note we expect task 3 to run last because it's non-nestable.
- EXPECT_THAT(run_order, ElementsAre(1, 2, 4, 5, 3));
-}
-
-TEST_F(TaskQueueManagerTest, QueuePolling) {
- Initialize(1u);
-
- std::vector<EnqueueOrder> run_order;
- EXPECT_FALSE(runners_[0]->HasPendingImmediateWork());
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- EXPECT_TRUE(runners_[0]->HasPendingImmediateWork());
-
- test_task_runner_->RunUntilIdle();
- EXPECT_FALSE(runners_[0]->HasPendingImmediateWork());
-}
-
-TEST_F(TaskQueueManagerTest, DelayedTaskPosting) {
- Initialize(1u);
-
- std::vector<EnqueueOrder> run_order;
- base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- delay);
- EXPECT_EQ(delay, test_task_runner_->DelayToNextTaskTime());
- EXPECT_FALSE(runners_[0]->HasPendingImmediateWork());
- EXPECT_TRUE(run_order.empty());
-
- // The task doesn't run before the delay has completed.
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(9));
- EXPECT_TRUE(run_order.empty());
-
- // After the delay has completed, the task runs normally.
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1));
- EXPECT_THAT(run_order, ElementsAre(1));
- EXPECT_FALSE(runners_[0]->HasPendingImmediateWork());
-}
-
-bool MessageLoopTaskCounter(size_t* count) {
- *count = *count + 1;
- return true;
-}
-
-TEST_F(TaskQueueManagerTest, DelayedTaskExecutedInOneMessageLoopTask) {
- Initialize(1u);
-
- base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay);
-
- size_t task_count = 0;
- test_task_runner_->RunTasksWhile(
- base::Bind(&MessageLoopTaskCounter, &task_count));
- EXPECT_EQ(1u, task_count);
-}
-
-TEST_F(TaskQueueManagerTest, DelayedTaskPosting_MultipleTasks_DecendingOrder) {
- Initialize(1u);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- base::TimeDelta::FromMilliseconds(10));
-
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
- base::TimeDelta::FromMilliseconds(8));
-
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
- base::TimeDelta::FromMilliseconds(5));
-
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(5),
- test_task_runner_->DelayToNextTaskTime());
-
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5));
- EXPECT_THAT(run_order, ElementsAre(3));
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(3),
- test_task_runner_->DelayToNextTaskTime());
-
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(3));
- EXPECT_THAT(run_order, ElementsAre(3, 2));
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(2),
- test_task_runner_->DelayToNextTaskTime());
-
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(2));
- EXPECT_THAT(run_order, ElementsAre(3, 2, 1));
-}
-
-TEST_F(TaskQueueManagerTest, DelayedTaskPosting_MultipleTasks_AscendingOrder) {
- Initialize(1u);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- base::TimeDelta::FromMilliseconds(1));
-
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
- base::TimeDelta::FromMilliseconds(5));
-
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
- base::TimeDelta::FromMilliseconds(10));
-
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(1),
- test_task_runner_->DelayToNextTaskTime());
-
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1));
- EXPECT_THAT(run_order, ElementsAre(1));
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(4),
- test_task_runner_->DelayToNextTaskTime());
-
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(4));
- EXPECT_THAT(run_order, ElementsAre(1, 2));
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(5),
- test_task_runner_->DelayToNextTaskTime());
-
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5));
- EXPECT_THAT(run_order, ElementsAre(1, 2, 3));
-}
-
-TEST_F(TaskQueueManagerTest, PostDelayedTask_SharesUnderlyingDelayedTasks) {
- Initialize(1u);
-
- std::vector<EnqueueOrder> run_order;
- base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- delay);
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
- delay);
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
- delay);
-
- EXPECT_EQ(1u, test_task_runner_->NumPendingTasks());
-}
-
-class TestObject {
- public:
- ~TestObject() { destructor_count_++; }
-
- void Run() { FAIL() << "TestObject::Run should not be called"; }
-
- static int destructor_count_;
-};
-
-int TestObject::destructor_count_ = 0;
-
-TEST_F(TaskQueueManagerTest, PendingDelayedTasksRemovedOnShutdown) {
- Initialize(1u);
-
- TestObject::destructor_count_ = 0;
-
- base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
- runners_[0]->PostDelayedTask(
- FROM_HERE, base::Bind(&TestObject::Run, base::Owned(new TestObject())),
- delay);
- runners_[0]->PostTask(
- FROM_HERE, base::Bind(&TestObject::Run, base::Owned(new TestObject())));
-
- manager_.reset();
-
- EXPECT_EQ(2, TestObject::destructor_count_);
-}
-
-TEST_F(TaskQueueManagerTest, ManualPumping) {
- Initialize(1u);
- runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
-
- std::vector<EnqueueOrder> run_order;
- // Posting a task when pumping is disabled doesn't result in work getting
- // posted.
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- EXPECT_FALSE(test_task_runner_->HasPendingTasks());
-
- // However polling still works.
- EXPECT_TRUE(runners_[0]->HasPendingImmediateWork());
-
- // After pumping the task runs normally.
- LazyNow lazy_now(now_src_.get());
- runners_[0]->PumpQueue(&lazy_now, true);
- EXPECT_TRUE(test_task_runner_->HasPendingTasks());
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1));
-}
-
-TEST_F(TaskQueueManagerTest, ManualPumpingToggle) {
- Initialize(1u);
- runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
-
- std::vector<EnqueueOrder> run_order;
- // Posting a task when pumping is disabled doesn't result in work getting
- // posted.
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- EXPECT_FALSE(test_task_runner_->HasPendingTasks());
-
- // When pumping is enabled the task runs normally.
- runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO);
- EXPECT_TRUE(test_task_runner_->HasPendingTasks());
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1));
-}
-
-TEST_F(TaskQueueManagerTest, DenyRunning_BeforePosting) {
- Initialize(1u);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->SetQueueEnabled(false);
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
-
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(run_order.empty());
-
- runners_[0]->SetQueueEnabled(true);
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1));
-}
-
-TEST_F(TaskQueueManagerTest, DenyRunning_AfterPosting) {
- Initialize(1u);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runners_[0]->SetQueueEnabled(false);
-
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(run_order.empty());
-
- runners_[0]->SetQueueEnabled(true);
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1));
-}
-
-TEST_F(TaskQueueManagerTest, DenyRunning_ManuallyPumpedTransitionsToAuto) {
- Initialize(1u);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
- runners_[0]->SetQueueEnabled(false);
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
-
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(run_order.empty());
-
- runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO);
- runners_[0]->SetQueueEnabled(true);
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1));
-}
-
-TEST_F(TaskQueueManagerTest, ManualPumpingWithDelayedTask) {
- Initialize(1u);
- runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
-
- std::vector<EnqueueOrder> run_order;
- // Posting a delayed task when pumping will apply the delay, but won't cause
- // work to executed afterwards.
- base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- delay);
-
- // After pumping but before the delay period has expired, task does not run.
- LazyNow lazy_now1(now_src_.get());
- runners_[0]->PumpQueue(&lazy_now1, true);
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5));
- EXPECT_TRUE(run_order.empty());
-
- // Once the delay has expired, pumping causes the task to run.
- now_src_->Advance(base::TimeDelta::FromMilliseconds(5));
- LazyNow lazy_now2(now_src_.get());
- runners_[0]->PumpQueue(&lazy_now2, true);
- EXPECT_TRUE(test_task_runner_->HasPendingTasks());
- test_task_runner_->RunPendingTasks();
- EXPECT_THAT(run_order, ElementsAre(1));
-}
-
-TEST_F(TaskQueueManagerTest, ManualPumpingWithMultipleDelayedTasks) {
- Initialize(1u);
- runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
-
- std::vector<EnqueueOrder> run_order;
- // Posting a delayed task when pumping will apply the delay, but won't cause
- // work to executed afterwards.
- base::TimeDelta delay1(base::TimeDelta::FromMilliseconds(1));
- base::TimeDelta delay2(base::TimeDelta::FromMilliseconds(10));
- base::TimeDelta delay3(base::TimeDelta::FromMilliseconds(20));
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- delay1);
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
- delay2);
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
- delay3);
-
- now_src_->Advance(base::TimeDelta::FromMilliseconds(15));
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(run_order.empty());
-
- // Once the delay has expired, pumping causes the task to run.
- LazyNow lazy_now(now_src_.get());
- runners_[0]->PumpQueue(&lazy_now, true);
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1, 2));
-}
-
-TEST_F(TaskQueueManagerTest, DelayedTasksDontAutoRunWithManualPumping) {
- Initialize(1u);
- runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
-
- std::vector<EnqueueOrder> run_order;
- base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- delay);
-
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(10));
- EXPECT_TRUE(run_order.empty());
-}
-
-TEST_F(TaskQueueManagerTest, ManualPumpingWithNonEmptyWorkQueue) {
- Initialize(1u);
- runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
-
- std::vector<EnqueueOrder> run_order;
- // Posting two tasks and pumping twice should result in two tasks in the work
- // queue.
- LazyNow lazy_now(now_src_.get());
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runners_[0]->PumpQueue(&lazy_now, true);
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- runners_[0]->PumpQueue(&lazy_now, true);
-
- EXPECT_EQ(2u, runners_[0]->immediate_work_queue()->Size());
-}
-
-void ReentrantTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner,
- int countdown,
- std::vector<EnqueueOrder>* out_result) {
- out_result->push_back(countdown);
- if (--countdown) {
- runner->PostTask(FROM_HERE,
- Bind(&ReentrantTestTask, runner, countdown, out_result));
- }
-}
-
-TEST_F(TaskQueueManagerTest, ReentrantPosting) {
- Initialize(1u);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostTask(FROM_HERE,
- Bind(&ReentrantTestTask, runners_[0], 3, &run_order));
-
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(3, 2, 1));
-}
-
-TEST_F(TaskQueueManagerTest, NoTasksAfterShutdown) {
- Initialize(1u);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- manager_.reset();
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
-
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(run_order.empty());
-}
-
-void PostTaskToRunner(scoped_refptr<base::SingleThreadTaskRunner> runner,
- std::vector<EnqueueOrder>* run_order) {
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, run_order));
-}
-
-TEST_F(TaskQueueManagerTest, PostFromThread) {
- InitializeWithRealMessageLoop(1u);
-
- std::vector<EnqueueOrder> run_order;
- base::Thread thread("TestThread");
- thread.Start();
- thread.task_runner()->PostTask(
- FROM_HERE, base::Bind(&PostTaskToRunner, runners_[0], &run_order));
- thread.Stop();
-
- message_loop_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1));
-}
-
-void RePostingTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner,
- int* run_count) {
- (*run_count)++;
- runner->PostTask(FROM_HERE, Bind(&RePostingTestTask,
- base::Unretained(runner.get()), run_count));
-}
-
-TEST_F(TaskQueueManagerTest, DoWorkCantPostItselfMultipleTimes) {
- Initialize(1u);
-
- int run_count = 0;
- runners_[0]->PostTask(
- FROM_HERE, base::Bind(&RePostingTestTask, runners_[0], &run_count));
-
- test_task_runner_->RunPendingTasks();
- // NOTE without the executing_task_ check in MaybeScheduleDoWork there
- // will be two tasks here.
- EXPECT_EQ(1u, test_task_runner_->NumPendingTasks());
- EXPECT_EQ(1, run_count);
-}
-
-TEST_F(TaskQueueManagerTest, PostFromNestedRunloop) {
- InitializeWithRealMessageLoop(1u);
-
- std::vector<EnqueueOrder> run_order;
- std::vector<std::pair<base::Closure, bool>> tasks_to_post_from_nested_loop;
- tasks_to_post_from_nested_loop.push_back(
- std::make_pair(base::Bind(&TestTask, 1, &run_order), true));
-
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 0, &run_order));
- runners_[0]->PostTask(
- FROM_HERE, base::Bind(&PostFromNestedRunloop, message_loop_.get(),
- base::RetainedRef(runners_[0]),
- base::Unretained(&tasks_to_post_from_nested_loop)));
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
-
- message_loop_->RunUntilIdle();
-
- EXPECT_THAT(run_order, ElementsAre(0, 2, 1));
-}
-
-TEST_F(TaskQueueManagerTest, WorkBatching) {
- Initialize(1u);
-
- manager_->SetWorkBatchSize(2);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order));
-
- // Running one task in the host message loop should cause two posted tasks to
- // get executed.
- EXPECT_EQ(test_task_runner_->NumPendingTasks(), 1u);
- test_task_runner_->RunPendingTasks();
- EXPECT_THAT(run_order, ElementsAre(1, 2));
-
- // The second task runs the remaining two posted tasks.
- EXPECT_EQ(test_task_runner_->NumPendingTasks(), 1u);
- test_task_runner_->RunPendingTasks();
- EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4));
-}
-
-TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeup) {
- Initialize(2u);
- runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(run_order.empty()); // Shouldn't run - no other task to wake TQM.
-
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(run_order.empty()); // Still shouldn't wake TQM.
-
- runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
- test_task_runner_->RunUntilIdle();
- // Executing a task on an auto pumped queue should wake the TQM.
- EXPECT_THAT(run_order, ElementsAre(3, 1, 2));
-}
-
-TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupWhenAlreadyAwake) {
- Initialize(2u);
- runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(2, 1)); // TQM was already awake.
-}
-
-TEST_F(TaskQueueManagerTest,
- AutoPumpAfterWakeupTriggeredByManuallyPumpedQueue) {
- Initialize(2u);
- runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
- runners_[1]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(run_order.empty()); // Shouldn't run - no other task to wake TQM.
-
- runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- test_task_runner_->RunUntilIdle();
- // This still shouldn't wake TQM as manual queue was not pumped.
- EXPECT_TRUE(run_order.empty());
-
- LazyNow lazy_now(now_src_.get());
- runners_[1]->PumpQueue(&lazy_now, true);
- test_task_runner_->RunUntilIdle();
- // Executing a task on an auto pumped queue should wake the TQM.
- EXPECT_THAT(run_order, ElementsAre(2, 1));
-}
-
-void TestPostingTask(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- base::Closure task) {
- task_runner->PostTask(FROM_HERE, task);
-}
-
-TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupFromTask) {
- Initialize(2u);
- runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
-
- std::vector<EnqueueOrder> run_order;
- // Check that a task which posts a task to an auto pump after wakeup queue
- // doesn't cause the queue to wake up.
- base::Closure after_wakeup_task = base::Bind(&TestTask, 1, &run_order);
- runners_[1]->PostTask(
- FROM_HERE, base::Bind(&TestPostingTask, runners_[0], after_wakeup_task));
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(run_order.empty());
-
- // Wake up the queue.
- runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(2, 1));
-}
-
-TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupFromMultipleTasks) {
- Initialize(2u);
- runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
-
- std::vector<EnqueueOrder> run_order;
- // Check that a task which posts a task to an auto pump after wakeup queue
- // doesn't cause the queue to wake up.
- base::Closure after_wakeup_task_1 = base::Bind(&TestTask, 1, &run_order);
- base::Closure after_wakeup_task_2 = base::Bind(&TestTask, 2, &run_order);
- runners_[1]->PostTask(FROM_HERE, base::Bind(&TestPostingTask, runners_[0],
- after_wakeup_task_1));
- runners_[1]->PostTask(FROM_HERE, base::Bind(&TestPostingTask, runners_[0],
- after_wakeup_task_2));
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(run_order.empty());
-
- // Wake up the queue.
- runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(3, 1, 2));
-}
-
-TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupBecomesQuiescent) {
- Initialize(2u);
- runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
-
- int run_count = 0;
- // Check that if multiple tasks reposts themselves onto a pump-after-wakeup
- // queue they don't wake each other and will eventually stop when no other
- // tasks execute.
- runners_[0]->PostTask(
- FROM_HERE, base::Bind(&RePostingTestTask, runners_[0], &run_count));
- runners_[0]->PostTask(
- FROM_HERE, base::Bind(&RePostingTestTask, runners_[0], &run_count));
- runners_[1]->PostTask(FROM_HERE, base::Bind(&NopTask));
- test_task_runner_->RunUntilIdle();
- // The reposting tasks posted to the after wakeup queue shouldn't have woken
- // each other up.
- EXPECT_EQ(2, run_count);
-}
-
-TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupWithDontWakeQueue) {
- Initialize(1u);
-
- scoped_refptr<internal::TaskQueueImpl> queue0 = manager_->NewTaskQueue(
- TaskQueue::Spec("test_queue 0")
- .SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP));
- scoped_refptr<internal::TaskQueueImpl> queue1 = manager_->NewTaskQueue(
- TaskQueue::Spec("test_queue 0")
- .SetWakeupPolicy(TaskQueue::WakeupPolicy::DONT_WAKE_OTHER_QUEUES));
- scoped_refptr<internal::TaskQueueImpl> queue2 = runners_[0];
-
- std::vector<EnqueueOrder> run_order;
- queue0->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- queue1->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- test_task_runner_->RunUntilIdle();
- // Executing a DONT_WAKE_OTHER_QUEUES queue shouldn't wake the autopump after
- // wakeup queue.
- EXPECT_THAT(run_order, ElementsAre(2));
-
- queue2->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
- test_task_runner_->RunUntilIdle();
- // Executing a CAN_WAKE_OTHER_QUEUES queue should wake the autopump after
- // wakeup queue.
- EXPECT_THAT(run_order, ElementsAre(2, 3, 1));
-}
-
-class MockTaskObserver : public base::MessageLoop::TaskObserver {
- public:
- MOCK_METHOD1(DidProcessTask, void(const base::PendingTask& task));
- MOCK_METHOD1(WillProcessTask, void(const base::PendingTask& task));
-};
-
-TEST_F(TaskQueueManagerTest, TaskObserverAdding) {
- InitializeWithRealMessageLoop(1u);
- MockTaskObserver observer;
-
- manager_->SetWorkBatchSize(2);
- manager_->AddTaskObserver(&observer);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
-
- EXPECT_CALL(observer, WillProcessTask(_)).Times(2);
- EXPECT_CALL(observer, DidProcessTask(_)).Times(2);
- message_loop_->RunUntilIdle();
-}
-
-TEST_F(TaskQueueManagerTest, TaskObserverRemoving) {
- InitializeWithRealMessageLoop(1u);
- MockTaskObserver observer;
- manager_->SetWorkBatchSize(2);
- manager_->AddTaskObserver(&observer);
- manager_->RemoveTaskObserver(&observer);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
-
- EXPECT_CALL(observer, WillProcessTask(_)).Times(0);
- EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
-
- message_loop_->RunUntilIdle();
-}
-
-void RemoveObserverTask(TaskQueueManager* manager,
- base::MessageLoop::TaskObserver* observer) {
- manager->RemoveTaskObserver(observer);
-}
-
-TEST_F(TaskQueueManagerTest, TaskObserverRemovingInsideTask) {
- InitializeWithRealMessageLoop(1u);
- MockTaskObserver observer;
- manager_->SetWorkBatchSize(3);
- manager_->AddTaskObserver(&observer);
-
- runners_[0]->PostTask(
- FROM_HERE, base::Bind(&RemoveObserverTask, manager_.get(), &observer));
-
- EXPECT_CALL(observer, WillProcessTask(_)).Times(1);
- EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
- message_loop_->RunUntilIdle();
-}
-
-TEST_F(TaskQueueManagerTest, QueueTaskObserverAdding) {
- InitializeWithRealMessageLoop(2u);
- MockTaskObserver observer;
-
- manager_->SetWorkBatchSize(2);
- runners_[0]->AddTaskObserver(&observer);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
-
- EXPECT_CALL(observer, WillProcessTask(_)).Times(1);
- EXPECT_CALL(observer, DidProcessTask(_)).Times(1);
- message_loop_->RunUntilIdle();
-}
-
-TEST_F(TaskQueueManagerTest, QueueTaskObserverRemoving) {
- InitializeWithRealMessageLoop(1u);
- MockTaskObserver observer;
- manager_->SetWorkBatchSize(2);
- runners_[0]->AddTaskObserver(&observer);
- runners_[0]->RemoveTaskObserver(&observer);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
-
- EXPECT_CALL(observer, WillProcessTask(_)).Times(0);
- EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
-
- message_loop_->RunUntilIdle();
-}
-
-void RemoveQueueObserverTask(scoped_refptr<TaskQueue> queue,
- base::MessageLoop::TaskObserver* observer) {
- queue->RemoveTaskObserver(observer);
-}
-
-TEST_F(TaskQueueManagerTest, QueueTaskObserverRemovingInsideTask) {
- InitializeWithRealMessageLoop(1u);
- MockTaskObserver observer;
- runners_[0]->AddTaskObserver(&observer);
-
- runners_[0]->PostTask(
- FROM_HERE, base::Bind(&RemoveQueueObserverTask, runners_[0], &observer));
-
- EXPECT_CALL(observer, WillProcessTask(_)).Times(1);
- EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
- message_loop_->RunUntilIdle();
-}
-
-TEST_F(TaskQueueManagerTest, ThreadCheckAfterTermination) {
- Initialize(1u);
- EXPECT_TRUE(runners_[0]->RunsTasksOnCurrentThread());
- manager_.reset();
- EXPECT_TRUE(runners_[0]->RunsTasksOnCurrentThread());
-}
-
-TEST_F(TaskQueueManagerTest, TimeDomain_NextScheduledRunTime) {
- Initialize(2u);
- now_src_->Advance(base::TimeDelta::FromMicroseconds(10000));
-
- // With no delayed tasks.
- base::TimeTicks run_time;
- EXPECT_FALSE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
-
- // With a non-delayed task.
- runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
- EXPECT_FALSE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
-
- // With a delayed task.
- base::TimeDelta expected_delay = base::TimeDelta::FromMilliseconds(50);
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay);
- EXPECT_TRUE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
- EXPECT_EQ(now_src_->NowTicks() + expected_delay, run_time);
-
- // With another delayed task in the same queue with a longer delay.
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask),
- base::TimeDelta::FromMilliseconds(100));
- EXPECT_TRUE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
- EXPECT_EQ(now_src_->NowTicks() + expected_delay, run_time);
-
- // With another delayed task in the same queue with a shorter delay.
- expected_delay = base::TimeDelta::FromMilliseconds(20);
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay);
- EXPECT_TRUE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
- EXPECT_EQ(now_src_->NowTicks() + expected_delay, run_time);
-
- // With another delayed task in a different queue with a shorter delay.
- expected_delay = base::TimeDelta::FromMilliseconds(10);
- runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay);
- EXPECT_TRUE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
- EXPECT_EQ(now_src_->NowTicks() + expected_delay, run_time);
-
- // Test it updates as time progresses
- now_src_->Advance(expected_delay);
- EXPECT_TRUE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
- EXPECT_EQ(now_src_->NowTicks(), run_time);
-}
-
-TEST_F(TaskQueueManagerTest, TimeDomain_NextScheduledRunTime_MultipleQueues) {
- Initialize(3u);
-
- base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(50);
- base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(5);
- base::TimeDelta delay3 = base::TimeDelta::FromMilliseconds(10);
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay1);
- runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay2);
- runners_[2]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay3);
- runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
-
- base::TimeTicks run_time;
- EXPECT_TRUE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
- EXPECT_EQ(now_src_->NowTicks() + delay2, run_time);
-}
-
-TEST_F(TaskQueueManagerTest, DeleteTaskQueueManagerInsideATask) {
- Initialize(1u);
-
- runners_[0]->PostTask(
- FROM_HERE, base::Bind(&TaskQueueManagerTest::DeleteTaskQueueManager,
- base::Unretained(this)));
-
- // This should not crash, assuming DoWork detects the TaskQueueManager has
- // been deleted.
- test_task_runner_->RunUntilIdle();
-}
-
-TEST_F(TaskQueueManagerTest, GetAndClearSystemIsQuiescentBit) {
- Initialize(3u);
-
- scoped_refptr<internal::TaskQueueImpl> queue0 = manager_->NewTaskQueue(
- TaskQueue::Spec("test_queue 0").SetShouldMonitorQuiescence(true));
- scoped_refptr<internal::TaskQueueImpl> queue1 = manager_->NewTaskQueue(
- TaskQueue::Spec("test_queue 1").SetShouldMonitorQuiescence(true));
- scoped_refptr<internal::TaskQueueImpl> queue2 = manager_->NewTaskQueue(
- TaskQueue::Spec("test_queue 2").SetShouldMonitorQuiescence(false));
-
- EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit());
-
- queue0->PostTask(FROM_HERE, base::Bind(&NopTask));
- test_task_runner_->RunUntilIdle();
- EXPECT_FALSE(manager_->GetAndClearSystemIsQuiescentBit());
- EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit());
-
- queue1->PostTask(FROM_HERE, base::Bind(&NopTask));
- test_task_runner_->RunUntilIdle();
- EXPECT_FALSE(manager_->GetAndClearSystemIsQuiescentBit());
- EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit());
-
- queue2->PostTask(FROM_HERE, base::Bind(&NopTask));
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit());
-
- queue0->PostTask(FROM_HERE, base::Bind(&NopTask));
- queue1->PostTask(FROM_HERE, base::Bind(&NopTask));
- test_task_runner_->RunUntilIdle();
- EXPECT_FALSE(manager_->GetAndClearSystemIsQuiescentBit());
- EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit());
-}
-
-TEST_F(TaskQueueManagerTest, HasPendingImmediateWork) {
- Initialize(2u);
- internal::TaskQueueImpl* queue0 = runners_[0].get();
- internal::TaskQueueImpl* queue1 = runners_[1].get();
- queue0->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO);
- queue1->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
-
- EXPECT_FALSE(queue0->HasPendingImmediateWork());
- EXPECT_FALSE(queue1->HasPendingImmediateWork());
-
- queue0->PostTask(FROM_HERE, base::Bind(NullTask));
- queue1->PostTask(FROM_HERE, base::Bind(NullTask));
- EXPECT_TRUE(queue0->HasPendingImmediateWork());
- EXPECT_TRUE(queue1->HasPendingImmediateWork());
-
- test_task_runner_->RunUntilIdle();
- EXPECT_FALSE(queue0->HasPendingImmediateWork());
- EXPECT_TRUE(queue1->HasPendingImmediateWork());
-
- LazyNow lazy_now(now_src_.get());
- queue1->PumpQueue(&lazy_now, true);
- EXPECT_FALSE(queue0->HasPendingImmediateWork());
- EXPECT_TRUE(queue1->HasPendingImmediateWork());
-
- test_task_runner_->RunUntilIdle();
- EXPECT_FALSE(queue0->HasPendingImmediateWork());
- EXPECT_FALSE(queue1->HasPendingImmediateWork());
-}
-
-TEST_F(TaskQueueManagerTest, HasPendingImmediateWorkAndNeedsPumping) {
- Initialize(2u);
- internal::TaskQueueImpl* queue0 = runners_[0].get();
- internal::TaskQueueImpl* queue1 = runners_[1].get();
- queue0->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO);
- queue1->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
-
- EXPECT_FALSE(queue0->HasPendingImmediateWork());
- EXPECT_FALSE(queue0->NeedsPumping());
- EXPECT_FALSE(queue1->HasPendingImmediateWork());
- EXPECT_FALSE(queue1->NeedsPumping());
-
- queue0->PostTask(FROM_HERE, base::Bind(NullTask));
- queue0->PostTask(FROM_HERE, base::Bind(NullTask));
- queue1->PostTask(FROM_HERE, base::Bind(NullTask));
- EXPECT_TRUE(queue0->HasPendingImmediateWork());
- EXPECT_TRUE(queue0->NeedsPumping());
- EXPECT_TRUE(queue1->HasPendingImmediateWork());
- EXPECT_TRUE(queue1->NeedsPumping());
-
- test_task_runner_->SetRunTaskLimit(1);
- test_task_runner_->RunPendingTasks();
- EXPECT_TRUE(queue0->HasPendingImmediateWork());
- EXPECT_FALSE(queue0->NeedsPumping());
- EXPECT_TRUE(queue1->HasPendingImmediateWork());
- EXPECT_TRUE(queue1->NeedsPumping());
-
- test_task_runner_->ClearRunTaskLimit();
- test_task_runner_->RunUntilIdle();
- EXPECT_FALSE(queue0->HasPendingImmediateWork());
- EXPECT_FALSE(queue0->NeedsPumping());
- EXPECT_TRUE(queue1->HasPendingImmediateWork());
- EXPECT_TRUE(queue1->NeedsPumping());
-
- LazyNow lazy_now(now_src_.get());
- queue1->PumpQueue(&lazy_now, true);
- EXPECT_FALSE(queue0->HasPendingImmediateWork());
- EXPECT_FALSE(queue0->NeedsPumping());
- EXPECT_TRUE(queue1->HasPendingImmediateWork());
- EXPECT_FALSE(queue1->NeedsPumping());
-
- test_task_runner_->RunUntilIdle();
- EXPECT_FALSE(queue0->HasPendingImmediateWork());
- EXPECT_FALSE(queue0->NeedsPumping());
- EXPECT_FALSE(queue1->HasPendingImmediateWork());
- EXPECT_FALSE(queue1->NeedsPumping());
-}
-
-void ExpensiveTestTask(int value,
- base::SimpleTestTickClock* clock,
- std::vector<EnqueueOrder>* out_result) {
- out_result->push_back(value);
- clock->Advance(base::TimeDelta::FromMilliseconds(1));
-}
-
-TEST_F(TaskQueueManagerTest, ImmediateAndDelayedTaskInterleaving) {
- Initialize(1u);
-
- std::vector<EnqueueOrder> run_order;
- base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10);
- for (int i = 10; i < 19; i++) {
- runners_[0]->PostDelayedTask(
- FROM_HERE,
- base::Bind(&ExpensiveTestTask, i, now_src_.get(), &run_order),
- delay);
- }
-
- test_task_runner_->RunForPeriod(delay);
-
- for (int i = 0; i < 9; i++) {
- runners_[0]->PostTask(
- FROM_HERE,
- base::Bind(&ExpensiveTestTask, i, now_src_.get(), &run_order));
- }
-
- test_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
- test_task_runner_->RunUntilIdle();
-
- // Delayed tasks are not allowed to starve out immediate work which is why
- // some of the immediate tasks run out of order.
- int expected_run_order[] = {
- 10, 11, 12, 13, 0, 14, 15, 16, 1, 17, 18, 2, 3, 4, 5, 6, 7, 8
- };
- EXPECT_THAT(run_order, ElementsAreArray(expected_run_order));
-}
-
-TEST_F(TaskQueueManagerTest,
- DelayedTaskDoesNotSkipAHeadOfNonDelayedTask_SameQueue) {
- Initialize(1u);
-
- std::vector<EnqueueOrder> run_order;
- base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10);
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- delay);
-
- now_src_->Advance(delay * 2);
- test_task_runner_->RunUntilIdle();
-
- EXPECT_THAT(run_order, ElementsAre(2, 3, 1));
-}
-
-TEST_F(TaskQueueManagerTest,
- DelayedTaskDoesNotSkipAHeadOfNonDelayedTask_DifferentQueues) {
- Initialize(2u);
-
- std::vector<EnqueueOrder> run_order;
- base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10);
- runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- delay);
-
- now_src_->Advance(delay * 2);
- test_task_runner_->RunUntilIdle();
-
- EXPECT_THAT(run_order, ElementsAre(2, 3, 1));
-}
-
-TEST_F(TaskQueueManagerTest, DelayedTaskDoesNotSkipAHeadOfShorterDelayedTask) {
- Initialize(2u);
-
- std::vector<EnqueueOrder> run_order;
- base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10);
- base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(5);
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- delay1);
- runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
- delay2);
-
- now_src_->Advance(delay1 * 2);
- test_task_runner_->RunUntilIdle();
-
- EXPECT_THAT(run_order, ElementsAre(2, 1));
-}
-
-void CheckIsNested(bool* is_nested) {
- *is_nested = base::MessageLoop::current()->IsNested();
-}
-
-void PostAndQuitFromNestedRunloop(base::RunLoop* run_loop,
- base::SingleThreadTaskRunner* runner,
- bool* was_nested) {
- base::MessageLoop::ScopedNestableTaskAllower allow(
- base::MessageLoop::current());
- runner->PostTask(FROM_HERE, run_loop->QuitClosure());
- runner->PostTask(FROM_HERE, base::Bind(&CheckIsNested, was_nested));
- run_loop->Run();
-}
-
-TEST_F(TaskQueueManagerTest, QuitWhileNested) {
- // This test makes sure we don't continue running a work batch after a nested
- // run loop has been exited in the middle of the batch.
- InitializeWithRealMessageLoop(1u);
- manager_->SetWorkBatchSize(2);
-
- bool was_nested = true;
- base::RunLoop run_loop;
- runners_[0]->PostTask(FROM_HERE, base::Bind(&PostAndQuitFromNestedRunloop,
- base::Unretained(&run_loop),
- base::RetainedRef(runners_[0]),
- base::Unretained(&was_nested)));
-
- message_loop_->RunUntilIdle();
- EXPECT_FALSE(was_nested);
-}
-
-class SequenceNumberCapturingTaskObserver
- : public base::MessageLoop::TaskObserver {
- public:
- // MessageLoop::TaskObserver overrides.
- void WillProcessTask(const base::PendingTask& pending_task) override {}
- void DidProcessTask(const base::PendingTask& pending_task) override {
- sequence_numbers_.push_back(pending_task.sequence_num);
- }
-
- const std::vector<EnqueueOrder>& sequence_numbers() const {
- return sequence_numbers_;
- }
-
- private:
- std::vector<EnqueueOrder> sequence_numbers_;
-};
-
-TEST_F(TaskQueueManagerTest, SequenceNumSetWhenTaskIsPosted) {
- Initialize(1u);
-
- SequenceNumberCapturingTaskObserver observer;
- manager_->AddTaskObserver(&observer);
-
- // Register four tasks that will run in reverse order.
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- base::TimeDelta::FromMilliseconds(30));
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
- base::TimeDelta::FromMilliseconds(20));
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
- base::TimeDelta::FromMilliseconds(10));
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order));
-
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(40));
- ASSERT_THAT(run_order, ElementsAre(4, 3, 2, 1));
-
- // The sequence numbers are a zero-based monotonically incrememting counter
- // which should be set when the task is posted rather than when it's enqueued
- // onto the Incoming queue.
- EXPECT_THAT(observer.sequence_numbers(), ElementsAre(3, 2, 1, 0));
-
- manager_->RemoveTaskObserver(&observer);
-}
-
-TEST_F(TaskQueueManagerTest, NewTaskQueues) {
- Initialize(1u);
-
- scoped_refptr<internal::TaskQueueImpl> queue1 =
- manager_->NewTaskQueue(TaskQueue::Spec("foo"));
- scoped_refptr<internal::TaskQueueImpl> queue2 =
- manager_->NewTaskQueue(TaskQueue::Spec("bar"));
- scoped_refptr<internal::TaskQueueImpl> queue3 =
- manager_->NewTaskQueue(TaskQueue::Spec("baz"));
-
- ASSERT_NE(queue1, queue2);
- ASSERT_NE(queue1, queue3);
- ASSERT_NE(queue2, queue3);
-
- std::vector<EnqueueOrder> run_order;
- queue1->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- queue2->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- queue3->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
- test_task_runner_->RunUntilIdle();
-
- EXPECT_THAT(run_order, ElementsAre(1, 2, 3));
-}
-
-TEST_F(TaskQueueManagerTest, UnregisterTaskQueue) {
- Initialize(1u);
-
- scoped_refptr<internal::TaskQueueImpl> queue1 =
- manager_->NewTaskQueue(TaskQueue::Spec("foo"));
- scoped_refptr<internal::TaskQueueImpl> queue2 =
- manager_->NewTaskQueue(TaskQueue::Spec("bar"));
- scoped_refptr<internal::TaskQueueImpl> queue3 =
- manager_->NewTaskQueue(TaskQueue::Spec("baz"));
-
- ASSERT_NE(queue1, queue2);
- ASSERT_NE(queue1, queue3);
- ASSERT_NE(queue2, queue3);
-
- std::vector<EnqueueOrder> run_order;
- queue1->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- queue2->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- queue3->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
-
- queue2->UnregisterTaskQueue();
- test_task_runner_->RunUntilIdle();
-
- EXPECT_THAT(run_order, ElementsAre(1, 3));
-}
-
-TEST_F(TaskQueueManagerTest, UnregisterTaskQueue_WithDelayedTasks) {
- Initialize(2u);
-
- // Register three delayed tasks
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- base::TimeDelta::FromMilliseconds(10));
- runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
- base::TimeDelta::FromMilliseconds(20));
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
- base::TimeDelta::FromMilliseconds(30));
-
- runners_[1]->UnregisterTaskQueue();
- test_task_runner_->RunUntilIdle();
-
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(40));
- ASSERT_THAT(run_order, ElementsAre(1, 3));
-}
-
-namespace {
-void UnregisterQueue(scoped_refptr<internal::TaskQueueImpl> queue) {
- queue->UnregisterTaskQueue();
-}
-}
-
-TEST_F(TaskQueueManagerTest, UnregisterTaskQueue_InTasks) {
- Initialize(3u);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runners_[0]->PostTask(FROM_HERE, base::Bind(&UnregisterQueue, runners_[1]));
- runners_[0]->PostTask(FROM_HERE, base::Bind(&UnregisterQueue, runners_[2]));
- runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- runners_[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
-
- test_task_runner_->RunUntilIdle();
- ASSERT_THAT(run_order, ElementsAre(1));
-}
-
-void PostTestTasksFromNestedMessageLoop(
- base::MessageLoop* message_loop,
- scoped_refptr<base::SingleThreadTaskRunner> main_runner,
- scoped_refptr<base::SingleThreadTaskRunner> wake_up_runner,
- std::vector<EnqueueOrder>* run_order) {
- base::MessageLoop::ScopedNestableTaskAllower allow(message_loop);
- main_runner->PostNonNestableTask(FROM_HERE,
- base::Bind(&TestTask, 1, run_order));
- // The following should never get executed.
- wake_up_runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, run_order));
- base::RunLoop().RunUntilIdle();
-}
-
-TEST_F(TaskQueueManagerTest, DeferredNonNestableTaskDoesNotTriggerWakeUp) {
- // This test checks that running (i.e., deferring) a non-nestable task in a
- // nested run loop does not trigger the pumping of an on-wakeup queue.
- InitializeWithRealMessageLoop(2u);
- runners_[1]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostTask(
- FROM_HERE,
- base::Bind(&PostTestTasksFromNestedMessageLoop, message_loop_.get(),
- runners_[0], runners_[1], base::Unretained(&run_order)));
-
- message_loop_->RunUntilIdle();
- ASSERT_THAT(run_order, ElementsAre(1));
-}
-
-namespace {
-
-class MockObserver : public TaskQueueManager::Observer {
- public:
- MOCK_METHOD1(OnUnregisterTaskQueue,
- void(const scoped_refptr<TaskQueue>& queue));
- MOCK_METHOD2(OnTriedToExecuteBlockedTask,
- void(const TaskQueue& queue, const base::PendingTask& task));
-};
-
-} // namespace
-
-TEST_F(TaskQueueManagerTest, OnUnregisterTaskQueue) {
- Initialize(0u);
-
- MockObserver observer;
- manager_->SetObserver(&observer);
-
- scoped_refptr<internal::TaskQueueImpl> task_queue =
- manager_->NewTaskQueue(TaskQueue::Spec("test_queue"));
-
- EXPECT_CALL(observer, OnUnregisterTaskQueue(_)).Times(1);
- task_queue->UnregisterTaskQueue();
-
- manager_->SetObserver(nullptr);
-}
-
-TEST_F(TaskQueueManagerTest, OnTriedToExecuteBlockedTask) {
- Initialize(0u);
-
- MockObserver observer;
- manager_->SetObserver(&observer);
-
- scoped_refptr<internal::TaskQueueImpl> task_queue = manager_->NewTaskQueue(
- TaskQueue::Spec("test_queue").SetShouldReportWhenExecutionBlocked(true));
- task_queue->SetQueueEnabled(false);
- task_queue->PostTask(FROM_HERE, base::Bind(&NopTask));
-
- EXPECT_CALL(observer, OnTriedToExecuteBlockedTask(_, _)).Times(1);
- test_task_runner_->RunPendingTasks();
-
- manager_->SetObserver(nullptr);
-}
-
-TEST_F(TaskQueueManagerTest, ExecutedNonBlockedTask) {
- Initialize(0u);
-
- MockObserver observer;
- manager_->SetObserver(&observer);
-
- scoped_refptr<internal::TaskQueueImpl> task_queue = manager_->NewTaskQueue(
- TaskQueue::Spec("test_queue").SetShouldReportWhenExecutionBlocked(true));
- task_queue->PostTask(FROM_HERE, base::Bind(&NopTask));
-
- EXPECT_CALL(observer, OnTriedToExecuteBlockedTask(_, _)).Times(0);
- test_task_runner_->RunPendingTasks();
-
- manager_->SetObserver(nullptr);
-}
-
-void HasOneRefTask(std::vector<bool>* log, internal::TaskQueueImpl* tq) {
- log->push_back(tq->HasOneRef());
-}
-
-TEST_F(TaskQueueManagerTest, UnregisterTaskQueueInNestedLoop) {
- InitializeWithRealMessageLoop(1u);
-
- // We retain a reference to the task queue even when the manager has deleted
- // its reference.
- scoped_refptr<internal::TaskQueueImpl> task_queue =
- manager_->NewTaskQueue(TaskQueue::Spec("test_queue"));
-
- std::vector<bool> log;
- std::vector<std::pair<base::Closure, bool>> tasks_to_post_from_nested_loop;
-
- // Inside a nested run loop, call task_queue->UnregisterTaskQueue, bookended
- // by calls to HasOneRefTask to make sure the manager doesn't release its
- // reference until the nested run loop exits.
- // NB: This first HasOneRefTask is a sanity check.
- tasks_to_post_from_nested_loop.push_back(
- std::make_pair(base::Bind(&HasOneRefTask, base::Unretained(&log),
- base::Unretained(task_queue.get())),
- true));
- tasks_to_post_from_nested_loop.push_back(std::make_pair(
- base::Bind(&internal::TaskQueueImpl::UnregisterTaskQueue,
- base::Unretained(task_queue.get())), true));
- tasks_to_post_from_nested_loop.push_back(
- std::make_pair(base::Bind(&HasOneRefTask, base::Unretained(&log),
- base::Unretained(task_queue.get())),
- true));
- runners_[0]->PostTask(
- FROM_HERE, base::Bind(&PostFromNestedRunloop, message_loop_.get(),
- base::RetainedRef(runners_[0]),
- base::Unretained(&tasks_to_post_from_nested_loop)));
- message_loop_->RunUntilIdle();
-
- // Add a final call to HasOneRefTask. This gives the manager a chance to
- // release its reference, and checks that it has.
- runners_[0]->PostTask(FROM_HERE,
- base::Bind(&HasOneRefTask, base::Unretained(&log),
- base::Unretained(task_queue.get())));
- message_loop_->RunUntilIdle();
-
- EXPECT_THAT(log, ElementsAre(false, false, true));
-}
-
-TEST_F(TaskQueueManagerTest, TimeDomainsAreIndependant) {
- Initialize(2u);
-
- base::TimeTicks start_time = manager_->delegate()->NowTicks();
- std::unique_ptr<VirtualTimeDomain> domain_a(
- new VirtualTimeDomain(nullptr, start_time));
- std::unique_ptr<VirtualTimeDomain> domain_b(
- new VirtualTimeDomain(nullptr, start_time));
- manager_->RegisterTimeDomain(domain_a.get());
- manager_->RegisterTimeDomain(domain_b.get());
- runners_[0]->SetTimeDomain(domain_a.get());
- runners_[1]->SetTimeDomain(domain_b.get());
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- base::TimeDelta::FromMilliseconds(10));
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
- base::TimeDelta::FromMilliseconds(20));
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
- base::TimeDelta::FromMilliseconds(30));
-
- runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order),
- base::TimeDelta::FromMilliseconds(10));
- runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 5, &run_order),
- base::TimeDelta::FromMilliseconds(20));
- runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 6, &run_order),
- base::TimeDelta::FromMilliseconds(30));
-
- domain_b->AdvanceTo(start_time + base::TimeDelta::FromMilliseconds(50));
- manager_->MaybeScheduleImmediateWork(FROM_HERE);
-
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(4, 5, 6));
-
- domain_a->AdvanceTo(start_time + base::TimeDelta::FromMilliseconds(50));
- manager_->MaybeScheduleImmediateWork(FROM_HERE);
-
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(4, 5, 6, 1, 2, 3));
-
- runners_[0]->UnregisterTaskQueue();
- runners_[1]->UnregisterTaskQueue();
-
- manager_->UnregisterTimeDomain(domain_a.get());
- manager_->UnregisterTimeDomain(domain_b.get());
-}
-
-TEST_F(TaskQueueManagerTest, TimeDomainMigration) {
- Initialize(1u);
-
- base::TimeTicks start_time = manager_->delegate()->NowTicks();
- std::unique_ptr<VirtualTimeDomain> domain_a(
- new VirtualTimeDomain(nullptr, start_time));
- manager_->RegisterTimeDomain(domain_a.get());
- runners_[0]->SetTimeDomain(domain_a.get());
-
- std::vector<EnqueueOrder> run_order;
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- base::TimeDelta::FromMilliseconds(10));
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
- base::TimeDelta::FromMilliseconds(20));
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
- base::TimeDelta::FromMilliseconds(30));
- runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order),
- base::TimeDelta::FromMilliseconds(40));
-
- domain_a->AdvanceTo(start_time + base::TimeDelta::FromMilliseconds(20));
- manager_->MaybeScheduleImmediateWork(FROM_HERE);
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1, 2));
-
- std::unique_ptr<VirtualTimeDomain> domain_b(
- new VirtualTimeDomain(nullptr, start_time));
- manager_->RegisterTimeDomain(domain_b.get());
- runners_[0]->SetTimeDomain(domain_b.get());
-
- domain_b->AdvanceTo(start_time + base::TimeDelta::FromMilliseconds(50));
- manager_->MaybeScheduleImmediateWork(FROM_HERE);
-
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4));
-
- runners_[0]->UnregisterTaskQueue();
-
- manager_->UnregisterTimeDomain(domain_a.get());
- manager_->UnregisterTimeDomain(domain_b.get());
-}
-
-namespace {
-void ChromiumRunloopInspectionTask(
- scoped_refptr<cc::OrderedSimpleTaskRunner> test_task_runner) {
- EXPECT_EQ(1u, test_task_runner->NumPendingTasks());
-}
-} // namespace
-
-TEST_F(TaskQueueManagerTest, NumberOfPendingTasksOnChromiumRunLoop) {
- Initialize(1u);
-
- // NOTE because tasks posted to the chromiumrun loop are not cancellable, we
- // will end up with a lot more tasks posted if the delayed tasks were posted
- // in the reverse order.
- // TODO(alexclarke): Consider talking to the message pump directly.
- test_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
- for (int i = 1; i < 100; i++) {
- runners_[0]->PostDelayedTask(
- FROM_HERE,
- base::Bind(&ChromiumRunloopInspectionTask, test_task_runner_),
- base::TimeDelta::FromMilliseconds(i));
- }
- test_task_runner_->RunUntilIdle();
-}
-
-namespace {
-
-class QuadraticTask {
- public:
- QuadraticTask(scoped_refptr<internal::TaskQueueImpl> task_queue,
- base::TimeDelta delay,
- base::SimpleTestTickClock* now_src)
- : count_(0), task_queue_(task_queue), delay_(delay), now_src_(now_src) {}
-
- void SetShouldExit(base::Callback<bool()> should_exit) {
- should_exit_ = should_exit;
- }
-
- void Run() {
- if (should_exit_.Run())
- return;
- count_++;
- task_queue_->PostDelayedTask(
- FROM_HERE, base::Bind(&QuadraticTask::Run, base::Unretained(this)),
- delay_);
- task_queue_->PostDelayedTask(
- FROM_HERE, base::Bind(&QuadraticTask::Run, base::Unretained(this)),
- delay_);
- now_src_->Advance(base::TimeDelta::FromMilliseconds(5));
- }
-
- int count() const { return count_; }
-
- private:
- int count_;
- scoped_refptr<internal::TaskQueueImpl> task_queue_;
- base::TimeDelta delay_;
- base::Callback<bool()> should_exit_;
- base::SimpleTestTickClock* now_src_;
-};
-
-class LinearTask {
- public:
- LinearTask(scoped_refptr<internal::TaskQueueImpl> task_queue,
- base::TimeDelta delay,
- base::SimpleTestTickClock* now_src)
- : count_(0), task_queue_(task_queue), delay_(delay), now_src_(now_src) {}
-
- void SetShouldExit(base::Callback<bool()> should_exit) {
- should_exit_ = should_exit;
- }
-
- void Run() {
- if (should_exit_.Run())
- return;
- count_++;
- task_queue_->PostDelayedTask(
- FROM_HERE, base::Bind(&LinearTask::Run, base::Unretained(this)),
- delay_);
- now_src_->Advance(base::TimeDelta::FromMilliseconds(5));
- }
-
- int count() const { return count_; }
-
- private:
- int count_;
- scoped_refptr<internal::TaskQueueImpl> task_queue_;
- base::TimeDelta delay_;
- base::Callback<bool()> should_exit_;
- base::SimpleTestTickClock* now_src_;
-};
-
-bool ShouldExit(QuadraticTask* quadratic_task, LinearTask* linear_task) {
- return quadratic_task->count() == 1000 || linear_task->count() == 1000;
-}
-
-} // namespace
-
-TEST_F(TaskQueueManagerTest,
- DelayedTasksDontBadlyStarveNonDelayedWork_SameQueue) {
- Initialize(1u);
-
- QuadraticTask quadratic_delayed_task(
- runners_[0], base::TimeDelta::FromMilliseconds(10), now_src_.get());
- LinearTask linear_immediate_task(runners_[0], base::TimeDelta(),
- now_src_.get());
- base::Callback<bool()> should_exit =
- base::Bind(ShouldExit, &quadratic_delayed_task, &linear_immediate_task);
- quadratic_delayed_task.SetShouldExit(should_exit);
- linear_immediate_task.SetShouldExit(should_exit);
-
- quadratic_delayed_task.Run();
- linear_immediate_task.Run();
-
- test_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
- test_task_runner_->RunUntilIdle();
-
- double ratio = static_cast<double>(linear_immediate_task.count()) /
- static_cast<double>(quadratic_delayed_task.count());
-
- EXPECT_GT(ratio, 0.333);
- EXPECT_LT(ratio, 1.1);
-}
-
-TEST_F(TaskQueueManagerTest, ImmediateWorkCanStarveDelayedTasks_SameQueue) {
- Initialize(1u);
-
- QuadraticTask quadratic_immediate_task(runners_[0], base::TimeDelta(),
- now_src_.get());
- LinearTask linear_delayed_task(
- runners_[0], base::TimeDelta::FromMilliseconds(10), now_src_.get());
- base::Callback<bool()> should_exit =
- base::Bind(&ShouldExit, &quadratic_immediate_task, &linear_delayed_task);
-
- quadratic_immediate_task.SetShouldExit(should_exit);
- linear_delayed_task.SetShouldExit(should_exit);
-
- quadratic_immediate_task.Run();
- linear_delayed_task.Run();
-
- test_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
- test_task_runner_->RunUntilIdle();
-
- double ratio = static_cast<double>(linear_delayed_task.count()) /
- static_cast<double>(quadratic_immediate_task.count());
-
- // This is by design, we want to enforce a strict ordering in task execution
- // where by delayed tasks can not skip ahead of non-delayed work.
- EXPECT_GT(ratio, 0.0);
- EXPECT_LT(ratio, 0.1);
-}
-
-TEST_F(TaskQueueManagerTest,
- DelayedTasksDontBadlyStarveNonDelayedWork_DifferentQueue) {
- Initialize(2u);
-
- QuadraticTask quadratic_delayed_task(
- runners_[0], base::TimeDelta::FromMilliseconds(10), now_src_.get());
- LinearTask linear_immediate_task(runners_[1], base::TimeDelta(),
- now_src_.get());
- base::Callback<bool()> should_exit =
- base::Bind(ShouldExit, &quadratic_delayed_task, &linear_immediate_task);
- quadratic_delayed_task.SetShouldExit(should_exit);
- linear_immediate_task.SetShouldExit(should_exit);
-
- quadratic_delayed_task.Run();
- linear_immediate_task.Run();
-
- test_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
- test_task_runner_->RunUntilIdle();
-
- double ratio = static_cast<double>(linear_immediate_task.count()) /
- static_cast<double>(quadratic_delayed_task.count());
-
- EXPECT_GT(ratio, 0.333);
- EXPECT_LT(ratio, 1.1);
-}
-
-TEST_F(TaskQueueManagerTest,
- ImmediateWorkCanStarveDelayedTasks_DifferentQueue) {
- Initialize(2u);
-
- QuadraticTask quadratic_immediate_task(runners_[0], base::TimeDelta(),
- now_src_.get());
- LinearTask linear_delayed_task(
- runners_[1], base::TimeDelta::FromMilliseconds(10), now_src_.get());
- base::Callback<bool()> should_exit =
- base::Bind(&ShouldExit, &quadratic_immediate_task, &linear_delayed_task);
-
- quadratic_immediate_task.SetShouldExit(should_exit);
- linear_delayed_task.SetShouldExit(should_exit);
-
- quadratic_immediate_task.Run();
- linear_delayed_task.Run();
-
- test_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
- test_task_runner_->RunUntilIdle();
-
- double ratio = static_cast<double>(linear_delayed_task.count()) /
- static_cast<double>(quadratic_immediate_task.count());
-
- // This is by design, we want to enforce a strict ordering in task execution
- // where by delayed tasks can not skip ahead of non-delayed work.
- EXPECT_GT(ratio, 0.0);
- EXPECT_LT(ratio, 0.1);
-}
-
-TEST_F(TaskQueueManagerTest, CurrentlyExecutingTaskQueue_NoTaskRunning) {
- Initialize(1u);
-
- EXPECT_EQ(nullptr, manager_->currently_executing_task_queue());
-}
-
-namespace {
-void CurrentlyExecutingTaskQueueTestTask(TaskQueueManager* task_queue_manager,
- std::vector<TaskQueue*>* task_sources) {
- task_sources->push_back(task_queue_manager->currently_executing_task_queue());
-}
-}
-
-TEST_F(TaskQueueManagerTest, CurrentlyExecutingTaskQueue_TaskRunning) {
- Initialize(2u);
-
- internal::TaskQueueImpl* queue0 = runners_[0].get();
- internal::TaskQueueImpl* queue1 = runners_[1].get();
-
- std::vector<TaskQueue*> task_sources;
- queue0->PostTask(FROM_HERE, base::Bind(&CurrentlyExecutingTaskQueueTestTask,
- manager_.get(), &task_sources));
- queue1->PostTask(FROM_HERE, base::Bind(&CurrentlyExecutingTaskQueueTestTask,
- manager_.get(), &task_sources));
- test_task_runner_->RunUntilIdle();
-
- EXPECT_THAT(task_sources, ElementsAre(queue0, queue1));
- EXPECT_EQ(nullptr, manager_->currently_executing_task_queue());
-}
-
-namespace {
-void RunloopCurrentlyExecutingTaskQueueTestTask(
- base::MessageLoop* message_loop,
- TaskQueueManager* task_queue_manager,
- std::vector<TaskQueue*>* task_sources,
- std::vector<std::pair<base::Closure, TaskQueue*>>* tasks) {
- base::MessageLoop::ScopedNestableTaskAllower allow(message_loop);
- task_sources->push_back(task_queue_manager->currently_executing_task_queue());
-
- for (std::pair<base::Closure, TaskQueue*>& pair : *tasks) {
- pair.second->PostTask(FROM_HERE, pair.first);
- }
-
- base::RunLoop().RunUntilIdle();
- task_sources->push_back(task_queue_manager->currently_executing_task_queue());
-}
-}
-
-TEST_F(TaskQueueManagerTest, CurrentlyExecutingTaskQueue_NestedLoop) {
- InitializeWithRealMessageLoop(3u);
-
- TaskQueue* queue0 = runners_[0].get();
- TaskQueue* queue1 = runners_[1].get();
- TaskQueue* queue2 = runners_[2].get();
-
- std::vector<TaskQueue*> task_sources;
- std::vector<std::pair<base::Closure, TaskQueue*>>
- tasks_to_post_from_nested_loop;
- tasks_to_post_from_nested_loop.push_back(
- std::make_pair(base::Bind(&CurrentlyExecutingTaskQueueTestTask,
- manager_.get(), &task_sources),
- queue1));
- tasks_to_post_from_nested_loop.push_back(
- std::make_pair(base::Bind(&CurrentlyExecutingTaskQueueTestTask,
- manager_.get(), &task_sources),
- queue2));
-
- queue0->PostTask(
- FROM_HERE, base::Bind(&RunloopCurrentlyExecutingTaskQueueTestTask,
- message_loop_.get(), manager_.get(), &task_sources,
- &tasks_to_post_from_nested_loop));
-
- message_loop_->RunUntilIdle();
- EXPECT_THAT(task_sources, ElementsAre(queue0, queue1, queue2, queue0));
- EXPECT_EQ(nullptr, manager_->currently_executing_task_queue());
-}
-
-void OnTraceDataCollected(base::Closure quit_closure,
- base::trace_event::TraceResultBuffer* buffer,
- const scoped_refptr<base::RefCountedString>& json,
- bool has_more_events) {
- buffer->AddFragment(json->data());
- if (!has_more_events)
- quit_closure.Run();
-}
-
-class TaskQueueManagerTestWithTracing : public TaskQueueManagerTest {
- public:
- void StartTracing();
- void StopTracing();
- std::unique_ptr<trace_analyzer::TraceAnalyzer> CreateTraceAnalyzer();
-};
-
-void TaskQueueManagerTestWithTracing::StartTracing() {
- base::trace_event::TraceLog::GetInstance()->SetEnabled(
- base::trace_event::TraceConfig("*"),
- base::trace_event::TraceLog::RECORDING_MODE);
-}
-
-void TaskQueueManagerTestWithTracing::StopTracing() {
- base::trace_event::TraceLog::GetInstance()->SetDisabled();
-}
-
-std::unique_ptr<trace_analyzer::TraceAnalyzer>
-TaskQueueManagerTestWithTracing::CreateTraceAnalyzer() {
- base::trace_event::TraceResultBuffer buffer;
- base::trace_event::TraceResultBuffer::SimpleOutput trace_output;
- buffer.SetOutputCallback(trace_output.GetCallback());
- base::RunLoop run_loop;
- buffer.Start();
- base::trace_event::TraceLog::GetInstance()->Flush(
- Bind(&OnTraceDataCollected, run_loop.QuitClosure(),
- base::Unretained(&buffer)));
- run_loop.Run();
- buffer.Finish();
-
- return base::WrapUnique(
- trace_analyzer::TraceAnalyzer::Create(trace_output.json_output));
-}
-
-TEST_F(TaskQueueManagerTestWithTracing, BlameContextAttribution) {
- using trace_analyzer::Query;
-
- InitializeWithRealMessageLoop(1u);
- TaskQueue* queue = runners_[0].get();
-
- StartTracing();
- {
- base::trace_event::BlameContext blame_context("cat", "name", "type",
- "scope", 0, nullptr);
- blame_context.Initialize();
- queue->SetBlameContext(&blame_context);
- queue->PostTask(FROM_HERE, base::Bind(&NopTask));
- message_loop_->RunUntilIdle();
- }
- StopTracing();
- std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer =
- CreateTraceAnalyzer();
-
- trace_analyzer::TraceEventVector events;
- Query q = Query::EventPhaseIs(TRACE_EVENT_PHASE_ENTER_CONTEXT) ||
- Query::EventPhaseIs(TRACE_EVENT_PHASE_LEAVE_CONTEXT);
- analyzer->FindEvents(q, &events);
-
- EXPECT_EQ(2u, events.size());
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/base/task_queue_selector.cc b/chromium/components/scheduler/base/task_queue_selector.cc
deleted file mode 100644
index 9db8ab9c2de..00000000000
--- a/chromium/components/scheduler/base/task_queue_selector.cc
+++ /dev/null
@@ -1,380 +0,0 @@
-// Copyright 2014 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/scheduler/base/task_queue_selector.h"
-
-#include "base/logging.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "components/scheduler/base/task_queue_impl.h"
-#include "components/scheduler/base/work_queue.h"
-
-namespace scheduler {
-namespace internal {
-
-TaskQueueSelector::TaskQueueSelector()
- : enabled_selector_(this, "enabled"),
- blocked_selector_(this, "blocked"),
- immediate_starvation_count_(0),
- high_priority_starvation_count_(0),
- num_blocked_queues_to_report_(0),
- task_queue_selector_observer_(nullptr) {}
-
-TaskQueueSelector::~TaskQueueSelector() {}
-
-void TaskQueueSelector::AddQueue(internal::TaskQueueImpl* queue) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- DCHECK(queue->IsQueueEnabled());
- enabled_selector_.AddQueue(queue, TaskQueue::NORMAL_PRIORITY);
-}
-
-void TaskQueueSelector::RemoveQueue(internal::TaskQueueImpl* queue) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- if (queue->IsQueueEnabled()) {
- enabled_selector_.RemoveQueue(queue);
-// The #if DCHECK_IS_ON() shouldn't be necessary but this doesn't compile on
-// chromeos bots without it :(
-#if DCHECK_IS_ON()
- DCHECK(!blocked_selector_.CheckContainsQueueForTest(queue));
-#endif
- } else if (queue->should_report_when_execution_blocked()) {
- DCHECK_GT(num_blocked_queues_to_report_, 0u);
- num_blocked_queues_to_report_--;
- blocked_selector_.RemoveQueue(queue);
-#if DCHECK_IS_ON()
- DCHECK(!enabled_selector_.CheckContainsQueueForTest(queue));
-#endif
- }
-}
-
-void TaskQueueSelector::EnableQueue(internal::TaskQueueImpl* queue) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- DCHECK(queue->IsQueueEnabled());
- if (queue->should_report_when_execution_blocked()) {
- DCHECK_GT(num_blocked_queues_to_report_, 0u);
- num_blocked_queues_to_report_--;
- blocked_selector_.RemoveQueue(queue);
- }
- enabled_selector_.AddQueue(queue, queue->GetQueuePriority());
- if (task_queue_selector_observer_)
- task_queue_selector_observer_->OnTaskQueueEnabled(queue);
-}
-
-void TaskQueueSelector::DisableQueue(internal::TaskQueueImpl* queue) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- DCHECK(!queue->IsQueueEnabled());
- enabled_selector_.RemoveQueue(queue);
- if (queue->should_report_when_execution_blocked()) {
- blocked_selector_.AddQueue(queue, queue->GetQueuePriority());
- num_blocked_queues_to_report_++;
- }
-}
-
-void TaskQueueSelector::SetQueuePriority(internal::TaskQueueImpl* queue,
- TaskQueue::QueuePriority priority) {
- DCHECK_LT(priority, TaskQueue::QUEUE_PRIORITY_COUNT);
- DCHECK(main_thread_checker_.CalledOnValidThread());
- if (queue->IsQueueEnabled()) {
- enabled_selector_.ChangeSetIndex(queue, priority);
- } else if (queue->should_report_when_execution_blocked()) {
- blocked_selector_.ChangeSetIndex(queue, priority);
- } else {
- // Normally blocked_selector_.ChangeSetIndex would assign the queue's
- // priority, however if |queue->should_report_when_execution_blocked()| is
- // false then the disabled queue is not in any set so we need to do it here.
- queue->delayed_work_queue()->AssignSetIndex(priority);
- queue->immediate_work_queue()->AssignSetIndex(priority);
- }
- DCHECK_EQ(priority, queue->GetQueuePriority());
-}
-
-TaskQueue::QueuePriority TaskQueueSelector::NextPriority(
- TaskQueue::QueuePriority priority) {
- DCHECK(priority < TaskQueue::QUEUE_PRIORITY_COUNT);
- return static_cast<TaskQueue::QueuePriority>(static_cast<int>(priority) + 1);
-}
-
-TaskQueueSelector::PrioritizingSelector::PrioritizingSelector(
- TaskQueueSelector* task_queue_selector,
- const char* name)
- : task_queue_selector_(task_queue_selector),
- delayed_work_queue_sets_(TaskQueue::QUEUE_PRIORITY_COUNT, name),
- immediate_work_queue_sets_(TaskQueue::QUEUE_PRIORITY_COUNT, name) {}
-
-void TaskQueueSelector::PrioritizingSelector::AddQueue(
- internal::TaskQueueImpl* queue,
- TaskQueue::QueuePriority priority) {
-#if DCHECK_IS_ON()
- DCHECK(!CheckContainsQueueForTest(queue));
-#endif
- delayed_work_queue_sets_.AddQueue(queue->delayed_work_queue(), priority);
- immediate_work_queue_sets_.AddQueue(queue->immediate_work_queue(), priority);
-#if DCHECK_IS_ON()
- DCHECK(CheckContainsQueueForTest(queue));
-#endif
-}
-
-void TaskQueueSelector::PrioritizingSelector::ChangeSetIndex(
- internal::TaskQueueImpl* queue,
- TaskQueue::QueuePriority priority) {
-#if DCHECK_IS_ON()
- DCHECK(CheckContainsQueueForTest(queue));
-#endif
- delayed_work_queue_sets_.ChangeSetIndex(queue->delayed_work_queue(),
- priority);
- immediate_work_queue_sets_.ChangeSetIndex(queue->immediate_work_queue(),
- priority);
-#if DCHECK_IS_ON()
- DCHECK(CheckContainsQueueForTest(queue));
-#endif
-}
-
-void TaskQueueSelector::PrioritizingSelector::RemoveQueue(
- internal::TaskQueueImpl* queue) {
-#if DCHECK_IS_ON()
- DCHECK(CheckContainsQueueForTest(queue));
-#endif
- delayed_work_queue_sets_.RemoveQueue(queue->delayed_work_queue());
- immediate_work_queue_sets_.RemoveQueue(queue->immediate_work_queue());
-
-#if DCHECK_IS_ON()
- DCHECK(!CheckContainsQueueForTest(queue));
-#endif
-}
-
-bool TaskQueueSelector::PrioritizingSelector::
- ChooseOldestImmediateTaskWithPriority(TaskQueue::QueuePriority priority,
- WorkQueue** out_work_queue) const {
- return immediate_work_queue_sets_.GetOldestQueueInSet(priority,
- out_work_queue);
-}
-
-bool TaskQueueSelector::PrioritizingSelector::
- ChooseOldestDelayedTaskWithPriority(TaskQueue::QueuePriority priority,
- WorkQueue** out_work_queue) const {
- return delayed_work_queue_sets_.GetOldestQueueInSet(priority, out_work_queue);
-}
-
-bool TaskQueueSelector::PrioritizingSelector::
- ChooseOldestImmediateOrDelayedTaskWithPriority(
- TaskQueue::QueuePriority priority,
- bool* out_chose_delayed_over_immediate,
- WorkQueue** out_work_queue) const {
- WorkQueue* immediate_queue;
- DCHECK_EQ(*out_chose_delayed_over_immediate, false);
- if (immediate_work_queue_sets_.GetOldestQueueInSet(priority,
- &immediate_queue)) {
- WorkQueue* delayed_queue;
- if (delayed_work_queue_sets_.GetOldestQueueInSet(priority,
- &delayed_queue)) {
- if (immediate_queue->ShouldRunBefore(delayed_queue)) {
- *out_work_queue = immediate_queue;
- } else {
- *out_chose_delayed_over_immediate = true;
- *out_work_queue = delayed_queue;
- }
- } else {
- *out_work_queue = immediate_queue;
- }
- return true;
- }
- return delayed_work_queue_sets_.GetOldestQueueInSet(priority, out_work_queue);
-}
-
-bool TaskQueueSelector::PrioritizingSelector::ChooseOldestWithPriority(
- TaskQueue::QueuePriority priority,
- bool* out_chose_delayed_over_immediate,
- WorkQueue** out_work_queue) const {
- // Select an immediate work queue if we are starving immediate tasks.
- if (task_queue_selector_->immediate_starvation_count_ >=
- kMaxDelayedStarvationTasks) {
- if (ChooseOldestImmediateTaskWithPriority(priority, out_work_queue)) {
- return true;
- }
- if (ChooseOldestDelayedTaskWithPriority(priority, out_work_queue)) {
- return true;
- }
- return false;
- }
- return ChooseOldestImmediateOrDelayedTaskWithPriority(
- priority, out_chose_delayed_over_immediate, out_work_queue);
-}
-
-bool TaskQueueSelector::PrioritizingSelector::SelectWorkQueueToService(
- TaskQueue::QueuePriority max_priority,
- WorkQueue** out_work_queue,
- bool* out_chose_delayed_over_immediate) {
- DCHECK(task_queue_selector_->main_thread_checker_.CalledOnValidThread());
- DCHECK_EQ(*out_chose_delayed_over_immediate, false);
-
- // Always service the control queue if it has any work.
- if (max_priority > TaskQueue::CONTROL_PRIORITY &&
- ChooseOldestWithPriority(TaskQueue::CONTROL_PRIORITY,
- out_chose_delayed_over_immediate,
- out_work_queue)) {
- return true;
- }
-
- // Select from the normal priority queue if we are starving it.
- if (max_priority > TaskQueue::NORMAL_PRIORITY &&
- task_queue_selector_->high_priority_starvation_count_ >=
- kMaxHighPriorityStarvationTasks &&
- ChooseOldestWithPriority(TaskQueue::NORMAL_PRIORITY,
- out_chose_delayed_over_immediate,
- out_work_queue)) {
- return true;
- }
- // Otherwise choose in priority order.
- for (TaskQueue::QueuePriority priority = TaskQueue::HIGH_PRIORITY;
- priority < max_priority; priority = NextPriority(priority)) {
- if (ChooseOldestWithPriority(priority, out_chose_delayed_over_immediate,
- out_work_queue)) {
- return true;
- }
- }
- return false;
-}
-
-#if DCHECK_IS_ON() || !defined(NDEBUG)
-bool
-TaskQueueSelector::PrioritizingSelector::CheckContainsQueueForTest(
- const internal::TaskQueueImpl* queue) const {
- bool contains_delayed_work_queue =
- delayed_work_queue_sets_.ContainsWorkQueueForTest(
- queue->delayed_work_queue());
-
- bool contains_immediate_work_queue =
- immediate_work_queue_sets_.ContainsWorkQueueForTest(
- queue->immediate_work_queue());
-
- DCHECK_EQ(contains_delayed_work_queue, contains_immediate_work_queue);
- return contains_delayed_work_queue;
-}
-#endif
-
-bool TaskQueueSelector::SelectWorkQueueToService(WorkQueue** out_work_queue) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- bool chose_delayed_over_immediate = false;
- bool found_queue = enabled_selector_.SelectWorkQueueToService(
- TaskQueue::QUEUE_PRIORITY_COUNT, out_work_queue,
- &chose_delayed_over_immediate);
- if (!found_queue) {
- TrySelectingBlockedQueue();
- return false;
- }
-
- TrySelectingBlockedQueueOverEnabledQueue(**out_work_queue);
- DidSelectQueueWithPriority(
- (*out_work_queue)->task_queue()->GetQueuePriority(),
- chose_delayed_over_immediate);
- return true;
-}
-
-void TaskQueueSelector::TrySelectingBlockedQueue() {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- if (!num_blocked_queues_to_report_ || !task_queue_selector_observer_)
- return;
- WorkQueue* chosen_blocked_queue;
- bool chose_delayed_over_immediate = false;
- // There was nothing unblocked to run, see if we could have run a blocked
- // task.
- if (blocked_selector_.SelectWorkQueueToService(
- TaskQueue::QUEUE_PRIORITY_COUNT, &chosen_blocked_queue,
- &chose_delayed_over_immediate)) {
- task_queue_selector_observer_->OnTriedToSelectBlockedWorkQueue(
- chosen_blocked_queue);
- }
-}
-
-void TaskQueueSelector::TrySelectingBlockedQueueOverEnabledQueue(
- const WorkQueue& chosen_enabled_queue) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- if (!num_blocked_queues_to_report_ || !task_queue_selector_observer_)
- return;
-
- TaskQueue::QueuePriority max_priority =
- NextPriority(chosen_enabled_queue.task_queue()->GetQueuePriority());
-
- WorkQueue* chosen_blocked_queue;
- bool chose_delayed_over_immediate = false;
- bool found_queue = blocked_selector_.SelectWorkQueueToService(
- max_priority, &chosen_blocked_queue, &chose_delayed_over_immediate);
- if (!found_queue)
- return;
-
- // Check if the chosen blocked queue has a lower numerical priority than the
- // chosen enabled queue. If so we would have chosen the blocked queue (since
- // zero is the highest priority).
- if (chosen_blocked_queue->task_queue()->GetQueuePriority() <
- chosen_enabled_queue.task_queue()->GetQueuePriority()) {
- task_queue_selector_observer_->OnTriedToSelectBlockedWorkQueue(
- chosen_blocked_queue);
- return;
- }
- DCHECK_EQ(chosen_blocked_queue->task_queue()->GetQueuePriority(),
- chosen_enabled_queue.task_queue()->GetQueuePriority());
- // Otherwise there was an enabled and a blocked task with the same priority.
- // The one with the older enqueue order wins.
- if (chosen_blocked_queue->ShouldRunBefore(&chosen_enabled_queue)) {
- task_queue_selector_observer_->OnTriedToSelectBlockedWorkQueue(
- chosen_blocked_queue);
- }
-}
-
-void TaskQueueSelector::DidSelectQueueWithPriority(
- TaskQueue::QueuePriority priority,
- bool chose_delayed_over_immediate) {
- switch (priority) {
- case TaskQueue::CONTROL_PRIORITY:
- break;
- case TaskQueue::HIGH_PRIORITY:
- high_priority_starvation_count_++;
- break;
- case TaskQueue::NORMAL_PRIORITY:
- case TaskQueue::BEST_EFFORT_PRIORITY:
- high_priority_starvation_count_ = 0;
- break;
- default:
- NOTREACHED();
- }
- if (chose_delayed_over_immediate) {
- immediate_starvation_count_++;
- } else {
- immediate_starvation_count_ = 0;
- }
-}
-
-void TaskQueueSelector::AsValueInto(
- base::trace_event::TracedValue* state) const {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- state->SetInteger("high_priority_starvation_count",
- high_priority_starvation_count_);
- state->SetInteger("immediate_starvation_count", immediate_starvation_count_);
- state->SetInteger("num_blocked_queues_to_report",
- num_blocked_queues_to_report_);
-}
-
-void TaskQueueSelector::SetTaskQueueSelectorObserver(Observer* observer) {
- task_queue_selector_observer_ = observer;
-}
-
-bool TaskQueueSelector::EnabledWorkQueuesEmpty() const {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- for (TaskQueue::QueuePriority priority = TaskQueue::CONTROL_PRIORITY;
- priority < TaskQueue::QUEUE_PRIORITY_COUNT;
- priority = NextPriority(priority)) {
- if (!enabled_selector_.delayed_work_queue_sets()->IsSetEmpty(priority) ||
- !enabled_selector_.immediate_work_queue_sets()->IsSetEmpty(priority)) {
- return false;
- }
- }
- return true;
-}
-
-void TaskQueueSelector::SetImmediateStarvationCountForTest(
- size_t immediate_starvation_count) {
- immediate_starvation_count_ = immediate_starvation_count;
-}
-
-} // namespace internal
-} // namespace scheduler
diff --git a/chromium/components/scheduler/base/task_queue_selector.h b/chromium/components/scheduler/base/task_queue_selector.h
deleted file mode 100644
index 4a82adcfbd3..00000000000
--- a/chromium/components/scheduler/base/task_queue_selector.h
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright 2015 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_SCHEDULER_BASE_TASK_QUEUE_SELECTOR_H_
-#define COMPONENTS_SCHEDULER_BASE_TASK_QUEUE_SELECTOR_H_
-
-#include <stddef.h>
-
-#include <set>
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "base/pending_task.h"
-#include "base/threading/thread_checker.h"
-#include "components/scheduler/base/work_queue_sets.h"
-#include "components/scheduler/scheduler_export.h"
-
-namespace scheduler {
-namespace internal {
-
-// TaskQueueSelector is used by the SchedulerHelper to enable prioritization
-// of particular task queues.
-class SCHEDULER_EXPORT TaskQueueSelector {
- public:
- TaskQueueSelector();
- ~TaskQueueSelector();
-
- // Called to register a queue that can be selected. This function is called
- // on the main thread.
- void AddQueue(internal::TaskQueueImpl* queue);
-
- // The specified work will no longer be considered for selection. This
- // function is called on the main thread.
- void RemoveQueue(internal::TaskQueueImpl* queue);
-
- // Make |queue| eligible for selection. This function is called on the main
- // thread. Must only be called if |queue| is disabled.
- void EnableQueue(internal::TaskQueueImpl* queue);
-
- // Disable selection from |queue|. If task blocking is enabled for the queue,
- // Observer::OnTriedToSelectBlockedWorkQueue will be emitted if the
- // SelectWorkQueueToService tries to select this disabled queue for execution.
- // Must only be called if |queue| is enabled.
- void DisableQueue(internal::TaskQueueImpl* queue);
-
- // Called get or set the priority of |queue|.
- void SetQueuePriority(internal::TaskQueueImpl* queue,
- TaskQueue::QueuePriority priority);
-
- // Called to choose the work queue from which the next task should be taken
- // and run. Return true if |out_work_queue| indicates the queue to service or
- // false to avoid running any task.
- //
- // This function is called on the main thread.
- bool SelectWorkQueueToService(WorkQueue** out_work_queue);
-
- // Serialize the selector state for tracing.
- void AsValueInto(base::trace_event::TracedValue* state) const;
-
- class SCHEDULER_EXPORT Observer {
- public:
- virtual ~Observer() {}
-
- // Called when |queue| transitions from disabled to enabled.
- virtual void OnTaskQueueEnabled(internal::TaskQueueImpl* queue) = 0;
-
- // Called when the selector tried to select a task from a disabled work
- // queue. See TaskQueue::Spec::SetShouldReportWhenExecutionBlocked. A single
- // call to SelectWorkQueueToService will only result in up to one
- // blocking notification even if multiple disabled queues could have been
- // selected.
- virtual void OnTriedToSelectBlockedWorkQueue(
- internal::WorkQueue* work_queue) = 0;
- };
-
- // Called once to set the Observer. This function is called
- // on the main thread. If |observer| is null, then no callbacks will occur.
- void SetTaskQueueSelectorObserver(Observer* observer);
-
- // Returns true if all the enabled work queues are empty. Returns false
- // otherwise.
- bool EnabledWorkQueuesEmpty() const;
-
- protected:
- class SCHEDULER_EXPORT PrioritizingSelector {
- public:
- PrioritizingSelector(TaskQueueSelector* task_queue_selector,
- const char* name);
-
- void ChangeSetIndex(internal::TaskQueueImpl* queue,
- TaskQueue::QueuePriority priority);
- void AddQueue(internal::TaskQueueImpl* queue,
- TaskQueue::QueuePriority priority);
- void RemoveQueue(internal::TaskQueueImpl* queue);
-
- bool SelectWorkQueueToService(TaskQueue::QueuePriority max_priority,
- WorkQueue** out_work_queue,
- bool* out_chose_delayed_over_immediate);
-
- WorkQueueSets* delayed_work_queue_sets() {
- return &delayed_work_queue_sets_;
- }
- WorkQueueSets* immediate_work_queue_sets() {
- return &immediate_work_queue_sets_;
- }
-
- const WorkQueueSets* delayed_work_queue_sets() const {
- return &delayed_work_queue_sets_;
- }
- const WorkQueueSets* immediate_work_queue_sets() const {
- return &immediate_work_queue_sets_;
- }
-
- bool ChooseOldestWithPriority(TaskQueue::QueuePriority priority,
- bool* out_chose_delayed_over_immediate,
- WorkQueue** out_work_queue) const;
-
-#if DCHECK_IS_ON() || !defined(NDEBUG)
- bool CheckContainsQueueForTest(const internal::TaskQueueImpl* queue) const;
-#endif
-
- private:
- bool ChooseOldestImmediateTaskWithPriority(
- TaskQueue::QueuePriority priority,
- WorkQueue** out_work_queue) const;
-
- bool ChooseOldestDelayedTaskWithPriority(TaskQueue::QueuePriority priority,
- WorkQueue** out_work_queue) const;
-
- // Return true if |out_queue| contains the queue with the oldest pending
- // task from the set of queues of |priority|, or false if all queues of that
- // priority are empty. In addition |out_chose_delayed_over_immediate| is set
- // to true iff we chose a delayed work queue in favour of an immediate work
- // queue.
- bool ChooseOldestImmediateOrDelayedTaskWithPriority(
- TaskQueue::QueuePriority priority,
- bool* out_chose_delayed_over_immediate,
- WorkQueue** out_work_queue) const;
-
- const TaskQueueSelector* task_queue_selector_;
- WorkQueueSets delayed_work_queue_sets_;
- WorkQueueSets immediate_work_queue_sets_;
-
- DISALLOW_COPY_AND_ASSIGN(PrioritizingSelector);
- };
-
- // Return true if |out_queue| contains the queue with the oldest pending task
- // from the set of queues of |priority|, or false if all queues of that
- // priority are empty. In addition |out_chose_delayed_over_immediate| is set
- // to true iff we chose a delayed work queue in favour of an immediate work
- // queue. This method will force select an immediate task if those are being
- // starved by delayed tasks.
- void SetImmediateStarvationCountForTest(size_t immediate_starvation_count);
-
- PrioritizingSelector* enabled_selector_for_test() {
- return &enabled_selector_;
- }
-
- private:
- // Returns the priority which is next after |priority|.
- static TaskQueue::QueuePriority NextPriority(
- TaskQueue::QueuePriority priority);
-
- bool SelectWorkQueueToServiceInternal(WorkQueue** out_work_queue);
-
- // Called whenever the selector chooses a task queue for execution with the
- // priority |priority|.
- void DidSelectQueueWithPriority(TaskQueue::QueuePriority priority,
- bool chose_delayed_over_immediate);
-
- // No enabled queue could be selected, check if we could have chosen a
- // disabled (blocked) work queue instead.
- void TrySelectingBlockedQueue();
-
- // Check if we could have chosen a disabled (blocked) work queue instead.
- // |chosen_enabled_queue| is the enabled queue that got chosen.
- void TrySelectingBlockedQueueOverEnabledQueue(
- const WorkQueue& chosen_enabled_queue);
-
- // Number of high priority tasks which can be run before a normal priority
- // task should be selected to prevent starvation.
- // TODO(rmcilroy): Check if this is a good value.
- static const size_t kMaxHighPriorityStarvationTasks = 5;
-
- // Maximum number of delayed tasks tasks which can be run while there's a
- // waiting non-delayed task.
- static const size_t kMaxDelayedStarvationTasks = 3;
-
- private:
- base::ThreadChecker main_thread_checker_;
-
- PrioritizingSelector enabled_selector_;
- PrioritizingSelector blocked_selector_;
- size_t immediate_starvation_count_;
- size_t high_priority_starvation_count_;
- size_t num_blocked_queues_to_report_;
-
- Observer* task_queue_selector_observer_; // NOT OWNED
- DISALLOW_COPY_AND_ASSIGN(TaskQueueSelector);
-};
-
-} // namespace internal
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_BASE_TASK_QUEUE_SELECTOR_H
diff --git a/chromium/components/scheduler/base/task_queue_selector_unittest.cc b/chromium/components/scheduler/base/task_queue_selector_unittest.cc
deleted file mode 100644
index 1be477d75f7..00000000000
--- a/chromium/components/scheduler/base/task_queue_selector_unittest.cc
+++ /dev/null
@@ -1,494 +0,0 @@
-// Copyright 2015 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/scheduler/base/task_queue_selector.h"
-
-#include <stddef.h>
-
-#include <memory>
-
-#include "base/bind.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/pending_task.h"
-#include "components/scheduler/base/task_queue_impl.h"
-#include "components/scheduler/base/virtual_time_domain.h"
-#include "components/scheduler/base/work_queue.h"
-#include "components/scheduler/base/work_queue_sets.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using testing::_;
-
-namespace scheduler {
-namespace internal {
-
-class MockObserver : public TaskQueueSelector::Observer {
- public:
- MockObserver() {}
- virtual ~MockObserver() {}
-
- MOCK_METHOD1(OnTaskQueueEnabled, void(internal::TaskQueueImpl*));
- MOCK_METHOD1(OnTriedToSelectBlockedWorkQueue, void(internal::WorkQueue*));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockObserver);
-};
-
-class TaskQueueSelectorForTest : public TaskQueueSelector {
- public:
- using TaskQueueSelector::SetImmediateStarvationCountForTest;
- using TaskQueueSelector::PrioritizingSelector;
- using TaskQueueSelector::enabled_selector_for_test;
-};
-
-class TaskQueueSelectorTest : public testing::Test {
- public:
- TaskQueueSelectorTest()
- : test_closure_(base::Bind(&TaskQueueSelectorTest::TestFunction)) {}
- ~TaskQueueSelectorTest() override {}
-
- TaskQueueSelectorForTest::PrioritizingSelector* enabled_selector() {
- return selector_.enabled_selector_for_test();
- }
-
- WorkQueueSets* delayed_work_queue_sets() {
- return enabled_selector()->delayed_work_queue_sets();
- }
- WorkQueueSets* immediate_work_queue_sets() {
- return enabled_selector()->immediate_work_queue_sets();
- }
-
- void PushTasks(const size_t queue_indices[], size_t num_tasks) {
- std::set<size_t> changed_queue_set;
- for (size_t i = 0; i < num_tasks; i++) {
- changed_queue_set.insert(queue_indices[i]);
- task_queues_[queue_indices[i]]->immediate_work_queue()->Push(
- TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(), 0,
- true, i));
- }
- }
-
- void PushTasksWithEnqueueOrder(const size_t queue_indices[],
- const size_t enqueue_orders[],
- size_t num_tasks) {
- std::set<size_t> changed_queue_set;
- for (size_t i = 0; i < num_tasks; i++) {
- changed_queue_set.insert(queue_indices[i]);
- task_queues_[queue_indices[i]]->immediate_work_queue()->Push(
- TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(), 0,
- true, enqueue_orders[i]));
- }
- }
-
- std::vector<size_t> PopTasks() {
- std::vector<size_t> order;
- WorkQueue* chosen_work_queue;
- while (selector_.SelectWorkQueueToService(&chosen_work_queue)) {
- size_t chosen_queue_index =
- queue_to_index_map_.find(chosen_work_queue->task_queue())->second;
- order.push_back(chosen_queue_index);
- chosen_work_queue->PopTaskForTest();
- immediate_work_queue_sets()->OnPopQueue(chosen_work_queue);
- }
- return order;
- }
-
- static void TestFunction() {}
-
- void EnableQueue(TaskQueueImpl* queue) {
- queue->SetQueueEnabled(true);
- selector_.EnableQueue(queue);
- }
-
- void DisableQueue(TaskQueueImpl* queue) {
- queue->SetQueueEnabled(false);
- selector_.DisableQueue(queue);
- }
-
- protected:
- void SetUp() final {
- virtual_time_domain_ = base::WrapUnique<VirtualTimeDomain>(
- new VirtualTimeDomain(nullptr, base::TimeTicks()));
- for (size_t i = 0; i < kTaskQueueCount; i++) {
- scoped_refptr<TaskQueueImpl> task_queue = make_scoped_refptr(
- new TaskQueueImpl(nullptr, virtual_time_domain_.get(),
- TaskQueue::Spec("test queue"), "test", "test"));
- selector_.AddQueue(task_queue.get());
- task_queues_.push_back(task_queue);
- }
- for (size_t i = 0; i < kTaskQueueCount; i++) {
- EXPECT_EQ(TaskQueue::NORMAL_PRIORITY, task_queues_[i]->GetQueuePriority())
- << i;
- queue_to_index_map_.insert(std::make_pair(task_queues_[i].get(), i));
- }
- }
-
- void TearDown() final {
- for (scoped_refptr<TaskQueueImpl>& task_queue : task_queues_) {
- task_queue->UnregisterTaskQueue();
- // Note since this test doesn't have a TaskQueueManager we need to
- // manually remove |task_queue| from the |selector_|. Normally
- // UnregisterTaskQueue would do that.
- selector_.RemoveQueue(task_queue.get());
- }
- }
-
- scoped_refptr<TaskQueueImpl> NewTaskQueueWithBlockReporting() {
- return make_scoped_refptr(new TaskQueueImpl(
- nullptr, virtual_time_domain_.get(),
- TaskQueue::Spec("test queue").SetShouldReportWhenExecutionBlocked(true),
- "test", "test"));
- }
-
- const size_t kTaskQueueCount = 5;
- base::Closure test_closure_;
- TaskQueueSelectorForTest selector_;
- std::unique_ptr<VirtualTimeDomain> virtual_time_domain_;
- std::vector<scoped_refptr<TaskQueueImpl>> task_queues_;
- std::map<TaskQueueImpl*, size_t> queue_to_index_map_;
-};
-
-TEST_F(TaskQueueSelectorTest, TestDefaultPriority) {
- size_t queue_order[] = {4, 3, 2, 1, 0};
- PushTasks(queue_order, 5);
- EXPECT_THAT(PopTasks(), testing::ElementsAre(4, 3, 2, 1, 0));
-}
-
-TEST_F(TaskQueueSelectorTest, TestHighPriority) {
- size_t queue_order[] = {0, 1, 2, 3, 4};
- PushTasks(queue_order, 5);
- selector_.SetQueuePriority(task_queues_[2].get(), TaskQueue::HIGH_PRIORITY);
- EXPECT_THAT(PopTasks(), testing::ElementsAre(2, 0, 1, 3, 4));
-}
-
-TEST_F(TaskQueueSelectorTest, TestBestEffortPriority) {
- size_t queue_order[] = {0, 1, 2, 3, 4};
- PushTasks(queue_order, 5);
- selector_.SetQueuePriority(task_queues_[0].get(),
- TaskQueue::BEST_EFFORT_PRIORITY);
- selector_.SetQueuePriority(task_queues_[2].get(), TaskQueue::HIGH_PRIORITY);
- EXPECT_THAT(PopTasks(), testing::ElementsAre(2, 1, 3, 4, 0));
-}
-
-TEST_F(TaskQueueSelectorTest, TestControlPriority) {
- size_t queue_order[] = {0, 1, 2, 3, 4};
- PushTasks(queue_order, 5);
- selector_.SetQueuePriority(task_queues_[4].get(),
- TaskQueue::CONTROL_PRIORITY);
- EXPECT_EQ(TaskQueue::CONTROL_PRIORITY, task_queues_[4]->GetQueuePriority());
- selector_.SetQueuePriority(task_queues_[2].get(), TaskQueue::HIGH_PRIORITY);
- EXPECT_EQ(TaskQueue::HIGH_PRIORITY, task_queues_[2]->GetQueuePriority());
- EXPECT_THAT(PopTasks(), testing::ElementsAre(4, 2, 0, 1, 3));
-}
-
-TEST_F(TaskQueueSelectorTest, TestObserverWithEnabledQueue) {
- DisableQueue(task_queues_[1].get());
- MockObserver mock_observer;
- selector_.SetTaskQueueSelectorObserver(&mock_observer);
- EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(1);
- EnableQueue(task_queues_[1].get());
-}
-
-TEST_F(TaskQueueSelectorTest,
- TestObserverWithSetQueuePriorityAndQueueAlreadyEnabled) {
- selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::HIGH_PRIORITY);
- MockObserver mock_observer;
- selector_.SetTaskQueueSelectorObserver(&mock_observer);
- EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(0);
- selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::NORMAL_PRIORITY);
-}
-
-TEST_F(TaskQueueSelectorTest, TestDisableEnable) {
- MockObserver mock_observer;
- selector_.SetTaskQueueSelectorObserver(&mock_observer);
-
- size_t queue_order[] = {0, 1, 2, 3, 4};
- PushTasks(queue_order, 5);
- DisableQueue(task_queues_[2].get());
- DisableQueue(task_queues_[4].get());
- // Disabling a queue should not affect its priority.
- EXPECT_EQ(TaskQueue::NORMAL_PRIORITY, task_queues_[2]->GetQueuePriority());
- EXPECT_EQ(TaskQueue::NORMAL_PRIORITY, task_queues_[4]->GetQueuePriority());
- EXPECT_THAT(PopTasks(), testing::ElementsAre(0, 1, 3));
-
- EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(2);
- EnableQueue(task_queues_[2].get());
- selector_.SetQueuePriority(task_queues_[2].get(),
- TaskQueue::BEST_EFFORT_PRIORITY);
- EXPECT_THAT(PopTasks(), testing::ElementsAre(2));
- EnableQueue(task_queues_[4].get());
- EXPECT_THAT(PopTasks(), testing::ElementsAre(4));
-}
-
-TEST_F(TaskQueueSelectorTest, TestDisableChangePriorityThenEnable) {
- EXPECT_TRUE(task_queues_[2]->delayed_work_queue()->Empty());
- EXPECT_TRUE(task_queues_[2]->immediate_work_queue()->Empty());
-
- DisableQueue(task_queues_[2].get());
- selector_.SetQueuePriority(task_queues_[2].get(), TaskQueue::HIGH_PRIORITY);
-
- size_t queue_order[] = {0, 1, 2, 3, 4};
- PushTasks(queue_order, 5);
-
- EXPECT_TRUE(task_queues_[2]->delayed_work_queue()->Empty());
- EXPECT_FALSE(task_queues_[2]->immediate_work_queue()->Empty());
- EnableQueue(task_queues_[2].get());
-
- EXPECT_EQ(TaskQueue::HIGH_PRIORITY, task_queues_[2]->GetQueuePriority());
- EXPECT_THAT(PopTasks(), testing::ElementsAre(2, 0, 1, 3, 4));
-}
-
-TEST_F(TaskQueueSelectorTest, TestEmptyQueues) {
- WorkQueue* chosen_work_queue = nullptr;
- EXPECT_FALSE(selector_.SelectWorkQueueToService(&chosen_work_queue));
-
- // Test only disabled queues.
- size_t queue_order[] = {0};
- PushTasks(queue_order, 1);
- task_queues_[0]->SetQueueEnabled(false);
- selector_.DisableQueue(task_queues_[0].get());
- EXPECT_FALSE(selector_.SelectWorkQueueToService(&chosen_work_queue));
-}
-
-TEST_F(TaskQueueSelectorTest, TestAge) {
- size_t enqueue_order[] = {10, 1, 2, 9, 4};
- size_t queue_order[] = {0, 1, 2, 3, 4};
- PushTasksWithEnqueueOrder(queue_order, enqueue_order, 5);
- EXPECT_THAT(PopTasks(), testing::ElementsAre(1, 2, 4, 3, 0));
-}
-
-TEST_F(TaskQueueSelectorTest, TestControlStarvesOthers) {
- size_t queue_order[] = {0, 1, 2, 3};
- PushTasks(queue_order, 4);
- selector_.SetQueuePriority(task_queues_[3].get(),
- TaskQueue::CONTROL_PRIORITY);
- selector_.SetQueuePriority(task_queues_[2].get(), TaskQueue::HIGH_PRIORITY);
- selector_.SetQueuePriority(task_queues_[1].get(),
- TaskQueue::BEST_EFFORT_PRIORITY);
- for (int i = 0; i < 100; i++) {
- WorkQueue* chosen_work_queue = nullptr;
- EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue));
- EXPECT_EQ(task_queues_[3].get(), chosen_work_queue->task_queue());
- // Don't remove task from queue to simulate all queues still being full.
- }
-}
-
-TEST_F(TaskQueueSelectorTest, TestHighPriorityDoesNotStarveNormal) {
- size_t queue_order[] = {0, 1, 2};
- PushTasks(queue_order, 3);
- selector_.SetQueuePriority(task_queues_[2].get(), TaskQueue::HIGH_PRIORITY);
- selector_.SetQueuePriority(task_queues_[1].get(),
- TaskQueue::BEST_EFFORT_PRIORITY);
- size_t counts[] = {0, 0, 0};
- for (int i = 0; i < 100; i++) {
- WorkQueue* chosen_work_queue = nullptr;
- EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue));
- size_t chosen_queue_index =
- queue_to_index_map_.find(chosen_work_queue->task_queue())->second;
- counts[chosen_queue_index]++;
- // Don't remove task from queue to simulate all queues still being full.
- }
- EXPECT_GT(counts[0], 0ul); // Check high doesn't starve normal.
- EXPECT_GT(counts[2], counts[0]); // Check high gets more chance to run.
- EXPECT_EQ(0ul, counts[1]); // Check best effort is starved.
-}
-
-TEST_F(TaskQueueSelectorTest, TestBestEffortGetsStarved) {
- size_t queue_order[] = {0, 1};
- PushTasks(queue_order, 2);
- selector_.SetQueuePriority(task_queues_[0].get(),
- TaskQueue::BEST_EFFORT_PRIORITY);
- EXPECT_EQ(TaskQueue::NORMAL_PRIORITY, task_queues_[1]->GetQueuePriority());
- WorkQueue* chosen_work_queue = nullptr;
- for (int i = 0; i < 100; i++) {
- EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue));
- EXPECT_EQ(task_queues_[1].get(), chosen_work_queue->task_queue());
- // Don't remove task from queue to simulate all queues still being full.
- }
- selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::HIGH_PRIORITY);
- for (int i = 0; i < 100; i++) {
- EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue));
- EXPECT_EQ(task_queues_[1].get(), chosen_work_queue->task_queue());
- // Don't remove task from queue to simulate all queues still being full.
- }
- selector_.SetQueuePriority(task_queues_[1].get(),
- TaskQueue::CONTROL_PRIORITY);
- for (int i = 0; i < 100; i++) {
- EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue));
- EXPECT_EQ(task_queues_[1].get(), chosen_work_queue->task_queue());
- // Don't remove task from queue to simulate all queues still being full.
- }
-}
-
-TEST_F(TaskQueueSelectorTest, EnabledWorkQueuesEmpty) {
- EXPECT_TRUE(selector_.EnabledWorkQueuesEmpty());
- size_t queue_order[] = {0, 1};
- PushTasks(queue_order, 2);
-
- EXPECT_FALSE(selector_.EnabledWorkQueuesEmpty());
- PopTasks();
- EXPECT_TRUE(selector_.EnabledWorkQueuesEmpty());
-}
-
-TEST_F(TaskQueueSelectorTest, EnabledWorkQueuesEmpty_ControlPriority) {
- size_t queue_order[] = {0};
- PushTasks(queue_order, 1);
-
- selector_.SetQueuePriority(task_queues_[0].get(),
- TaskQueue::CONTROL_PRIORITY);
-
- EXPECT_FALSE(selector_.EnabledWorkQueuesEmpty());
-}
-
-TEST_F(TaskQueueSelectorTest, ChooseOldestWithPriority_Empty) {
- WorkQueue* chosen_work_queue = nullptr;
- bool chose_delayed_over_immediate = false;
- EXPECT_FALSE(enabled_selector()->ChooseOldestWithPriority(
- TaskQueue::NORMAL_PRIORITY, &chose_delayed_over_immediate,
- &chosen_work_queue));
- EXPECT_FALSE(chose_delayed_over_immediate);
-}
-
-TEST_F(TaskQueueSelectorTest, ChooseOldestWithPriority_OnlyDelayed) {
- task_queues_[0]->delayed_work_queue()->Push(TaskQueueImpl::Task(
- FROM_HERE, test_closure_, base::TimeTicks(), 0, true, 0));
-
- WorkQueue* chosen_work_queue = nullptr;
- bool chose_delayed_over_immediate = false;
- EXPECT_TRUE(enabled_selector()->ChooseOldestWithPriority(
- TaskQueue::NORMAL_PRIORITY, &chose_delayed_over_immediate,
- &chosen_work_queue));
- EXPECT_EQ(chosen_work_queue, task_queues_[0]->delayed_work_queue());
- EXPECT_FALSE(chose_delayed_over_immediate);
-}
-
-TEST_F(TaskQueueSelectorTest, ChooseOldestWithPriority_OnlyImmediate) {
- task_queues_[0]->immediate_work_queue()->Push(TaskQueueImpl::Task(
- FROM_HERE, test_closure_, base::TimeTicks(), 0, true, 0));
-
- WorkQueue* chosen_work_queue = nullptr;
- bool chose_delayed_over_immediate = false;
- EXPECT_TRUE(enabled_selector()->ChooseOldestWithPriority(
- TaskQueue::NORMAL_PRIORITY, &chose_delayed_over_immediate,
- &chosen_work_queue));
- EXPECT_EQ(chosen_work_queue, task_queues_[0]->immediate_work_queue());
- EXPECT_FALSE(chose_delayed_over_immediate);
-}
-
-TEST_F(TaskQueueSelectorTest, TestObserverWithOneBlockedQueue) {
- TaskQueueSelectorForTest selector;
- MockObserver mock_observer;
- selector.SetTaskQueueSelectorObserver(&mock_observer);
-
- scoped_refptr<TaskQueueImpl> task_queue(NewTaskQueueWithBlockReporting());
- selector.AddQueue(task_queue.get());
- task_queue->SetQueueEnabled(false);
- selector.DisableQueue(task_queue.get());
-
- task_queue->immediate_work_queue()->PushAndSetEnqueueOrder(
- TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(), 0, true),
- 0);
-
- WorkQueue* chosen_work_queue;
- EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1);
- EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue));
-
- task_queue->UnregisterTaskQueue();
- selector.RemoveQueue(task_queue.get());
-}
-
-TEST_F(TaskQueueSelectorTest, TestObserverWithTwoBlockedQueues) {
- TaskQueueSelectorForTest selector;
- MockObserver mock_observer;
- selector.SetTaskQueueSelectorObserver(&mock_observer);
-
- scoped_refptr<TaskQueueImpl> task_queue(NewTaskQueueWithBlockReporting());
- scoped_refptr<TaskQueueImpl> task_queue2(NewTaskQueueWithBlockReporting());
- selector.AddQueue(task_queue.get());
- selector.AddQueue(task_queue2.get());
- task_queue->SetQueueEnabled(false);
- task_queue2->SetQueueEnabled(false);
- selector.DisableQueue(task_queue.get());
- selector.DisableQueue(task_queue2.get());
- selector.SetQueuePriority(task_queue2.get(), TaskQueue::CONTROL_PRIORITY);
-
- task_queue->immediate_work_queue()->PushAndSetEnqueueOrder(
- TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(), 0, true),
- 0);
- task_queue2->immediate_work_queue()->PushAndSetEnqueueOrder(
- TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(), 0, true),
- 0);
-
- // Should still only see one call to OnTriedToSelectBlockedWorkQueue.
- WorkQueue* chosen_work_queue;
- EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1);
- EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue));
- testing::Mock::VerifyAndClearExpectations(&mock_observer);
-
- // Removing the second queue and selecting again should result in another
- // notification.
- task_queue->UnregisterTaskQueue();
- selector.RemoveQueue(task_queue.get());
- EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1);
- EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue));
-
- task_queue2->UnregisterTaskQueue();
- selector.RemoveQueue(task_queue2.get());
-}
-
-struct ChooseOldestWithPriorityTestParam {
- int delayed_task_enqueue_order;
- int immediate_task_enqueue_order;
- int immediate_starvation_count;
- const char* expected_work_queue_name;
- bool expected_did_starve_immediate_queue;
-};
-
-static const ChooseOldestWithPriorityTestParam
- kChooseOldestWithPriorityTestCases[] = {
- {1, 2, 0, "delayed", true},
- {1, 2, 1, "delayed", true},
- {1, 2, 2, "delayed", true},
- {1, 2, 3, "immediate", false},
- {1, 2, 4, "immediate", false},
- {2, 1, 4, "immediate", false},
- {2, 1, 4, "immediate", false},
-};
-
-class ChooseOldestWithPriorityTest
- : public TaskQueueSelectorTest,
- public testing::WithParamInterface<ChooseOldestWithPriorityTestParam> {};
-
-TEST_P(ChooseOldestWithPriorityTest, RoundRobinTest) {
- task_queues_[0]->immediate_work_queue()->Push(
- TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(),
- GetParam().immediate_task_enqueue_order, true,
- GetParam().immediate_task_enqueue_order));
-
- task_queues_[0]->delayed_work_queue()->Push(
- TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(),
- GetParam().delayed_task_enqueue_order, true,
- GetParam().delayed_task_enqueue_order));
-
- selector_.SetImmediateStarvationCountForTest(
- GetParam().immediate_starvation_count);
-
- WorkQueue* chosen_work_queue = nullptr;
- bool chose_delayed_over_immediate = false;
- EXPECT_TRUE(enabled_selector()->ChooseOldestWithPriority(
- TaskQueue::NORMAL_PRIORITY, &chose_delayed_over_immediate,
- &chosen_work_queue));
- EXPECT_EQ(chosen_work_queue->task_queue(), task_queues_[0].get());
- EXPECT_STREQ(chosen_work_queue->name(), GetParam().expected_work_queue_name);
- EXPECT_EQ(chose_delayed_over_immediate,
- GetParam().expected_did_starve_immediate_queue);
-}
-
-INSTANTIATE_TEST_CASE_P(ChooseOldestWithPriorityTest,
- ChooseOldestWithPriorityTest,
- testing::ValuesIn(kChooseOldestWithPriorityTestCases));
-
-} // namespace internal
-} // namespace scheduler
diff --git a/chromium/components/scheduler/base/test_always_fail_time_source.cc b/chromium/components/scheduler/base/test_always_fail_time_source.cc
deleted file mode 100644
index 254298453f9..00000000000
--- a/chromium/components/scheduler/base/test_always_fail_time_source.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2015 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/scheduler/base/test_always_fail_time_source.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace scheduler {
-
-TestAlwaysFailTimeSource::TestAlwaysFailTimeSource() {
-}
-
-TestAlwaysFailTimeSource::~TestAlwaysFailTimeSource() {
-}
-
-base::TimeTicks TestAlwaysFailTimeSource::NowTicks() {
- ADD_FAILURE() << "NowTicks() was called!";
- return base::TimeTicks();
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/base/test_always_fail_time_source.h b/chromium/components/scheduler/base/test_always_fail_time_source.h
deleted file mode 100644
index ec6e73ddf81..00000000000
--- a/chromium/components/scheduler/base/test_always_fail_time_source.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2015 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_SCHEDULER_BASE_TEST_ALWAYS_FAIL_TIME_SOURCE_H_
-#define COMPONENTS_SCHEDULER_BASE_TEST_ALWAYS_FAIL_TIME_SOURCE_H_
-
-#include "base/macros.h"
-#include "base/time/tick_clock.h"
-
-namespace scheduler {
-
-class TestAlwaysFailTimeSource : public base::TickClock {
- public:
- explicit TestAlwaysFailTimeSource();
- ~TestAlwaysFailTimeSource() override;
-
- base::TimeTicks NowTicks() override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TestAlwaysFailTimeSource);
-};
-
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_BASE_TEST_ALWAYS_FAIL_TIME_SOURCE_H_
diff --git a/chromium/components/scheduler/base/test_time_source.cc b/chromium/components/scheduler/base/test_time_source.cc
deleted file mode 100644
index 6bbe83ba2a9..00000000000
--- a/chromium/components/scheduler/base/test_time_source.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2015 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/scheduler/base/test_time_source.h"
-
-namespace scheduler {
-
-TestTimeSource::TestTimeSource(base::SimpleTestTickClock* time_source)
- : time_source_(time_source) {
- DCHECK(time_source_);
-}
-
-TestTimeSource::~TestTimeSource() {}
-
-base::TimeTicks TestTimeSource::NowTicks() {
- return time_source_->NowTicks();
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/base/test_time_source.h b/chromium/components/scheduler/base/test_time_source.h
deleted file mode 100644
index 9ff57f0202e..00000000000
--- a/chromium/components/scheduler/base/test_time_source.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2015 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_SCHEDULER_BASE_TEST_TIME_SOURCE_H_
-#define COMPONENTS_SCHEDULER_BASE_TEST_TIME_SOURCE_H_
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "base/time/tick_clock.h"
-
-namespace scheduler {
-
-class TestTimeSource : public base::TickClock {
- public:
- explicit TestTimeSource(base::SimpleTestTickClock* time_source);
- ~TestTimeSource() override;
-
- base::TimeTicks NowTicks() override;
-
- private:
- // Not owned.
- base::SimpleTestTickClock* time_source_;
-
- DISALLOW_COPY_AND_ASSIGN(TestTimeSource);
-};
-
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_BASE_TEST_TIME_SOURCE_H_
diff --git a/chromium/components/scheduler/base/time_domain.cc b/chromium/components/scheduler/base/time_domain.cc
deleted file mode 100644
index 61851c533ea..00000000000
--- a/chromium/components/scheduler/base/time_domain.cc
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright 2015 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/scheduler/base/time_domain.h"
-
-#include <set>
-
-#include "components/scheduler/base/task_queue_impl.h"
-#include "components/scheduler/base/task_queue_manager_delegate.h"
-#include "components/scheduler/base/work_queue.h"
-#include "components/scheduler/scheduler_export.h"
-
-namespace scheduler {
-
-TimeDomain::TimeDomain(Observer* observer) : observer_(observer) {}
-
-TimeDomain::~TimeDomain() {
- DCHECK(main_thread_checker_.CalledOnValidThread());
-}
-
-void TimeDomain::RegisterQueue(internal::TaskQueueImpl* queue) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- DCHECK_EQ(queue->GetTimeDomain(), this);
-}
-
-void TimeDomain::UnregisterQueue(internal::TaskQueueImpl* queue) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- DCHECK_EQ(queue->GetTimeDomain(), this);
- UnregisterAsUpdatableTaskQueue(queue);
-
- // We need to remove |task_queue| from delayed_wakeup_multimap_ which is a
- // little awkward since it's keyed by time. O(n) running time.
- for (DelayedWakeupMultimap::iterator iter = delayed_wakeup_multimap_.begin();
- iter != delayed_wakeup_multimap_.end();) {
- if (iter->second == queue) {
- // O(1) amortized.
- iter = delayed_wakeup_multimap_.erase(iter);
- } else {
- iter++;
- }
- }
-}
-
-void TimeDomain::MigrateQueue(internal::TaskQueueImpl* queue,
- TimeDomain* destination_time_domain) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- DCHECK_EQ(queue->GetTimeDomain(), this);
- DCHECK(destination_time_domain);
- UnregisterAsUpdatableTaskQueue(queue);
-
- base::TimeTicks destination_now = destination_time_domain->Now();
- // We need to remove |task_queue| from delayed_wakeup_multimap_ which is a
- // little awkward since it's keyed by time. O(n) running time.
- for (DelayedWakeupMultimap::iterator iter = delayed_wakeup_multimap_.begin();
- iter != delayed_wakeup_multimap_.end();) {
- if (iter->second == queue) {
- destination_time_domain->ScheduleDelayedWork(queue, iter->first,
- destination_now);
- // O(1) amortized.
- iter = delayed_wakeup_multimap_.erase(iter);
- } else {
- iter++;
- }
- }
-}
-
-void TimeDomain::ScheduleDelayedWork(internal::TaskQueueImpl* queue,
- base::TimeTicks delayed_run_time,
- base::TimeTicks now) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- if (delayed_wakeup_multimap_.empty() ||
- delayed_run_time < delayed_wakeup_multimap_.begin()->first) {
- base::TimeDelta delay = std::max(base::TimeDelta(), delayed_run_time - now);
- RequestWakeup(now, delay);
- }
-
- delayed_wakeup_multimap_.insert(std::make_pair(delayed_run_time, queue));
- if (observer_)
- observer_->OnTimeDomainHasDelayedWork();
-}
-
-void TimeDomain::RegisterAsUpdatableTaskQueue(internal::TaskQueueImpl* queue) {
- {
- base::AutoLock lock(newly_updatable_lock_);
- newly_updatable_.push_back(queue);
- }
- if (observer_)
- observer_->OnTimeDomainHasImmediateWork();
-}
-
-void TimeDomain::UnregisterAsUpdatableTaskQueue(
- internal::TaskQueueImpl* queue) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
-
- updatable_queue_set_.erase(queue);
-
- base::AutoLock lock(newly_updatable_lock_);
- // Remove all copies of |queue| from |newly_updatable_|.
- for (size_t i = 0; i < newly_updatable_.size();) {
- if (newly_updatable_[i] == queue) {
- // Move last element into slot #i and then compact.
- newly_updatable_[i] = newly_updatable_.back();
- newly_updatable_.pop_back();
- } else {
- i++;
- }
- }
-}
-
-void TimeDomain::UpdateWorkQueues(
- bool should_trigger_wakeup,
- const internal::TaskQueueImpl::Task* previous_task) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- LazyNow lazy_now(CreateLazyNow());
-
- // Move any ready delayed tasks into the Incoming queues.
- WakeupReadyDelayedQueues(&lazy_now, should_trigger_wakeup, previous_task);
-
- MoveNewlyUpdatableQueuesIntoUpdatableQueueSet();
-
- auto iter = updatable_queue_set_.begin();
- while (iter != updatable_queue_set_.end()) {
- internal::TaskQueueImpl* queue = *iter++;
- // NOTE Update work queue may erase itself from |updatable_queue_set_|.
- // This is fine, erasing an element won't invalidate any interator, as long
- // as the iterator isn't the element being delated.
- if (queue->immediate_work_queue()->Empty())
- queue->UpdateImmediateWorkQueue(should_trigger_wakeup, previous_task);
- }
-}
-
-void TimeDomain::MoveNewlyUpdatableQueuesIntoUpdatableQueueSet() {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- base::AutoLock lock(newly_updatable_lock_);
- while (!newly_updatable_.empty()) {
- updatable_queue_set_.insert(newly_updatable_.back());
- newly_updatable_.pop_back();
- }
-}
-
-void TimeDomain::WakeupReadyDelayedQueues(
- LazyNow* lazy_now,
- bool should_trigger_wakeup,
- const internal::TaskQueueImpl::Task* previous_task) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- // Wake up any queues with pending delayed work. Note std::multipmap stores
- // the elements sorted by key, so the begin() iterator points to the earliest
- // queue to wakeup.
- std::set<internal::TaskQueueImpl*> dedup_set;
- while (!delayed_wakeup_multimap_.empty()) {
- DelayedWakeupMultimap::iterator next_wakeup =
- delayed_wakeup_multimap_.begin();
- if (next_wakeup->first > lazy_now->Now())
- break;
- // A queue could have any number of delayed tasks pending so it's worthwhile
- // deduping calls to UpdateDelayedWorkQueue since it takes a lock.
- // NOTE the order in which these are called matters since the order
- // in which EnqueueTaskLocks is called is respected when choosing which
- // queue to execute a task from.
- if (dedup_set.insert(next_wakeup->second).second) {
- next_wakeup->second->UpdateDelayedWorkQueue(
- lazy_now, should_trigger_wakeup, previous_task);
- }
- delayed_wakeup_multimap_.erase(next_wakeup);
- }
-}
-
-void TimeDomain::ClearExpiredWakeups() {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- LazyNow lazy_now(CreateLazyNow());
- while (!delayed_wakeup_multimap_.empty()) {
- DelayedWakeupMultimap::iterator next_wakeup =
- delayed_wakeup_multimap_.begin();
- if (next_wakeup->first > lazy_now.Now())
- break;
- delayed_wakeup_multimap_.erase(next_wakeup);
- }
-}
-
-bool TimeDomain::NextScheduledRunTime(base::TimeTicks* out_time) const {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- if (delayed_wakeup_multimap_.empty())
- return false;
-
- *out_time = delayed_wakeup_multimap_.begin()->first;
- return true;
-}
-
-bool TimeDomain::NextScheduledTaskQueue(TaskQueue** out_task_queue) const {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- if (delayed_wakeup_multimap_.empty())
- return false;
-
- *out_task_queue = delayed_wakeup_multimap_.begin()->second;
- return true;
-}
-
-void TimeDomain::AsValueInto(base::trace_event::TracedValue* state) const {
- state->BeginDictionary();
- state->SetString("name", GetName());
- state->BeginArray("updatable_queue_set");
- for (auto& queue : updatable_queue_set_)
- state->AppendString(queue->GetName());
- state->EndArray();
- state->SetInteger("registered_delay_count", delayed_wakeup_multimap_.size());
- if (!delayed_wakeup_multimap_.empty()) {
- base::TimeDelta delay = delayed_wakeup_multimap_.begin()->first - Now();
- state->SetDouble("next_delay_ms", delay.InMillisecondsF());
- }
- AsValueIntoInternal(state);
- state->EndDictionary();
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/base/time_domain.h b/chromium/components/scheduler/base/time_domain.h
deleted file mode 100644
index 0f33d811bad..00000000000
--- a/chromium/components/scheduler/base/time_domain.h
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2015 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_SCHEDULER_BASE_TIME_DOMAIN_H_
-#define COMPONENTS_SCHEDULER_BASE_TIME_DOMAIN_H_
-
-#include <map>
-
-#include "base/callback.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/time/time.h"
-#include "components/scheduler/base/lazy_now.h"
-#include "components/scheduler/base/task_queue_impl.h"
-#include "components/scheduler/scheduler_export.h"
-
-namespace scheduler {
-namespace internal {
-class TaskQueueImpl;
-} // internal
-class TaskQueueManager;
-class TaskQueueManagerDelegate;
-
-class SCHEDULER_EXPORT TimeDomain {
- public:
- class SCHEDULER_EXPORT Observer {
- public:
- virtual ~Observer() {}
-
- // Called when an empty TaskQueue registered with this TimeDomain has a task
- // enqueued.
- virtual void OnTimeDomainHasImmediateWork() = 0;
-
- // Called when a TaskQueue registered with this TimeDomain has a delayed
- // task enqueued.
- virtual void OnTimeDomainHasDelayedWork() = 0;
- };
-
- explicit TimeDomain(Observer* observer);
- virtual ~TimeDomain();
-
- // Returns a LazyNow that evaluate this TimeDomain's Now. Can be called from
- // any thread.
- // TODO(alexclarke): Make this main thread only.
- virtual LazyNow CreateLazyNow() const = 0;
-
- // Evaluate this TimeDomain's Now. Can be called from any thread.
- virtual base::TimeTicks Now() const = 0;
-
- // Some TimeDomains support virtual time, this method tells us to advance time
- // if possible and return true if time was advanced.
- virtual bool MaybeAdvanceTime() = 0;
-
- // Returns the name of this time domain for tracing.
- virtual const char* GetName() const = 0;
-
- // If there is a scheduled delayed task, |out_time| is set to the scheduled
- // runtime for the next one and it returns true. Returns false otherwise.
- bool NextScheduledRunTime(base::TimeTicks* out_time) const;
-
- protected:
- friend class internal::TaskQueueImpl;
- friend class TaskQueueManager;
-
- void AsValueInto(base::trace_event::TracedValue* state) const;
-
- // Migrates |queue| from this time domain to |destination_time_domain|.
- void MigrateQueue(internal::TaskQueueImpl* queue,
- TimeDomain* destination_time_domain);
-
- // If there is a scheduled delayed task, |out_task_queue| is set to the queue
- // the next task was posted to and it returns true. Returns false otherwise.
- bool NextScheduledTaskQueue(TaskQueue** out_task_queue) const;
-
- // Adds |queue| to the set of task queues that UpdateWorkQueues calls
- // UpdateWorkQueue on.
- void RegisterAsUpdatableTaskQueue(internal::TaskQueueImpl* queue);
-
- // Schedules a call to TaskQueueImpl::MoveReadyDelayedTasksToDelayedWorkQueue
- // when this TimeDomain reaches |delayed_run_time|.
- void ScheduleDelayedWork(internal::TaskQueueImpl* queue,
- base::TimeTicks delayed_run_time,
- base::TimeTicks now);
-
- // Registers the |queue|.
- void RegisterQueue(internal::TaskQueueImpl* queue);
-
- // Removes |queue| from the set of task queues that UpdateWorkQueues calls
- // UpdateWorkQueue on.
- void UnregisterAsUpdatableTaskQueue(internal::TaskQueueImpl* queue);
-
- // Removes |queue| from all internal data structures.
- void UnregisterQueue(internal::TaskQueueImpl* queue);
-
- // Updates active queues associated with this TimeDomain.
- void UpdateWorkQueues(bool should_trigger_wakeup,
- const internal::TaskQueueImpl::Task* previous_task);
-
- // Called by the TaskQueueManager when the TimeDomain is registered.
- virtual void OnRegisterWithTaskQueueManager(
- TaskQueueManager* task_queue_manager) = 0;
-
- // The implementaion will secedule task processing to run with |delay| with
- // respect to the TimeDomain's time source. Always called on the main thread.
- // NOTE this is only called by ScheduleDelayedWork if the scheduled runtime
- // is sooner than any previously sheduled work or if there is no other
- // scheduled work.
- virtual void RequestWakeup(base::TimeTicks now, base::TimeDelta delay) = 0;
-
- // For implementation specific tracing.
- virtual void AsValueIntoInternal(
- base::trace_event::TracedValue* state) const = 0;
-
- // Call TaskQueueImpl::UpdateDelayedWorkQueue for each queue where the delay
- // has elapsed.
- void WakeupReadyDelayedQueues(
- LazyNow* lazy_now,
- bool should_trigger_wakeup,
- const internal::TaskQueueImpl::Task* previous_task);
-
- protected:
- // Clears expired entries from |delayed_wakeup_multimap_|. Caution needs to be
- // taken to ensure TaskQueueImpl::UpdateDelayedWorkQueue or
- // TaskQueueImpl::Pump is called on the affected queues.
- void ClearExpiredWakeups();
-
- private:
- void MoveNewlyUpdatableQueuesIntoUpdatableQueueSet();
-
- typedef std::multimap<base::TimeTicks, internal::TaskQueueImpl*>
- DelayedWakeupMultimap;
-
- DelayedWakeupMultimap delayed_wakeup_multimap_;
-
- // This lock guards only |newly_updatable_|. It's not expected to be heavily
- // contended.
- base::Lock newly_updatable_lock_;
- std::vector<internal::TaskQueueImpl*> newly_updatable_;
-
- // Set of task queues with avaliable work on the incoming queue. This should
- // only be accessed from the main thread.
- std::set<internal::TaskQueueImpl*> updatable_queue_set_;
-
- Observer* observer_; // NOT OWNED.
-
- base::ThreadChecker main_thread_checker_;
-
- DISALLOW_COPY_AND_ASSIGN(TimeDomain);
-};
-
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_BASE_TIME_DOMAIN_H_
diff --git a/chromium/components/scheduler/base/time_domain_unittest.cc b/chromium/components/scheduler/base/time_domain_unittest.cc
deleted file mode 100644
index 39fc93997a1..00000000000
--- a/chromium/components/scheduler/base/time_domain_unittest.cc
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright 2015 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/scheduler/base/time_domain.h"
-
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "cc/test/ordered_simple_task_runner.h"
-#include "components/scheduler/base/task_queue_impl.h"
-#include "components/scheduler/base/task_queue_manager.h"
-#include "components/scheduler/base/task_queue_manager_delegate_for_test.h"
-#include "components/scheduler/base/test_time_source.h"
-#include "components/scheduler/base/work_queue.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-using testing::_;
-using testing::AnyNumber;
-using testing::Mock;
-
-namespace scheduler {
-
-class MockTimeDomain : public TimeDomain {
- public:
- explicit MockTimeDomain(TimeDomain::Observer* observer)
- : TimeDomain(observer),
- now_(base::TimeTicks() + base::TimeDelta::FromSeconds(1)) {}
-
- ~MockTimeDomain() override {}
-
- using TimeDomain::ClearExpiredWakeups;
- using TimeDomain::NextScheduledRunTime;
- using TimeDomain::NextScheduledTaskQueue;
- using TimeDomain::ScheduleDelayedWork;
- using TimeDomain::UnregisterQueue;
- using TimeDomain::UpdateWorkQueues;
- using TimeDomain::RegisterAsUpdatableTaskQueue;
-
- // TimeSource implementation:
- LazyNow CreateLazyNow() const override { return LazyNow(now_); }
- base::TimeTicks Now() const override { return now_; }
-
- void AsValueIntoInternal(
- base::trace_event::TracedValue* state) const override {}
-
- bool MaybeAdvanceTime() override { return false; }
- const char* GetName() const override { return "Test"; }
- void OnRegisterWithTaskQueueManager(
- TaskQueueManager* task_queue_manager) override {}
-
- MOCK_METHOD2(RequestWakeup, void(base::TimeTicks now, base::TimeDelta delay));
-
- void SetNow(base::TimeTicks now) { now_ = now; }
-
-
- private:
- base::TimeTicks now_;
-
- DISALLOW_COPY_AND_ASSIGN(MockTimeDomain);
-};
-
-class TimeDomainTest : public testing::Test {
- public:
- void SetUp() final {
- time_domain_ = base::WrapUnique(CreateMockTimeDomain());
- task_queue_ = make_scoped_refptr(new internal::TaskQueueImpl(
- nullptr, time_domain_.get(), TaskQueue::Spec("test_queue"),
- "test.category", "test.category"));
- }
-
- void TearDown() final {
- if (task_queue_)
- task_queue_->UnregisterTaskQueue();
- }
-
- virtual MockTimeDomain* CreateMockTimeDomain() {
- return new MockTimeDomain(nullptr);
- }
-
- std::unique_ptr<MockTimeDomain> time_domain_;
- scoped_refptr<internal::TaskQueueImpl> task_queue_;
-};
-
-TEST_F(TimeDomainTest, ScheduleDelayedWork) {
- base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10);
- base::TimeTicks delayed_runtime = time_domain_->Now() + delay;
- EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay));
- base::TimeTicks now = time_domain_->Now();
- time_domain_->ScheduleDelayedWork(task_queue_.get(), now + delay, now);
-
- base::TimeTicks next_scheduled_runtime;
- EXPECT_TRUE(time_domain_->NextScheduledRunTime(&next_scheduled_runtime));
- EXPECT_EQ(delayed_runtime, next_scheduled_runtime);
-
- TaskQueue* next_task_queue;
- EXPECT_TRUE(time_domain_->NextScheduledTaskQueue(&next_task_queue));
- EXPECT_EQ(task_queue_.get(), next_task_queue);
-}
-
-TEST_F(TimeDomainTest, RequestWakeup_OnlyCalledForEarlierTasks) {
- base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10);
- base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(20);
- base::TimeDelta delay3 = base::TimeDelta::FromMilliseconds(30);
- base::TimeDelta delay4 = base::TimeDelta::FromMilliseconds(1);
-
- // RequestWakeup should always be called if there are no other wakeups.
- EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay1));
- base::TimeTicks now = time_domain_->Now();
- time_domain_->ScheduleDelayedWork(task_queue_.get(), now + delay1, now);
-
- Mock::VerifyAndClearExpectations(time_domain_.get());
-
- // RequestWakeup should not be called when scheduling later tasks.
- EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)).Times(0);
- time_domain_->ScheduleDelayedWork(task_queue_.get(), now + delay2, now);
- time_domain_->ScheduleDelayedWork(task_queue_.get(), now + delay3, now);
-
- // RequestWakeup should be called when scheduling earlier tasks.
- Mock::VerifyAndClearExpectations(time_domain_.get());
- EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay4));
- time_domain_->ScheduleDelayedWork(task_queue_.get(), now + delay4, now);
-}
-
-TEST_F(TimeDomainTest, UnregisterQueue) {
- scoped_refptr<internal::TaskQueueImpl> task_queue2_ =
- make_scoped_refptr(new internal::TaskQueueImpl(
- nullptr, time_domain_.get(), TaskQueue::Spec("test_queue2"),
- "test.category", "test.category"));
-
- EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)).Times(1);
- base::TimeTicks now = time_domain_->Now();
- time_domain_->ScheduleDelayedWork(
- task_queue_.get(), now + base::TimeDelta::FromMilliseconds(10), now);
- time_domain_->ScheduleDelayedWork(
- task_queue2_.get(), now + base::TimeDelta::FromMilliseconds(100), now);
-
- TaskQueue* next_task_queue;
- EXPECT_TRUE(time_domain_->NextScheduledTaskQueue(&next_task_queue));
- EXPECT_EQ(task_queue_.get(), next_task_queue);
-
- time_domain_->UnregisterQueue(task_queue_.get());
- task_queue_ = scoped_refptr<internal::TaskQueueImpl>();
- EXPECT_TRUE(time_domain_->NextScheduledTaskQueue(&next_task_queue));
- EXPECT_EQ(task_queue2_.get(), next_task_queue);
-
- time_domain_->UnregisterQueue(task_queue2_.get());
- EXPECT_FALSE(time_domain_->NextScheduledTaskQueue(&next_task_queue));
-}
-
-TEST_F(TimeDomainTest, UpdateWorkQueues) {
- base::TimeDelta delay = base::TimeDelta::FromMilliseconds(50);
- EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay));
- base::TimeTicks now = time_domain_->Now();
- base::TimeTicks delayed_runtime = now + delay;
- time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime, now);
-
- base::TimeTicks next_run_time;
- ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time));
- EXPECT_EQ(delayed_runtime, next_run_time);
-
- time_domain_->UpdateWorkQueues(false, nullptr);
- ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time));
- EXPECT_EQ(delayed_runtime, next_run_time);
-
- time_domain_->SetNow(delayed_runtime);
- time_domain_->UpdateWorkQueues(false, nullptr);
- ASSERT_FALSE(time_domain_->NextScheduledRunTime(&next_run_time));
-}
-
-TEST_F(TimeDomainTest, ClearExpiredWakeups) {
- base::TimeTicks now = time_domain_->Now();
- base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10);
- base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(20);
- base::TimeTicks run_time1 = now + delay1;
- base::TimeTicks run_time2 = now + delay2;
-
- EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)).Times(AnyNumber());
- time_domain_->ScheduleDelayedWork(task_queue_.get(), run_time1, now);
- time_domain_->ScheduleDelayedWork(task_queue_.get(), run_time2, now);
-
- base::TimeTicks next_run_time;
- ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time));
- EXPECT_EQ(run_time1, next_run_time);
-
- time_domain_->SetNow(run_time1);
- time_domain_->ClearExpiredWakeups();
-
- ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time));
- EXPECT_EQ(run_time2, next_run_time);
-
- time_domain_->SetNow(run_time2);
- time_domain_->ClearExpiredWakeups();
- ASSERT_FALSE(time_domain_->NextScheduledRunTime(&next_run_time));
-}
-
-namespace {
-class MockObserver : public TimeDomain::Observer {
- public:
- ~MockObserver() override {}
-
- MOCK_METHOD0(OnTimeDomainHasImmediateWork, void());
- MOCK_METHOD0(OnTimeDomainHasDelayedWork, void());
-};
-} // namespace
-
-class TimeDomainWithObserverTest : public TimeDomainTest {
- public:
- MockTimeDomain* CreateMockTimeDomain() override {
- observer_.reset(new MockObserver());
- return new MockTimeDomain(observer_.get());
- }
-
- std::unique_ptr<MockObserver> observer_;
-};
-
-TEST_F(TimeDomainWithObserverTest, OnTimeDomainHasImmediateWork) {
- EXPECT_CALL(*observer_, OnTimeDomainHasImmediateWork());
- time_domain_->RegisterAsUpdatableTaskQueue(task_queue_.get());
-}
-
-TEST_F(TimeDomainWithObserverTest, OnTimeDomainHasDelayedWork) {
- EXPECT_CALL(*observer_, OnTimeDomainHasDelayedWork());
- EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _));
- base::TimeTicks now = time_domain_->Now();
- time_domain_->ScheduleDelayedWork(
- task_queue_.get(), now + base::TimeDelta::FromMilliseconds(10), now);
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/base/virtual_time_domain.cc b/chromium/components/scheduler/base/virtual_time_domain.cc
deleted file mode 100644
index db9c4035b29..00000000000
--- a/chromium/components/scheduler/base/virtual_time_domain.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2015 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/scheduler/base/virtual_time_domain.h"
-
-#include "base/bind.h"
-#include "components/scheduler/base/task_queue_impl.h"
-#include "components/scheduler/base/task_queue_manager.h"
-#include "components/scheduler/base/task_queue_manager_delegate.h"
-
-namespace scheduler {
-
-VirtualTimeDomain::VirtualTimeDomain(TimeDomain::Observer* observer,
- base::TimeTicks initial_time)
- : TimeDomain(observer), now_(initial_time), task_queue_manager_(nullptr) {}
-
-VirtualTimeDomain::~VirtualTimeDomain() {}
-
-void VirtualTimeDomain::OnRegisterWithTaskQueueManager(
- TaskQueueManager* task_queue_manager) {
- task_queue_manager_ = task_queue_manager;
- DCHECK(task_queue_manager_);
-}
-
-LazyNow VirtualTimeDomain::CreateLazyNow() const {
- base::AutoLock lock(lock_);
- return LazyNow(now_);
-}
-
-base::TimeTicks VirtualTimeDomain::Now() const {
- base::AutoLock lock(lock_);
- return now_;
-}
-
-void VirtualTimeDomain::RequestWakeup(base::TimeTicks now,
- base::TimeDelta delay) {
- // We don't need to do anything here because the caller of AdvanceTo is
- // responsible for calling TaskQueueManager::MaybeScheduleImmediateWork if
- // needed.
-}
-
-bool VirtualTimeDomain::MaybeAdvanceTime() {
- return false;
-}
-
-void VirtualTimeDomain::AsValueIntoInternal(
- base::trace_event::TracedValue* state) const {}
-
-void VirtualTimeDomain::AdvanceTo(base::TimeTicks now) {
- base::AutoLock lock(lock_);
- DCHECK_GE(now, now_);
- now_ = now;
-}
-
-void VirtualTimeDomain::RequestDoWork() {
- task_queue_manager_->MaybeScheduleImmediateWork(FROM_HERE);
-}
-
-const char* VirtualTimeDomain::GetName() const {
- return "VirtualTimeDomain";
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/base/virtual_time_domain.h b/chromium/components/scheduler/base/virtual_time_domain.h
deleted file mode 100644
index e522533be66..00000000000
--- a/chromium/components/scheduler/base/virtual_time_domain.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2015 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_SCHEDULER_BASE_VIRTUAL_TIME_DOMAIN_H_
-#define COMPONENTS_SCHEDULER_BASE_VIRTUAL_TIME_DOMAIN_H_
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "components/scheduler/base/time_domain.h"
-#include "components/scheduler/scheduler_export.h"
-
-namespace scheduler {
-
-class SCHEDULER_EXPORT VirtualTimeDomain : public TimeDomain {
- public:
- VirtualTimeDomain(TimeDomain::Observer* observer,
- base::TimeTicks initial_time);
- ~VirtualTimeDomain() override;
-
- // TimeDomain implementation:
- LazyNow CreateLazyNow() const override;
- base::TimeTicks Now() const override;
- bool MaybeAdvanceTime() override;
- const char* GetName() const override;
-
- // Advances this time domain to |now|. NOTE |now| is supposed to be
- // monotonically increasing. NOTE it's the responsibility of the caller to
- // call TaskQueueManager::MaybeScheduleImmediateWork if needed.
- void AdvanceTo(base::TimeTicks now);
-
- using TimeDomain::ClearExpiredWakeups;
-
- protected:
- void OnRegisterWithTaskQueueManager(
- TaskQueueManager* task_queue_manager) override;
- void RequestWakeup(base::TimeTicks now, base::TimeDelta delay) override;
- void AsValueIntoInternal(
- base::trace_event::TracedValue* state) const override;
-
- void RequestDoWork();
-
- private:
- mutable base::Lock lock_; // Protects |now_|.
- base::TimeTicks now_;
-
- TaskQueueManager* task_queue_manager_; // NOT OWNED
- base::Closure do_work_closure_;
-
- DISALLOW_COPY_AND_ASSIGN(VirtualTimeDomain);
-};
-
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_BASE_VIRTUAL_TIME_DOMAIN_H_
diff --git a/chromium/components/scheduler/base/work_queue.cc b/chromium/components/scheduler/base/work_queue.cc
deleted file mode 100644
index 313baa9af36..00000000000
--- a/chromium/components/scheduler/base/work_queue.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2015 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/scheduler/base/work_queue.h"
-
-#include "components/scheduler/base/work_queue_sets.h"
-
-namespace scheduler {
-namespace internal {
-
-WorkQueue::WorkQueue(TaskQueueImpl* task_queue, const char* name)
- : work_queue_sets_(nullptr),
- task_queue_(task_queue),
- work_queue_set_index_(0),
- name_(name) {}
-
-void WorkQueue::AsValueInto(base::trace_event::TracedValue* state) const {
- std::queue<TaskQueueImpl::Task> queue_copy(work_queue_);
- while (!queue_copy.empty()) {
- TaskQueueImpl::TaskAsValueInto(queue_copy.front(), state);
- queue_copy.pop();
- }
-}
-
-WorkQueue::~WorkQueue() {
- DCHECK(!work_queue_sets_) << task_queue_ ->GetName() << " : "
- << work_queue_sets_->name() << " : " << name_;
-}
-
-const TaskQueueImpl::Task* WorkQueue::GetFrontTask() const {
- if (work_queue_.empty())
- return nullptr;
- return &work_queue_.front();
-}
-
-bool WorkQueue::GetFrontTaskEnqueueOrder(EnqueueOrder* enqueue_order) const {
- if (work_queue_.empty())
- return false;
- *enqueue_order = work_queue_.front().enqueue_order();
- return true;
-}
-
-void WorkQueue::Push(const TaskQueueImpl::Task& task) {
- bool was_empty = work_queue_.empty();
- work_queue_.push(task);
- if (was_empty && work_queue_sets_)
- work_queue_sets_->OnPushQueue(this);
-}
-
-void WorkQueue::PushAndSetEnqueueOrder(const TaskQueueImpl::Task& task,
- EnqueueOrder enqueue_order) {
- bool was_empty = work_queue_.empty();
- work_queue_.push(task);
- work_queue_.back().set_enqueue_order(enqueue_order);
-
- if (was_empty && work_queue_sets_)
- work_queue_sets_->OnPushQueue(this);
-}
-
-void WorkQueue::PopTaskForTest() {
- work_queue_.pop();
-}
-
-void WorkQueue::SwapLocked(std::queue<TaskQueueImpl::Task>& incoming_queue) {
- std::swap(work_queue_, incoming_queue);
-
- if (!work_queue_.empty() && work_queue_sets_)
- work_queue_sets_->OnPushQueue(this);
- task_queue_->TraceQueueSize(true);
-}
-
-TaskQueueImpl::Task WorkQueue::TakeTaskFromWorkQueue() {
- DCHECK(work_queue_sets_);
- DCHECK(!work_queue_.empty());
- TaskQueueImpl::Task pending_task = std::move(work_queue_.front());
- work_queue_.pop();
- work_queue_sets_->OnPopQueue(this);
- task_queue_->TraceQueueSize(false);
- return pending_task;
-}
-
-void WorkQueue::AssignToWorkQueueSets(WorkQueueSets* work_queue_sets) {
- work_queue_sets_ = work_queue_sets;
-}
-
-void WorkQueue::AssignSetIndex(size_t work_queue_set_index) {
- work_queue_set_index_ = work_queue_set_index;
-}
-
-bool WorkQueue::ShouldRunBefore(const WorkQueue* other_queue) const {
- DCHECK(!work_queue_.empty());
- DCHECK(!other_queue->work_queue_.empty());
- EnqueueOrder enqueue_order = 0;
- EnqueueOrder other_enqueue_order = 0;
- bool have_task = GetFrontTaskEnqueueOrder(&enqueue_order);
- bool have_other_task =
- other_queue->GetFrontTaskEnqueueOrder(&other_enqueue_order);
- DCHECK(have_task);
- DCHECK(have_other_task);
- return enqueue_order < other_enqueue_order;
-}
-
-} // namespace internal
-} // namespace scheduler
diff --git a/chromium/components/scheduler/base/work_queue.h b/chromium/components/scheduler/base/work_queue.h
deleted file mode 100644
index 9ff919d7f7e..00000000000
--- a/chromium/components/scheduler/base/work_queue.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2015 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 CONTENT_RENDERER_SCHEDULER_BASE_WORK_QUEUE_H_
-#define CONTENT_RENDERER_SCHEDULER_BASE_WORK_QUEUE_H_
-
-#include <stddef.h>
-
-#include <set>
-
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "components/scheduler/base/enqueue_order.h"
-#include "components/scheduler/base/task_queue_impl.h"
-#include "components/scheduler/scheduler_export.h"
-
-namespace scheduler {
-namespace internal {
-class WorkQueueSets;
-
-class SCHEDULER_EXPORT WorkQueue {
- public:
- WorkQueue(TaskQueueImpl* task_queue, const char* name);
- ~WorkQueue();
-
- // Associates this work queue with the given work queue sets. This must be
- // called before any tasks can be inserted into this work queue.
- void AssignToWorkQueueSets(WorkQueueSets* work_queue_sets);
-
- // Assigns the current set index.
- void AssignSetIndex(size_t work_queue_set_index);
-
- void AsValueInto(base::trace_event::TracedValue* state) const;
-
- // Clears the |work_queue_|.
- void Clear();
-
- // returns true if the |work_queue_| is empty.
- bool Empty() const { return work_queue_.empty(); }
-
- // If the |work_queue_| isn't empty, |enqueue_order| gets set to the enqueue
- // order of the front task and the function returns true. Otherwise the
- // function returns false.
- bool GetFrontTaskEnqueueOrder(EnqueueOrder* enqueue_order) const;
-
- // Returns the first task in this queue or null if the queue is empty.
- const TaskQueueImpl::Task* GetFrontTask() const;
-
- // Pushes the task onto the |work_queue_| and informs the WorkQueueSets if
- // the head changed.
- void Push(const TaskQueueImpl::Task& task);
-
- // Pushes the task onto the |work_queue_|, sets the |enqueue_order| and
- // informs the WorkQueueSets if the head changed.
- void PushAndSetEnqueueOrder(const TaskQueueImpl::Task& task,
- EnqueueOrder enqueue_order);
-
- // Swap the |work_queue_| with |incoming_queue| and informs the
- // WorkQueueSets if the head changed. Assumes |task_queue_->any_thread_lock_|
- // is locked.
- void SwapLocked(std::queue<TaskQueueImpl::Task>& incoming_queue);
-
- size_t Size() const { return work_queue_.size(); }
-
- // Pulls a task off the |work_queue_| and informs the WorkQueueSets.
- TaskQueueImpl::Task TakeTaskFromWorkQueue();
-
- const char* name() const { return name_; }
-
- TaskQueueImpl* task_queue() const { return task_queue_; }
-
- WorkQueueSets* work_queue_sets() const { return work_queue_sets_; }
-
- size_t work_queue_set_index() const { return work_queue_set_index_; }
-
- // Test support function. This should not be used in production code.
- void PopTaskForTest();
-
- // Returns true if the front task in this queue has an older enqueue order
- // than the front task of |other_queue|. Both queue are assumed to be
- // non-empty.
- bool ShouldRunBefore(const WorkQueue* other_queue) const;
-
- private:
- std::queue<TaskQueueImpl::Task> work_queue_;
- WorkQueueSets* work_queue_sets_; // NOT OWNED.
- TaskQueueImpl* task_queue_; // NOT OWNED.
- size_t work_queue_set_index_;
- const char* name_;
-};
-
-} // namespace internal
-} // namespace scheduler
-
-#endif // CONTENT_RENDERER_SCHEDULER_BASE_WORK_QUEUE_H_
diff --git a/chromium/components/scheduler/base/work_queue_sets.cc b/chromium/components/scheduler/base/work_queue_sets.cc
deleted file mode 100644
index 96c5da4a01f..00000000000
--- a/chromium/components/scheduler/base/work_queue_sets.cc
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2015 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/scheduler/base/work_queue_sets.h"
-
-#include "base/logging.h"
-#include "components/scheduler/base/work_queue.h"
-
-namespace scheduler {
-namespace internal {
-
-WorkQueueSets::WorkQueueSets(size_t num_sets, const char* name)
- : enqueue_order_to_work_queue_maps_(num_sets), name_(name) {}
-
-WorkQueueSets::~WorkQueueSets() {}
-
-void WorkQueueSets::AddQueue(WorkQueue* work_queue, size_t set_index) {
- DCHECK(!work_queue->work_queue_sets());
- DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size());
- EnqueueOrder enqueue_order;
- bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order);
- work_queue->AssignToWorkQueueSets(this);
- work_queue->AssignSetIndex(set_index);
- if (!has_enqueue_order)
- return;
- enqueue_order_to_work_queue_maps_[set_index].insert(
- std::make_pair(enqueue_order, work_queue));
-}
-
-void WorkQueueSets::RemoveQueue(WorkQueue* work_queue) {
- DCHECK_EQ(this, work_queue->work_queue_sets());
- EnqueueOrder enqueue_order;
- bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order);
- work_queue->AssignToWorkQueueSets(nullptr);
- if (!has_enqueue_order)
- return;
- size_t set_index = work_queue->work_queue_set_index();
- DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size());
- DCHECK_EQ(
- work_queue,
- enqueue_order_to_work_queue_maps_[set_index].find(enqueue_order)->second);
- enqueue_order_to_work_queue_maps_[set_index].erase(enqueue_order);
-}
-
-void WorkQueueSets::ChangeSetIndex(WorkQueue* work_queue, size_t set_index) {
- DCHECK_EQ(this, work_queue->work_queue_sets());
- DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size());
- EnqueueOrder enqueue_order;
- bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order);
- size_t old_set = work_queue->work_queue_set_index();
- DCHECK_LT(old_set, enqueue_order_to_work_queue_maps_.size());
- DCHECK_NE(old_set, set_index);
- work_queue->AssignSetIndex(set_index);
- if (!has_enqueue_order)
- return;
- enqueue_order_to_work_queue_maps_[old_set].erase(enqueue_order);
- enqueue_order_to_work_queue_maps_[set_index].insert(
- std::make_pair(enqueue_order, work_queue));
-}
-
-void WorkQueueSets::OnPushQueue(WorkQueue* work_queue) {
- // NOTE if this funciton changes, we need to keep |WorkQueueSets::AddQueue| in
- // sync.
- DCHECK_EQ(this, work_queue->work_queue_sets());
- EnqueueOrder enqueue_order;
- bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order);
- DCHECK(has_enqueue_order);
- size_t set_index = work_queue->work_queue_set_index();
- DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size())
- << " set_index = " << set_index;
- enqueue_order_to_work_queue_maps_[set_index].insert(
- std::make_pair(enqueue_order, work_queue));
-}
-
-void WorkQueueSets::OnPopQueue(WorkQueue* work_queue) {
- size_t set_index = work_queue->work_queue_set_index();
- DCHECK_EQ(this, work_queue->work_queue_sets());
- DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size());
- DCHECK(!enqueue_order_to_work_queue_maps_[set_index].empty())
- << " set_index = " << set_index;
- DCHECK_EQ(enqueue_order_to_work_queue_maps_[set_index].begin()->second,
- work_queue)
- << " set_index = " << set_index;
- // O(1) amortised.
- enqueue_order_to_work_queue_maps_[set_index].erase(
- enqueue_order_to_work_queue_maps_[set_index].begin());
- EnqueueOrder enqueue_order;
- bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order);
- if (!has_enqueue_order)
- return;
- enqueue_order_to_work_queue_maps_[set_index].insert(
- std::make_pair(enqueue_order, work_queue));
-}
-
-bool WorkQueueSets::GetOldestQueueInSet(size_t set_index,
- WorkQueue** out_work_queue) const {
- DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size());
- if (enqueue_order_to_work_queue_maps_[set_index].empty())
- return false;
- *out_work_queue =
- enqueue_order_to_work_queue_maps_[set_index].begin()->second;
-#ifndef NDEBUG
- EnqueueOrder enqueue_order;
- DCHECK((*out_work_queue)->GetFrontTaskEnqueueOrder(&enqueue_order));
- DCHECK_EQ(enqueue_order,
- enqueue_order_to_work_queue_maps_[set_index].begin()->first);
-#endif
- return true;
-}
-
-bool WorkQueueSets::IsSetEmpty(size_t set_index) const {
- DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size())
- << " set_index = " << set_index;
- return enqueue_order_to_work_queue_maps_[set_index].empty();
-}
-
-#if DCHECK_IS_ON() || !defined(NDEBUG)
-bool WorkQueueSets::ContainsWorkQueueForTest(
- const WorkQueue* work_queue) const {
- EnqueueOrder enqueue_order;
- bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order);
-
- for (const EnqueueOrderToWorkQueueMap& map :
- enqueue_order_to_work_queue_maps_) {
- for (const EnqueueOrderToWorkQueueMap::value_type& key_value_pair : map) {
- if (key_value_pair.second == work_queue) {
- DCHECK(has_enqueue_order);
- DCHECK_EQ(key_value_pair.first, enqueue_order);
- DCHECK_EQ(this, work_queue->work_queue_sets());
- return true;
- }
- }
- }
-
- if (work_queue->work_queue_sets() == this) {
- DCHECK(!has_enqueue_order);
- return true;
- }
-
- return false;
-}
-#endif
-
-} // namespace internal
-} // namespace scheduler
diff --git a/chromium/components/scheduler/base/work_queue_sets.h b/chromium/components/scheduler/base/work_queue_sets.h
deleted file mode 100644
index 0c2c2dcf2c1..00000000000
--- a/chromium/components/scheduler/base/work_queue_sets.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2015 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_SCHEDULER_BASE_WORK_QUEUE_SETS_H_
-#define COMPONENTS_SCHEDULER_BASE_WORK_QUEUE_SETS_H_
-
-#include <stddef.h>
-
-#include <map>
-#include <vector>
-
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "components/scheduler/base/task_queue_impl.h"
-#include "components/scheduler/scheduler_export.h"
-
-namespace scheduler {
-namespace internal {
-class TaskQueueImpl;
-
-class SCHEDULER_EXPORT WorkQueueSets {
- public:
- WorkQueueSets(size_t num_sets, const char* name);
- ~WorkQueueSets();
-
- // O(log num queues)
- void AddQueue(WorkQueue* queue, size_t set_index);
-
- // O(log num queues)
- void RemoveQueue(WorkQueue* work_queue);
-
- // O(log num queues)
- void ChangeSetIndex(WorkQueue* queue, size_t set_index);
-
- // O(log num queues)
- void OnPushQueue(WorkQueue* work_queue);
-
- // If empty it's O(1) amortized, otherwise it's O(log num queues)
- void OnPopQueue(WorkQueue* work_queue);
-
- // O(1)
- bool GetOldestQueueInSet(size_t set_index, WorkQueue** out_work_queue) const;
-
- // O(1)
- bool IsSetEmpty(size_t set_index) const;
-
-#if DCHECK_IS_ON() || !defined(NDEBUG)
- // Note this iterates over everything in |enqueue_order_to_work_queue_maps_|.
- // It's intended for use with DCHECKS and for testing
- bool ContainsWorkQueueForTest(const WorkQueue* queue) const;
-#endif
-
- const char* name() const { return name_; }
-
- private:
- typedef std::map<EnqueueOrder, WorkQueue*> EnqueueOrderToWorkQueueMap;
- std::vector<EnqueueOrderToWorkQueueMap> enqueue_order_to_work_queue_maps_;
- const char* name_;
-
- DISALLOW_COPY_AND_ASSIGN(WorkQueueSets);
-};
-
-} // namespace internal
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_BASE_WORK_QUEUE_SETS_H_
diff --git a/chromium/components/scheduler/base/work_queue_sets_unittest.cc b/chromium/components/scheduler/base/work_queue_sets_unittest.cc
deleted file mode 100644
index 4466db1f981..00000000000
--- a/chromium/components/scheduler/base/work_queue_sets_unittest.cc
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright 2015 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/scheduler/base/work_queue_sets.h"
-
-#include <stddef.h>
-
-#include "base/memory/ptr_util.h"
-#include "components/scheduler/base/work_queue.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace scheduler {
-class TimeDomain;
-
-namespace internal {
-
-class WorkQueueSetsTest : public testing::Test {
- public:
- void SetUp() override {
- work_queue_sets_.reset(new WorkQueueSets(kNumSets, "test"));
- }
-
- void TearDown() override {
- for (std::unique_ptr<WorkQueue>& work_queue : work_queues_) {
- if (work_queue->work_queue_sets())
- work_queue_sets_->RemoveQueue(work_queue.get());
- }
- }
-
- protected:
- enum {
- kNumSets = 5 // An arbitary choice.
- };
-
- WorkQueue* NewTaskQueue(const char* queue_name) {
- WorkQueue* queue = new WorkQueue(nullptr, "test");
- work_queues_.push_back(base::WrapUnique(queue));
- work_queue_sets_->AddQueue(queue, TaskQueue::CONTROL_PRIORITY);
- return queue;
- }
-
- TaskQueueImpl::Task FakeTaskWithEnqueueOrder(int enqueue_order) {
- TaskQueueImpl::Task fake_task(FROM_HERE, base::Closure(), base::TimeTicks(),
- 0, true);
- fake_task.set_enqueue_order(enqueue_order);
- return fake_task;
- }
-
- std::vector<std::unique_ptr<WorkQueue>> work_queues_;
- std::unique_ptr<WorkQueueSets> work_queue_sets_;
-};
-
-TEST_F(WorkQueueSetsTest, ChangeSetIndex) {
- WorkQueue* work_queue = NewTaskQueue("queue");
- size_t set = TaskQueue::NORMAL_PRIORITY;
- work_queue_sets_->ChangeSetIndex(work_queue, set);
-
- EXPECT_EQ(set, work_queue->work_queue_set_index());
-}
-
-TEST_F(WorkQueueSetsTest, GetOldestQueueInSet_QueueEmpty) {
- WorkQueue* work_queue = NewTaskQueue("queue");
- size_t set = TaskQueue::NORMAL_PRIORITY;
- work_queue_sets_->ChangeSetIndex(work_queue, set);
-
- WorkQueue* selected_work_queue;
- EXPECT_FALSE(
- work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue));
-}
-
-TEST_F(WorkQueueSetsTest, OnPushQueue) {
- WorkQueue* work_queue = NewTaskQueue("queue");
- size_t set = TaskQueue::NORMAL_PRIORITY;
- work_queue_sets_->ChangeSetIndex(work_queue, set);
-
- WorkQueue* selected_work_queue;
- EXPECT_FALSE(
- work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue));
-
- work_queue->Push(FakeTaskWithEnqueueOrder(10));
- work_queue_sets_->OnPushQueue(work_queue);
-
- EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue));
- EXPECT_EQ(work_queue, selected_work_queue);
-}
-
-TEST_F(WorkQueueSetsTest, GetOldestQueueInSet_SingleTaskInSet) {
- WorkQueue* work_queue = NewTaskQueue("queue");
- work_queue->Push(FakeTaskWithEnqueueOrder(10));
- size_t set = 1;
- work_queue_sets_->ChangeSetIndex(work_queue, set);
-
- WorkQueue* selected_work_queue;
- EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue));
- EXPECT_EQ(work_queue, selected_work_queue);
-}
-
-TEST_F(WorkQueueSetsTest, GetOldestQueueInSet_MultipleAgesInSet) {
- WorkQueue* queue1 = NewTaskQueue("queue1");
- WorkQueue* queue2 = NewTaskQueue("queue2");
- WorkQueue* queue3 = NewTaskQueue("queue2");
- queue1->Push(FakeTaskWithEnqueueOrder(6));
- queue2->Push(FakeTaskWithEnqueueOrder(5));
- queue3->Push(FakeTaskWithEnqueueOrder(4));
- size_t set = 2;
- work_queue_sets_->ChangeSetIndex(queue1, set);
- work_queue_sets_->ChangeSetIndex(queue2, set);
- work_queue_sets_->ChangeSetIndex(queue3, set);
-
- WorkQueue* selected_work_queue;
- EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue));
- EXPECT_EQ(queue3, selected_work_queue);
-}
-
-TEST_F(WorkQueueSetsTest, OnPopQueue) {
- WorkQueue* queue1 = NewTaskQueue("queue1");
- WorkQueue* queue2 = NewTaskQueue("queue2");
- WorkQueue* queue3 = NewTaskQueue("queue3");
- queue1->Push(FakeTaskWithEnqueueOrder(6));
- queue2->Push(FakeTaskWithEnqueueOrder(3));
- queue2->Push(FakeTaskWithEnqueueOrder(1));
- queue3->Push(FakeTaskWithEnqueueOrder(4));
- size_t set = 3;
- work_queue_sets_->ChangeSetIndex(queue1, set);
- work_queue_sets_->ChangeSetIndex(queue2, set);
- work_queue_sets_->ChangeSetIndex(queue3, set);
-
- WorkQueue* selected_work_queue;
- EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue));
- EXPECT_EQ(queue2, selected_work_queue);
-
- queue2->PopTaskForTest();
- work_queue_sets_->OnPopQueue(queue2);
-
- EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue));
- EXPECT_EQ(queue2, selected_work_queue);
-}
-
-TEST_F(WorkQueueSetsTest, OnPopQueue_QueueBecomesEmpty) {
- WorkQueue* queue1 = NewTaskQueue("queue");
- WorkQueue* queue2 = NewTaskQueue("queue");
- WorkQueue* queue3 = NewTaskQueue("queue");
- queue1->Push(FakeTaskWithEnqueueOrder(6));
- queue2->Push(FakeTaskWithEnqueueOrder(5));
- queue3->Push(FakeTaskWithEnqueueOrder(4));
- size_t set = 4;
- work_queue_sets_->ChangeSetIndex(queue1, set);
- work_queue_sets_->ChangeSetIndex(queue2, set);
- work_queue_sets_->ChangeSetIndex(queue3, set);
-
- WorkQueue* selected_work_queue;
- EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue));
- EXPECT_EQ(queue3, selected_work_queue);
-
- queue3->PopTaskForTest();
- work_queue_sets_->OnPopQueue(queue3);
-
- EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue));
- EXPECT_EQ(queue2, selected_work_queue);
-}
-
-TEST_F(WorkQueueSetsTest,
- GetOldestQueueInSet_MultipleAgesInSetIntegerRollover) {
- WorkQueue* queue1 = NewTaskQueue("queue1");
- WorkQueue* queue2 = NewTaskQueue("queue2");
- WorkQueue* queue3 = NewTaskQueue("queue3");
- queue1->Push(FakeTaskWithEnqueueOrder(0x7ffffff1));
- queue2->Push(FakeTaskWithEnqueueOrder(0x7ffffff0));
- queue3->Push(FakeTaskWithEnqueueOrder(-0x7ffffff1));
- size_t set = 1;
- work_queue_sets_->ChangeSetIndex(queue1, set);
- work_queue_sets_->ChangeSetIndex(queue2, set);
- work_queue_sets_->ChangeSetIndex(queue3, set);
-
- WorkQueue* selected_work_queue;
- EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue));
- EXPECT_EQ(queue2, selected_work_queue);
-}
-
-TEST_F(WorkQueueSetsTest, GetOldestQueueInSet_MultipleAgesInSet_RemoveQueue) {
- WorkQueue* queue1 = NewTaskQueue("queue1");
- WorkQueue* queue2 = NewTaskQueue("queue2");
- WorkQueue* queue3 = NewTaskQueue("queue3");
- queue1->Push(FakeTaskWithEnqueueOrder(6));
- queue2->Push(FakeTaskWithEnqueueOrder(5));
- queue3->Push(FakeTaskWithEnqueueOrder(4));
- size_t set = 1;
- work_queue_sets_->ChangeSetIndex(queue1, set);
- work_queue_sets_->ChangeSetIndex(queue2, set);
- work_queue_sets_->ChangeSetIndex(queue3, set);
- work_queue_sets_->RemoveQueue(queue3);
-
- WorkQueue* selected_work_queue;
- EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue));
- EXPECT_EQ(queue2, selected_work_queue);
-}
-
-TEST_F(WorkQueueSetsTest, ChangeSetIndex_Complex) {
- WorkQueue* queue1 = NewTaskQueue("queue1");
- WorkQueue* queue2 = NewTaskQueue("queue2");
- WorkQueue* queue3 = NewTaskQueue("queue3");
- WorkQueue* queue4 = NewTaskQueue("queue4");
- queue1->Push(FakeTaskWithEnqueueOrder(6));
- queue2->Push(FakeTaskWithEnqueueOrder(5));
- queue3->Push(FakeTaskWithEnqueueOrder(4));
- queue4->Push(FakeTaskWithEnqueueOrder(3));
- size_t set1 = 1;
- size_t set2 = 2;
- work_queue_sets_->ChangeSetIndex(queue1, set1);
- work_queue_sets_->ChangeSetIndex(queue2, set1);
- work_queue_sets_->ChangeSetIndex(queue3, set2);
- work_queue_sets_->ChangeSetIndex(queue4, set2);
-
- WorkQueue* selected_work_queue;
- EXPECT_TRUE(
- work_queue_sets_->GetOldestQueueInSet(set1, &selected_work_queue));
- EXPECT_EQ(queue2, selected_work_queue);
-
- EXPECT_TRUE(
- work_queue_sets_->GetOldestQueueInSet(set2, &selected_work_queue));
- EXPECT_EQ(queue4, selected_work_queue);
-
- work_queue_sets_->ChangeSetIndex(queue4, set1);
-
- EXPECT_TRUE(
- work_queue_sets_->GetOldestQueueInSet(set1, &selected_work_queue));
- EXPECT_EQ(queue4, selected_work_queue);
-
- EXPECT_TRUE(
- work_queue_sets_->GetOldestQueueInSet(set2, &selected_work_queue));
- EXPECT_EQ(queue3, selected_work_queue);
-}
-
-TEST_F(WorkQueueSetsTest, IsSetEmpty_NoWork) {
- size_t set = 2;
- EXPECT_TRUE(work_queue_sets_->IsSetEmpty(set));
-
- WorkQueue* work_queue = NewTaskQueue("queue");
- work_queue_sets_->ChangeSetIndex(work_queue, set);
- EXPECT_TRUE(work_queue_sets_->IsSetEmpty(set));
-}
-
-TEST_F(WorkQueueSetsTest, IsSetEmpty_Work) {
- size_t set = 2;
- EXPECT_TRUE(work_queue_sets_->IsSetEmpty(set));
-
- WorkQueue* work_queue = NewTaskQueue("queue");
- work_queue->Push(FakeTaskWithEnqueueOrder(1));
- work_queue_sets_->ChangeSetIndex(work_queue, set);
- EXPECT_FALSE(work_queue_sets_->IsSetEmpty(set));
-
- work_queue->PopTaskForTest();
- work_queue_sets_->OnPopQueue(work_queue);
- EXPECT_TRUE(work_queue_sets_->IsSetEmpty(set));
-}
-
-} // namespace internal
-} // namespace scheduler