1311425 - Make requestIdleCallback aware of timeouts.

Prepare for handling several sources of idleness.

Make idle callbacks aware of nsITimers.

Add pref for how far into the timer queue.

1311425 - Avoid expiration timers when scheduling idle runnables.

review comment fix to ensure low priority timers aren't taken into account when calling NS_GetTimerDeadlineHintOnCurrentThread.
This commit is contained in:
win7-7 2024-04-27 19:21:20 +03:00 committed by wuggy
commit 5499c5f9a3
12 changed files with 188 additions and 60 deletions

View file

@ -8,9 +8,13 @@
#include "mozilla/Maybe.h"
#include "mozilla/Preferences.h"
#include "nsRefreshDriver.h"
#include "nsThreadUtils.h"
#define DEFAULT_LONG_IDLE_PERIOD 50.0f
#define DEFAULT_MIN_IDLE_PERIOD 3.0f
#define DEFAULT_MAX_TIMER_THREAD_BOUND 5
const uint32_t kMaxTimerThreadBoundClamp = 15;
namespace mozilla {
@ -20,19 +24,22 @@ MainThreadIdlePeriod::GetIdlePeriodHint(TimeStamp* aIdleDeadline)
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aIdleDeadline);
Maybe<TimeStamp> deadline = nsRefreshDriver::GetIdleDeadlineHint();
TimeStamp now = TimeStamp::Now();
TimeStamp currentGuess =
now + TimeDuration::FromMilliseconds(GetLongIdlePeriod());
if (deadline.isSome()) {
// If the idle period is too small, then just return a null time
// to indicate we are busy. Otherwise return the actual deadline.
TimeDuration minIdlePeriod =
TimeDuration::FromMilliseconds(GetMinIdlePeriod());
bool busySoon = deadline.value().IsNull() ||
(TimeStamp::Now() >= (deadline.value() - minIdlePeriod));
*aIdleDeadline = busySoon ? TimeStamp() : deadline.value();
} else {
*aIdleDeadline =
TimeStamp::Now() + TimeDuration::FromMilliseconds(GetLongIdlePeriod());
currentGuess = nsRefreshDriver::GetIdleDeadlineHint(currentGuess);
currentGuess = NS_GetTimerDeadlineHintOnCurrentThread(currentGuess, GetMaxTimerThreadBound());
// If the idle period is too small, then just return a null time
// to indicate we are busy. Otherwise return the actual deadline.
TimeDuration minIdlePeriod =
TimeDuration::FromMilliseconds(GetMinIdlePeriod());
bool busySoon = currentGuess.IsNull() ||
(now >= (currentGuess - minIdlePeriod)) ||
currentGuess < mLastIdleDeadline;
if (!busySoon) {
*aIdleDeadline = mLastIdleDeadline = currentGuess;
}
return NS_OK;
@ -72,4 +79,21 @@ MainThreadIdlePeriod::GetMinIdlePeriod()
return sMinIdlePeriod;
}
/* static */ uint32_t
MainThreadIdlePeriod::GetMaxTimerThreadBound()
{
MOZ_ASSERT(NS_IsMainThread());
static uint32_t sMaxTimerThreadBound = DEFAULT_MAX_TIMER_THREAD_BOUND;
static bool sInitialized = false;
if (!sInitialized && Preferences::IsServiceAvailable()) {
sInitialized = true;
Preferences::AddUintVarCache(&sMaxTimerThreadBound, "idle_queue.max_timer_thread_bound",
DEFAULT_MAX_TIMER_THREAD_BOUND);
}
return std::max(sMaxTimerThreadBound, kMaxTimerThreadBoundClamp);
}
} // namespace mozilla