Commit 6923bfde authored by Alexander Timin's avatar Alexander Timin Committed by Commit Bot

[scheduler] Group all task information from PostTask into PostedTask.

Group all information passed to PostDelayedTask (callback, posted from
and delay) into a struct to plumb it together to a place inside
scheduler where a sequence number is generated and PendingTask is
created.

This will allow for easier plumbing for additional task metadata that
we might want to add in the future.

R=alexclarke@chromium.org
CC=skyostil@chromium.org

Bug: 
Change-Id: Iac00cd6c8ce5ac468116ee8bce17894da2d9bc79
Reviewed-on: https://chromium-review.googlesource.com/664703
Commit-Queue: Alexander Timin <altimin@chromium.org>
Reviewed-by: default avatarAlex Clarke <alexclarke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#501632}
parent fd585def
...@@ -20,6 +20,15 @@ TaskQueue::Task::Task(const base::Location& posted_from, ...@@ -20,6 +20,15 @@ TaskQueue::Task::Task(const base::Location& posted_from,
bool nestable) bool nestable)
: PendingTask(posted_from, std::move(task), desired_run_time, nestable) {} : PendingTask(posted_from, std::move(task), desired_run_time, nestable) {}
TaskQueue::PostedTask::PostedTask(base::OnceClosure callback,
base::Location posted_from,
base::TimeDelta delay,
bool nestable)
: callback(std::move(callback)),
posted_from(posted_from),
delay(delay),
nestable(nestable) {}
void TaskQueue::UnregisterTaskQueue() { void TaskQueue::UnregisterTaskQueue() {
impl_->UnregisterTaskQueue(this); impl_->UnregisterTaskQueue(this);
} }
...@@ -31,13 +40,15 @@ bool TaskQueue::RunsTasksInCurrentSequence() const { ...@@ -31,13 +40,15 @@ bool TaskQueue::RunsTasksInCurrentSequence() const {
bool TaskQueue::PostDelayedTask(const base::Location& from_here, bool TaskQueue::PostDelayedTask(const base::Location& from_here,
base::OnceClosure task, base::OnceClosure task,
base::TimeDelta delay) { base::TimeDelta delay) {
return impl_->PostDelayedTask(from_here, std::move(task), delay); return impl_->PostDelayedTask(
PostedTask(std::move(task), from_here, delay, /* nestable */ true));
} }
bool TaskQueue::PostNonNestableDelayedTask(const base::Location& from_here, bool TaskQueue::PostNonNestableDelayedTask(const base::Location& from_here,
base::OnceClosure task, base::OnceClosure task,
base::TimeDelta delay) { base::TimeDelta delay) {
return impl_->PostNonNestableDelayedTask(from_here, std::move(task), delay); return impl_->PostDelayedTask(
PostedTask(std::move(task), from_here, delay, /* nestable */ false));
} }
std::unique_ptr<TaskQueue::QueueEnabledVoter> std::unique_ptr<TaskQueue::QueueEnabledVoter>
......
...@@ -48,6 +48,20 @@ class PLATFORM_EXPORT TaskQueue : public base::SingleThreadTaskRunner { ...@@ -48,6 +48,20 @@ class PLATFORM_EXPORT TaskQueue : public base::SingleThreadTaskRunner {
base::TimeTicks next_wake_up) = 0; base::TimeTicks next_wake_up) = 0;
}; };
// A wrapper around base::OnceClosure with additional metadata to be passed
// to PostTask and plumbed until PendingTask is created.
struct PostedTask {
PostedTask(base::OnceClosure callback,
base::Location posted_from,
base::TimeDelta delay,
bool nestable);
base::OnceClosure callback;
base::Location posted_from;
base::TimeDelta delay;
bool nestable;
};
// Unregisters the task queue after which no tasks posted to it will run and // Unregisters the task queue after which no tasks posted to it will run and
// the TaskQueueManager's reference to it will be released soon. // the TaskQueueManager's reference to it will be released soon.
virtual void UnregisterTaskQueue(); virtual void UnregisterTaskQueue();
......
...@@ -164,33 +164,17 @@ bool TaskQueueImpl::RunsTasksInCurrentSequence() const { ...@@ -164,33 +164,17 @@ bool TaskQueueImpl::RunsTasksInCurrentSequence() const {
return base::PlatformThread::CurrentId() == thread_id_; return base::PlatformThread::CurrentId() == thread_id_;
} }
bool TaskQueueImpl::PostDelayedTask(const base::Location& from_here, bool TaskQueueImpl::PostDelayedTask(TaskQueue::PostedTask task) {
base::OnceClosure task, if (task.delay.is_zero())
base::TimeDelta delay) { return PostImmediateTaskImpl(std::move(task));
if (delay.is_zero())
return PostImmediateTaskImpl(from_here, std::move(task), TaskType::NORMAL);
return PostDelayedTaskImpl(from_here, std::move(task), delay, return PostDelayedTaskImpl(std::move(task));
TaskType::NORMAL);
} }
bool TaskQueueImpl::PostNonNestableDelayedTask(const base::Location& from_here, bool TaskQueueImpl::PostImmediateTaskImpl(TaskQueue::PostedTask task) {
base::OnceClosure task,
base::TimeDelta delay) {
if (delay.is_zero())
return PostImmediateTaskImpl(from_here, std::move(task),
TaskType::NON_NESTABLE);
return PostDelayedTaskImpl(from_here, std::move(task), delay,
TaskType::NON_NESTABLE);
}
bool TaskQueueImpl::PostImmediateTaskImpl(const base::Location& from_here,
base::OnceClosure task,
TaskType task_type) {
// Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167 // Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167
// for details. // for details.
CHECK(task); CHECK(task.callback);
base::AutoLock lock(any_thread_lock_); base::AutoLock lock(any_thread_lock_);
if (!any_thread().task_queue_manager) if (!any_thread().task_queue_manager)
return false; return false;
...@@ -198,20 +182,17 @@ bool TaskQueueImpl::PostImmediateTaskImpl(const base::Location& from_here, ...@@ -198,20 +182,17 @@ bool TaskQueueImpl::PostImmediateTaskImpl(const base::Location& from_here,
EnqueueOrder sequence_number = EnqueueOrder sequence_number =
any_thread().task_queue_manager->GetNextSequenceNumber(); any_thread().task_queue_manager->GetNextSequenceNumber();
PushOntoImmediateIncomingQueueLocked(from_here, std::move(task), PushOntoImmediateIncomingQueueLocked(
base::TimeTicks(), sequence_number, Task(task.posted_from, std::move(task.callback), base::TimeTicks(),
task_type != TaskType::NON_NESTABLE); sequence_number, task.nestable, sequence_number));
return true; return true;
} }
bool TaskQueueImpl::PostDelayedTaskImpl(const base::Location& from_here, bool TaskQueueImpl::PostDelayedTaskImpl(TaskQueue::PostedTask task) {
base::OnceClosure task,
base::TimeDelta delay,
TaskType task_type) {
// Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167 // Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167
// for details. // for details.
CHECK(task); CHECK(task.callback);
DCHECK_GT(delay, base::TimeDelta()); DCHECK_GT(task.delay, base::TimeDelta());
if (base::PlatformThread::CurrentId() == thread_id_) { if (base::PlatformThread::CurrentId() == thread_id_) {
// Lock-free fast path for delayed tasks posted from the main thread. // Lock-free fast path for delayed tasks posted from the main thread.
if (!main_thread_only().task_queue_manager) if (!main_thread_only().task_queue_manager)
...@@ -221,10 +202,10 @@ bool TaskQueueImpl::PostDelayedTaskImpl(const base::Location& from_here, ...@@ -221,10 +202,10 @@ bool TaskQueueImpl::PostDelayedTaskImpl(const base::Location& from_here,
main_thread_only().task_queue_manager->GetNextSequenceNumber(); main_thread_only().task_queue_manager->GetNextSequenceNumber();
base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); base::TimeTicks time_domain_now = main_thread_only().time_domain->Now();
base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay; base::TimeTicks time_domain_delayed_run_time = time_domain_now + task.delay;
PushOntoDelayedIncomingQueueFromMainThread( PushOntoDelayedIncomingQueueFromMainThread(
Task(from_here, std::move(task), time_domain_delayed_run_time, Task(task.posted_from, std::move(task.callback),
sequence_number, task_type != TaskType::NON_NESTABLE), time_domain_delayed_run_time, sequence_number, task.nestable),
time_domain_now); time_domain_now);
} else { } else {
// NOTE posting a delayed task from a different thread is not expected to // NOTE posting a delayed task from a different thread is not expected to
...@@ -239,10 +220,10 @@ bool TaskQueueImpl::PostDelayedTaskImpl(const base::Location& from_here, ...@@ -239,10 +220,10 @@ bool TaskQueueImpl::PostDelayedTaskImpl(const base::Location& from_here,
any_thread().task_queue_manager->GetNextSequenceNumber(); any_thread().task_queue_manager->GetNextSequenceNumber();
base::TimeTicks time_domain_now = any_thread().time_domain->Now(); base::TimeTicks time_domain_now = any_thread().time_domain->Now();
base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay; base::TimeTicks time_domain_delayed_run_time = time_domain_now + task.delay;
PushOntoDelayedIncomingQueueLocked( PushOntoDelayedIncomingQueueLocked(
Task(from_here, std::move(task), time_domain_delayed_run_time, Task(task.posted_from, std::move(task.callback),
sequence_number, task_type != TaskType::NON_NESTABLE)); time_domain_delayed_run_time, sequence_number, task.nestable));
} }
return true; return true;
} }
...@@ -273,10 +254,11 @@ void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) { ...@@ -273,10 +254,11 @@ void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) {
int thread_hop_task_sequence_number = int thread_hop_task_sequence_number =
any_thread().task_queue_manager->GetNextSequenceNumber(); any_thread().task_queue_manager->GetNextSequenceNumber();
PushOntoImmediateIncomingQueueLocked( PushOntoImmediateIncomingQueueLocked(
FROM_HERE, Task(FROM_HERE,
base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask,
base::Unretained(this), base::Passed(&pending_task)), base::Unretained(this), base::Passed(&pending_task)),
base::TimeTicks(), thread_hop_task_sequence_number, false); base::TimeTicks(), thread_hop_task_sequence_number, false,
thread_hop_task_sequence_number));
} }
void TaskQueueImpl::ScheduleDelayedWorkTask(Task pending_task) { void TaskQueueImpl::ScheduleDelayedWorkTask(Task pending_task) {
...@@ -300,22 +282,18 @@ void TaskQueueImpl::ScheduleDelayedWorkTask(Task pending_task) { ...@@ -300,22 +282,18 @@ void TaskQueueImpl::ScheduleDelayedWorkTask(Task pending_task) {
TraceQueueSize(); TraceQueueSize();
} }
void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked( void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked(Task task) {
const base::Location& posted_from,
base::OnceClosure task,
base::TimeTicks desired_run_time,
EnqueueOrder sequence_number,
bool nestable) {
// If the |immediate_incoming_queue| is empty we need a DoWork posted to make // If the |immediate_incoming_queue| is empty we need a DoWork posted to make
// it run. // it run.
bool was_immediate_incoming_queue_empty; bool was_immediate_incoming_queue_empty;
EnqueueOrder sequence_number = task.sequence_num;
base::TimeTicks desired_run_time = task.delayed_run_time;
{ {
base::AutoLock lock(immediate_incoming_queue_lock_); base::AutoLock lock(immediate_incoming_queue_lock_);
was_immediate_incoming_queue_empty = immediate_incoming_queue().empty(); was_immediate_incoming_queue_empty = immediate_incoming_queue().empty();
immediate_incoming_queue().emplace_back(posted_from, std::move(task), immediate_incoming_queue().push_back(std::move(task));
desired_run_time, sequence_number,
nestable, sequence_number);
any_thread().task_queue_manager->DidQueueTask( any_thread().task_queue_manager->DidQueueTask(
immediate_incoming_queue().back()); immediate_incoming_queue().back());
} }
......
...@@ -143,12 +143,7 @@ class PLATFORM_EXPORT TaskQueueImpl { ...@@ -143,12 +143,7 @@ class PLATFORM_EXPORT TaskQueueImpl {
// TaskQueue implementation. // TaskQueue implementation.
const char* GetName() const; const char* GetName() const;
bool RunsTasksInCurrentSequence() const; bool RunsTasksInCurrentSequence() const;
bool PostDelayedTask(const base::Location& from_here, bool PostDelayedTask(TaskQueue::PostedTask task);
base::OnceClosure task,
base::TimeDelta delay);
bool PostNonNestableDelayedTask(const base::Location& from_here,
base::OnceClosure task,
base::TimeDelta delay);
// Require a reference to enclosing task queue for lifetime control. // Require a reference to enclosing task queue for lifetime control.
std::unique_ptr<TaskQueue::QueueEnabledVoter> CreateQueueEnabledVoter( std::unique_ptr<TaskQueue::QueueEnabledVoter> CreateQueueEnabledVoter(
scoped_refptr<TaskQueue> owning_task_queue); scoped_refptr<TaskQueue> owning_task_queue);
...@@ -280,11 +275,6 @@ class PLATFORM_EXPORT TaskQueueImpl { ...@@ -280,11 +275,6 @@ class PLATFORM_EXPORT TaskQueueImpl {
friend class WorkQueue; friend class WorkQueue;
friend class WorkQueueTest; friend class WorkQueueTest;
enum class TaskType {
NORMAL,
NON_NESTABLE,
};
struct AnyThread { struct AnyThread {
AnyThread(TaskQueueManager* task_queue_manager, TimeDomain* time_domain); AnyThread(TaskQueueManager* task_queue_manager, TimeDomain* time_domain);
~AnyThread(); ~AnyThread();
...@@ -329,13 +319,8 @@ class PLATFORM_EXPORT TaskQueueImpl { ...@@ -329,13 +319,8 @@ class PLATFORM_EXPORT TaskQueueImpl {
bool is_enabled_for_test; bool is_enabled_for_test;
}; };
bool PostImmediateTaskImpl(const base::Location& from_here, bool PostImmediateTaskImpl(TaskQueue::PostedTask task);
base::OnceClosure task, bool PostDelayedTaskImpl(TaskQueue::PostedTask task);
TaskType task_type);
bool PostDelayedTaskImpl(const base::Location& from_here,
base::OnceClosure task,
base::TimeDelta delay,
TaskType task_type);
// Push the task onto the |delayed_incoming_queue|. Lock-free main thread // Push the task onto the |delayed_incoming_queue|. Lock-free main thread
// only fast path. // only fast path.
...@@ -353,11 +338,7 @@ class PLATFORM_EXPORT TaskQueueImpl { ...@@ -353,11 +338,7 @@ class PLATFORM_EXPORT TaskQueueImpl {
// Push the task onto the |immediate_incoming_queue| and for auto pumped // Push the task onto the |immediate_incoming_queue| and for auto pumped
// queues it calls MaybePostDoWorkOnMainRunner if the Incoming queue was // queues it calls MaybePostDoWorkOnMainRunner if the Incoming queue was
// empty. // empty.
void PushOntoImmediateIncomingQueueLocked(const base::Location& posted_from, void PushOntoImmediateIncomingQueueLocked(Task task);
base::OnceClosure task,
base::TimeTicks desired_run_time,
EnqueueOrder sequence_number,
bool nestable);
// We reserve an inline capacity of 8 tasks to try and reduce the load on // We reserve an inline capacity of 8 tasks to try and reduce the load on
// PartitionAlloc. // PartitionAlloc.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment