Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1210)

Unified Diff: third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc

Issue 2644553002: Refactor TimeDomain::MaybeAdvanceTime in preparation for DoWork deduping (Closed)
Patch Set: Rebased Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc
index cbfc90cdd527d88838cf21921758e75ccd0ec4bb..b2572ae4a5f682b39538e36dcc4ff0e14f989020 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc
@@ -147,15 +147,17 @@ void TaskQueueManager::UnregisterTaskQueue(
selector_.RemoveQueue(task_queue.get());
}
-void TaskQueueManager::UpdateWorkQueues(LazyNow lazy_now) {
+void TaskQueueManager::UpdateWorkQueues(LazyNow* lazy_now) {
TRACE_EVENT0(disabled_by_default_tracing_category_,
"TaskQueueManager::UpdateWorkQueues");
for (TimeDomain* time_domain : time_domains_) {
- LazyNow lazy_now_in_domain = time_domain == real_time_domain_.get()
- ? lazy_now
- : time_domain->CreateLazyNow();
- time_domain->UpdateWorkQueues(lazy_now_in_domain);
+ if (time_domain == real_time_domain_.get()) {
+ time_domain->UpdateWorkQueues(lazy_now);
+ } else {
+ LazyNow time_domain_lazy_now = time_domain->CreateLazyNow();
+ time_domain->UpdateWorkQueues(&time_domain_lazy_now);
+ }
}
}
@@ -232,14 +234,15 @@ void TaskQueueManager::DoWork(base::TimeTicks run_time, bool from_main_thread) {
queues_to_delete_.clear();
LazyNow lazy_now(real_time_domain()->CreateLazyNow());
- UpdateWorkQueues(lazy_now);
+ UpdateWorkQueues(&lazy_now);
for (int i = 0; i < work_batch_size_; i++) {
internal::WorkQueue* work_queue;
if (!SelectWorkQueueToService(&work_queue))
break;
- switch (ProcessTaskFromWorkQueue(work_queue, &lazy_now)) {
+ base::TimeTicks time_after_task;
+ switch (ProcessTaskFromWorkQueue(work_queue, lazy_now, &time_after_task)) {
case ProcessTaskResult::DEFERRED:
// If a task was deferred, try again with another task.
continue;
@@ -251,7 +254,9 @@ void TaskQueueManager::DoWork(base::TimeTicks run_time, bool from_main_thread) {
work_queue = nullptr; // The queue may have been unregistered.
- UpdateWorkQueues(lazy_now);
+ lazy_now = time_after_task.is_null() ? real_time_domain()->CreateLazyNow()
+ : LazyNow(time_after_task);
+ UpdateWorkQueues(&lazy_now);
// 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().
@@ -264,16 +269,38 @@ void TaskQueueManager::DoWork(base::TimeTicks run_time, bool from_main_thread) {
// 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())
+ base::Optional<base::TimeDelta> next_delay =
+ ComputeDelayTillNextTask(&lazy_now);
+
+ if (!next_delay)
+ return;
+
+ base::TimeDelta delay = next_delay.value();
+ if (delay.is_zero()) {
MaybeScheduleImmediateWork(FROM_HERE);
+ } else {
+ MaybeScheduleDelayedWork(FROM_HERE, lazy_now.Now(), delay);
+ }
}
-bool TaskQueueManager::TryAdvanceTimeDomains() {
- bool can_advance = false;
+base::Optional<base::TimeDelta> TaskQueueManager::ComputeDelayTillNextTask(
+ LazyNow* lazy_now) {
+ // If the selector has non-empty queues we trivially know there is immediate
+ // work to be done.
+ if (!selector_.EnabledWorkQueuesEmpty())
+ return base::TimeDelta();
+
+ // Otherwise we need to find the shortest delay, if any.
+ base::Optional<base::TimeDelta> next_continuation;
for (TimeDomain* time_domain : time_domains_) {
- can_advance |= time_domain->MaybeAdvanceTime();
+ base::Optional<base::TimeDelta> continuation =
+ time_domain->DelayTillNextTask(lazy_now);
+ if (!continuation)
+ continue;
+ if (!next_continuation || next_continuation.value() > continuation.value())
+ next_continuation = continuation;
}
- return can_advance;
+ return next_continuation;
}
bool TaskQueueManager::SelectWorkQueueToService(
@@ -292,7 +319,8 @@ void TaskQueueManager::DidQueueTask(
TaskQueueManager::ProcessTaskResult TaskQueueManager::ProcessTaskFromWorkQueue(
internal::WorkQueue* work_queue,
- LazyNow* lazy_now) {
+ LazyNow time_before_task,
+ base::TimeTicks* time_after_task) {
DCHECK(main_thread_checker_.CalledOnValidThread());
scoped_refptr<DeletionSentinel> protect(deletion_sentinel_);
internal::TaskQueueImpl::Task pending_task =
@@ -332,7 +360,7 @@ TaskQueueManager::ProcessTaskResult TaskQueueManager::ProcessTaskFromWorkQueue(
bool notify_time_observers =
!delegate_->IsNested() && task_time_observers_.might_have_observers();
if (notify_time_observers) {
- task_start_time = MonotonicTimeInSeconds(lazy_now->Now());
+ task_start_time = MonotonicTimeInSeconds(time_before_task.Now());
for (auto& observer : task_time_observers_)
observer.willProcessTask(queue, task_start_time);
}
@@ -354,11 +382,11 @@ TaskQueueManager::ProcessTaskResult TaskQueueManager::ProcessTaskFromWorkQueue(
currently_executing_task_queue_ = prev_executing_task_queue;
- *lazy_now = real_time_domain()->CreateLazyNow();
if (queue->GetShouldNotifyObservers()) {
if (task_start_time) {
- double task_end_time = MonotonicTimeInSeconds(lazy_now->Now());
+ *time_after_task = real_time_domain()->Now();
+ double task_end_time = MonotonicTimeInSeconds(*time_after_task);
for (auto& observer : task_time_observers_)
observer.didProcessTask(queue, task_start_time, task_end_time);
}
@@ -409,7 +437,8 @@ void TaskQueueManager::RemoveTaskObserver(
task_observers_.RemoveObserver(task_observer);
}
-void TaskQueueManager::AddTaskTimeObserver(TaskTimeObserver* task_time_observer) {
+void TaskQueueManager::AddTaskTimeObserver(
+ TaskTimeObserver* task_time_observer) {
DCHECK(main_thread_checker_.CalledOnValidThread());
task_time_observers_.AddObserver(task_time_observer);
}

Powered by Google App Engine
This is Rietveld 408576698