Skip to content

Commit

Permalink
[Upstream VT 3/n] Ensure ApplyVirtualTimePolicy() is only called with…
Browse files Browse the repository at this point in the history
… VT enabled

Also, do not store initial virtual time and ticks as part of VT
state in MainThreadSchedulerImpl, just pass it to the
AutoAdvancingVirtualTimeDomain instantly.

Change-Id: I613ba103e88b40547431b13565bf1ba3a318b033
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3487334
Reviewed-by: Alexander Timin <altimin@chromium.org>
Commit-Queue: Andrey Kosyakov <caseq@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1001259}
  • Loading branch information
caseq authored and Chromium LUCI CQ committed May 10, 2022
1 parent a199bec commit f125701
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class PLATFORM_EXPORT AutoAdvancingVirtualTimeDomain

int task_starvation_count() const { return task_starvation_count_; }

base::TimeTicks InitialTicks() const { return initial_time_ticks_; }
// TickClock implementation:
base::TimeTicks NowTicks() const override;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1756,17 +1756,15 @@ IdleTimeEstimator* MainThreadSchedulerImpl::GetIdleTimeEstimatorForTesting() {

base::TimeTicks MainThreadSchedulerImpl::EnableVirtualTime(
base::Time initial_time) {
if (main_thread_only().use_virtual_time)
return main_thread_only().initial_virtual_time_ticks;
if (virtual_time_domain_)
return virtual_time_domain_->InitialTicks();
main_thread_only().use_virtual_time = true;
main_thread_only().initial_virtual_time =
initial_time.is_null() ? base::Time::Now() : initial_time;
DCHECK(main_thread_only().initial_virtual_time_ticks.is_null());
main_thread_only().initial_virtual_time_ticks = NowTicks();
if (initial_time.is_null())
initial_time = base::Time::Now();
base::TimeTicks initial_ticks = NowTicks();
DCHECK(!virtual_time_domain_);
virtual_time_domain_ = std::make_unique<AutoAdvancingVirtualTimeDomain>(
main_thread_only().initial_virtual_time,
main_thread_only().initial_virtual_time_ticks, &helper_);
initial_time, initial_ticks, &helper_);
helper_.SetTimeDomain(virtual_time_domain_.get());

DCHECK(!virtual_time_control_task_queue_);
Expand All @@ -1781,12 +1779,10 @@ base::TimeTicks MainThreadSchedulerImpl::EnableVirtualTime(
page_scheduler->OnVirtualTimeEnabled();
}

virtual_time_domain_->SetCanAdvanceVirtualTime(
!main_thread_only().virtual_time_stopped);
DCHECK(!main_thread_only().virtual_time_stopped);
virtual_time_domain_->SetCanAdvanceVirtualTime(true);

if (main_thread_only().virtual_time_stopped)
VirtualTimePaused();
return main_thread_only().initial_virtual_time_ticks;
return initial_ticks;
}

