mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 590422. Stop futzing with our timer scheduling and just schedule them. r=brendan
This commit is contained in:
parent
c98596fdf2
commit
de52194990
@ -8416,12 +8416,11 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
|
||||
TimeStamp deadline;
|
||||
|
||||
if (aTimeout && aTimeout->mWhen > now) {
|
||||
// The OS timer fired early (yikes!), and possibly out of order
|
||||
// too. Set |deadline| to be the time when the OS timer *should*
|
||||
// have fired so that any timers that *should* have fired before
|
||||
// aTimeout *will* be fired now. This happens most of the time on
|
||||
// Win2k.
|
||||
|
||||
// The OS timer fired early (which can happen due to the timers
|
||||
// having lower precision than TimeStamp does). Set |deadline| to
|
||||
// be the time when the OS timer *should* have fired so that any
|
||||
// timers that *should* have fired before aTimeout *will* be fired
|
||||
// now.
|
||||
deadline = aTimeout->mWhen;
|
||||
} else {
|
||||
deadline = now;
|
||||
|
@ -61,9 +61,7 @@ TimerThread::TimerThread() :
|
||||
mCondVar(nsnull),
|
||||
mShutdown(PR_FALSE),
|
||||
mWaiting(PR_FALSE),
|
||||
mSleeping(PR_FALSE),
|
||||
mDelayLineCounter(0),
|
||||
mMinTimerPeriod(0)
|
||||
mSleeping(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
@ -189,60 +187,6 @@ nsresult TimerThread::Shutdown()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Keep track of how early (positive slack) or late (negative slack) timers
|
||||
// are running, and use the filtered slack number to adaptively estimate how
|
||||
// early timers should fire to be "on time".
|
||||
void TimerThread::UpdateFilter(PRUint32 aDelay, TimeStamp aTimeout,
|
||||
TimeStamp aNow)
|
||||
{
|
||||
TimeDuration slack = aTimeout - aNow;
|
||||
double smoothSlack = 0;
|
||||
PRUint32 i, filterLength;
|
||||
static TimeDuration kFilterFeedbackMaxTicks =
|
||||
TimeDuration::FromMilliseconds(FILTER_FEEDBACK_MAX);
|
||||
static TimeDuration kFilterFeedbackMinTicks =
|
||||
TimeDuration::FromMilliseconds(-FILTER_FEEDBACK_MAX);
|
||||
|
||||
if (slack > kFilterFeedbackMaxTicks)
|
||||
slack = kFilterFeedbackMaxTicks;
|
||||
else if (slack < kFilterFeedbackMinTicks)
|
||||
slack = kFilterFeedbackMinTicks;
|
||||
|
||||
mDelayLine[mDelayLineCounter & DELAY_LINE_LENGTH_MASK] =
|
||||
slack.ToMilliseconds();
|
||||
if (++mDelayLineCounter < DELAY_LINE_LENGTH) {
|
||||
// Startup mode: accumulate a full delay line before filtering.
|
||||
PR_ASSERT(mTimeoutAdjustment.ToSeconds() == 0);
|
||||
filterLength = 0;
|
||||
} else {
|
||||
// Past startup: compute number of filter taps based on mMinTimerPeriod.
|
||||
if (mMinTimerPeriod == 0) {
|
||||
mMinTimerPeriod = (aDelay != 0) ? aDelay : 1;
|
||||
} else if (aDelay != 0 && aDelay < mMinTimerPeriod) {
|
||||
mMinTimerPeriod = aDelay;
|
||||
}
|
||||
|
||||
filterLength = (PRUint32) (FILTER_DURATION / mMinTimerPeriod);
|
||||
if (filterLength > DELAY_LINE_LENGTH)
|
||||
filterLength = DELAY_LINE_LENGTH;
|
||||
else if (filterLength < 4)
|
||||
filterLength = 4;
|
||||
|
||||
for (i = 1; i <= filterLength; i++)
|
||||
smoothSlack += mDelayLine[(mDelayLineCounter-i) & DELAY_LINE_LENGTH_MASK];
|
||||
smoothSlack /= filterLength;
|
||||
|
||||
// XXXbe do we need amplification? hacking a fudge factor, need testing...
|
||||
mTimeoutAdjustment = TimeDuration::FromMilliseconds(smoothSlack * 1.5);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_TIMERS
|
||||
PR_LOG(gTimerLog, PR_LOG_DEBUG,
|
||||
("UpdateFilter: smoothSlack = %g, filterLength = %u\n",
|
||||
smoothSlack, filterLength));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* void Run(); */
|
||||
NS_IMETHODIMP TimerThread::Run()
|
||||
{
|
||||
@ -263,7 +207,7 @@ NS_IMETHODIMP TimerThread::Run()
|
||||
if (!mTimers.IsEmpty()) {
|
||||
timer = mTimers[0];
|
||||
|
||||
if (now >= timer->mTimeout + mTimeoutAdjustment) {
|
||||
if (now >= timer->mTimeout) {
|
||||
next:
|
||||
// NB: AddRef before the Release under RemoveTimerInternal to avoid
|
||||
// mRefCnt passing through zero, in case all other refs than the one
|
||||
@ -320,7 +264,7 @@ NS_IMETHODIMP TimerThread::Run()
|
||||
if (!mTimers.IsEmpty()) {
|
||||
timer = mTimers[0];
|
||||
|
||||
TimeStamp timeout = timer->mTimeout + mTimeoutAdjustment;
|
||||
TimeStamp timeout = timer->mTimeout;
|
||||
|
||||
// Don't wait at all (even for PR_INTERVAL_NO_WAIT) if the next timer
|
||||
// is due now or overdue.
|
||||
@ -418,15 +362,7 @@ PRInt32 TimerThread::AddTimerInternal(nsTimerImpl *aTimer)
|
||||
nsTimerImpl *timer = mTimers[i];
|
||||
|
||||
// Don't break till we have skipped any overdue timers.
|
||||
|
||||
// XXXbz why? Given our definition of overdue in terms of
|
||||
// mTimeoutAdjustment, aTimer might be overdue already! Why not
|
||||
// just fire timers in order?
|
||||
|
||||
// XXX does this hold for TYPE_REPEATING_PRECISE? /be
|
||||
|
||||
if (now < timer->mTimeout + mTimeoutAdjustment &&
|
||||
aTimer->mTimeout < timer->mTimeout) {
|
||||
if (now < timer->mTimeout && aTimer->mTimeout < timer->mTimeout) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -471,9 +407,6 @@ void TimerThread::DoAfterSleep()
|
||||
timer->SetDelay(delay);
|
||||
}
|
||||
|
||||
// nuke the stored adjustments, so they get recalibrated
|
||||
mTimeoutAdjustment = TimeDuration(0);
|
||||
mDelayLineCounter = 0;
|
||||
mSleeping = PR_FALSE;
|
||||
}
|
||||
|
||||
|
@ -105,15 +105,6 @@ private:
|
||||
PRPackedBool mSleeping;
|
||||
|
||||
nsTArray<nsTimerImpl*> mTimers;
|
||||
|
||||
#define DELAY_LINE_LENGTH_LOG2 5
|
||||
#define DELAY_LINE_LENGTH_MASK PR_BITMASK(DELAY_LINE_LENGTH_LOG2)
|
||||
#define DELAY_LINE_LENGTH PR_BIT(DELAY_LINE_LENGTH_LOG2)
|
||||
|
||||
PRInt32 mDelayLine[DELAY_LINE_LENGTH]; // milliseconds
|
||||
PRUint32 mDelayLineCounter;
|
||||
PRUint32 mMinTimerPeriod; // milliseconds
|
||||
TimeDuration mTimeoutAdjustment;
|
||||
};
|
||||
|
||||
#endif /* TimerThread_h___ */
|
||||
|
@ -403,8 +403,6 @@ void nsTimerImpl::Fire()
|
||||
// calling Fire().
|
||||
timeout -= TimeDuration::FromMilliseconds(mDelay);
|
||||
}
|
||||
if (gThread)
|
||||
gThread->UpdateFilter(mDelay, timeout, now);
|
||||
|
||||
if (mCallbackType == CALLBACK_TYPE_INTERFACE)
|
||||
mTimerCallbackWhileFiring = mCallback.i;
|
||||
|
Loading…
Reference in New Issue
Block a user