bool MainThreadSchedulerImpl::IsVirtualTimeEnabled() const {
Expand All @@ -1797,13 +1793,9 @@ void MainThreadSchedulerImpl::DisableVirtualTimeForTesting() {
if (!main_thread_only().use_virtual_time)
return;
// Reset virtual time and all tasks queues back to their initial state.
SetVirtualTimeStopped(false);
main_thread_only().use_virtual_time = false;

if (main_thread_only().virtual_time_stopped) {
main_thread_only().virtual_time_stopped = false;
VirtualTimeResumed();
}

ForceUpdatePolicy();
// This can only happen during test tear down, in which case there is no need
// to notify the pages that virtual time was disabled.
Expand All @@ -1812,24 +1804,18 @@ void MainThreadSchedulerImpl::DisableVirtualTimeForTesting() {
virtual_time_control_task_queue_->ShutdownTaskQueue();
virtual_time_control_task_queue_ = nullptr;
virtual_time_domain_.reset();
ApplyVirtualTimePolicy();

main_thread_only().initial_virtual_time = base::Time();
main_thread_only().initial_virtual_time_ticks = base::TimeTicks();

// Reset the MetricsHelper because it gets confused by time going backwards.
base::TimeTicks now = NowTicks();
main_thread_only().metrics_helper.ResetForTest(now);
}

void MainThreadSchedulerImpl::SetVirtualTimeStopped(bool virtual_time_stopped) {
DCHECK(main_thread_only().use_virtual_time);
if (main_thread_only().virtual_time_stopped == virtual_time_stopped)
return;
main_thread_only().virtual_time_stopped = virtual_time_stopped;

if (!main_thread_only().use_virtual_time)
return;

virtual_time_domain_->SetCanAdvanceVirtualTime(!virtual_time_stopped);

if (virtual_time_stopped) {
Expand Down Expand Up @@ -1876,15 +1862,16 @@ void MainThreadSchedulerImpl::GrantVirtualTimeBudget(

base::TimeTicks MainThreadSchedulerImpl::IncrementVirtualTimePauseCount() {
main_thread_only().virtual_time_pause_count++;
ApplyVirtualTimePolicy();

if (main_thread_only().use_virtual_time)
ApplyVirtualTimePolicy();
return NowTicks();
}

void MainThreadSchedulerImpl::DecrementVirtualTimePauseCount() {
main_thread_only().virtual_time_pause_count--;
DCHECK_GE(main_thread_only().virtual_time_pause_count, 0);
ApplyVirtualTimePolicy();
if (main_thread_only().use_virtual_time)
ApplyVirtualTimePolicy();
}

void MainThreadSchedulerImpl::MaybeAdvanceVirtualTime(
Expand All @@ -1900,31 +1887,27 @@ void MainThreadSchedulerImpl::SetVirtualTimePolicy(VirtualTimePolicy policy) {
}

void MainThreadSchedulerImpl::ApplyVirtualTimePolicy() {
DCHECK(main_thread_only().use_virtual_time);
DCHECK(virtual_time_domain_);
switch (main_thread_only().virtual_time_policy) {
case VirtualTimePolicy::kAdvance:
if (virtual_time_domain_) {
virtual_time_domain_->SetMaxVirtualTimeTaskStarvationCount(
main_thread_only().IsInNestedRunloop()
? 0
: main_thread_only().max_virtual_time_task_starvation_count);
virtual_time_domain_->SetVirtualTimeFence(base::TimeTicks());
}
virtual_time_domain_->SetMaxVirtualTimeTaskStarvationCount(
main_thread_only().IsInNestedRunloop()
? 0
: main_thread_only().max_virtual_time_task_starvation_count);
virtual_time_domain_->SetVirtualTimeFence(base::TimeTicks());
SetVirtualTimeStopped(false);
break;
case VirtualTimePolicy::kPause:
if (virtual_time_domain_) {
virtual_time_domain_->SetMaxVirtualTimeTaskStarvationCount(0);
virtual_time_domain_->SetVirtualTimeFence(NowTicks());
}
virtual_time_domain_->SetMaxVirtualTimeTaskStarvationCount(0);
virtual_time_domain_->SetVirtualTimeFence(NowTicks());
SetVirtualTimeStopped(true);
break;
case VirtualTimePolicy::kDeterministicLoading:
if (virtual_time_domain_) {
virtual_time_domain_->SetMaxVirtualTimeTaskStarvationCount(
main_thread_only().IsInNestedRunloop()
? 0
: main_thread_only().max_virtual_time_task_starvation_count);
}
virtual_time_domain_->SetMaxVirtualTimeTaskStarvationCount(
main_thread_only().IsInNestedRunloop()
? 0
: main_thread_only().max_virtual_time_task_starvation_count);

// We pause virtual time while the run loop is nested because that implies
// something modal is happening such as the DevTools debugger pausing the
Expand Down Expand Up @@ -2686,13 +2669,15 @@ TaskQueue::QueuePriority MainThreadSchedulerImpl::ComputePriority(
void MainThreadSchedulerImpl::OnBeginNestedRunLoop() {
DCHECK(!main_thread_only().running_queues.empty());
main_thread_only().nested_runloop_depth++;
ApplyVirtualTimePolicy();
if (main_thread_only().use_virtual_time)
ApplyVirtualTimePolicy();
}

void MainThreadSchedulerImpl::OnExitNestedRunLoop() {
DCHECK(!main_thread_only().running_queues.empty());
main_thread_only().nested_runloop_depth--;
ApplyVirtualTimePolicy();
if (main_thread_only().use_virtual_time)
ApplyVirtualTimePolicy();
}

void MainThreadSchedulerImpl::AddTaskTimeObserver(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -871,8 +871,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
absl::optional<base::sequence_manager::TaskQueue::QueuePriority>,
TracingCategory::kInfo>
task_priority_for_tracing; // Only used for tracing.
base::Time initial_virtual_time;
base::TimeTicks initial_virtual_time_ticks;

VirtualTimePolicy virtual_time_policy;

Expand Down

0 comments on commit f125701

Please sign in to comment.