Bug 618479 part 2. Use binary, not linear, search to determine timer insertion locations. r=brendan

This commit is contained in:
Boris Zbarsky 2013-02-13 10:11:53 -05:00
parent e4fca1d362
commit 5aa03620ad
3 changed files with 40 additions and 19 deletions

View File

@ -417,31 +417,16 @@ int32_t TimerThread::AddTimerInternal(nsTimerImpl *aTimer)
return -1; return -1;
TimeStamp now = TimeStamp::Now(); TimeStamp now = TimeStamp::Now();
uint32_t count = mTimers.Length();
uint32_t i = 0;
for (; i < count; i++) {
nsTimerImpl *timer = mTimers[i];
// Don't break till we have skipped any overdue timers. TimerAdditionComparator c(now, mTimeoutAdjustment, aTimer);
nsTimerImpl** insertSlot = mTimers.InsertElementSorted(aTimer, c);
// XXXbz why? Given our definition of overdue in terms of if (!insertSlot)
// 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) {
break;
}
}
if (!mTimers.InsertElementAt(i, aTimer))
return -1; return -1;
aTimer->mArmed = true; aTimer->mArmed = true;
NS_ADDREF(aTimer); NS_ADDREF(aTimer);
return i; return insertSlot - mTimers.Elements();
} }
bool TimerThread::RemoveTimerInternal(nsTimerImpl *aTimer) bool TimerThread::RemoveTimerInternal(nsTimerImpl *aTimer)

View File

@ -81,4 +81,39 @@ private:
TimeDuration mTimeoutAdjustment; TimeDuration mTimeoutAdjustment;
}; };
struct TimerAdditionComparator {
TimerAdditionComparator(const mozilla::TimeStamp &aNow,
const mozilla::TimeDuration &aTimeoutAdjustment,
nsTimerImpl *aTimerToInsert) :
now(aNow),
timeoutAdjustment(aTimeoutAdjustment)
#ifdef DEBUG
, timerToInsert(aTimerToInsert)
#endif
{}
PRBool LessThan(nsTimerImpl *fromArray, nsTimerImpl *newTimer) const {
NS_ABORT_IF_FALSE(newTimer == timerToInsert, "Unexpected timer ordering");
// Skip 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?
return now >= fromArray->mTimeout + timeoutAdjustment ||
fromArray->mTimeout <= newTimer->mTimeout;
}
PRBool Equals(nsTimerImpl* fromArray, nsTimerImpl* newTimer) const {
return PR_FALSE;
}
private:
const mozilla::TimeStamp &now;
const mozilla::TimeDuration &timeoutAdjustment;
#ifdef DEBUG
const nsTimerImpl * const timerToInsert;
#endif
};
#endif /* TimerThread_h___ */ #endif /* TimerThread_h___ */

View File

@ -52,6 +52,7 @@ public:
static NS_HIDDEN_(void) Shutdown(); static NS_HIDDEN_(void) Shutdown();
friend class TimerThread; friend class TimerThread;
friend class TimerAdditionComparator;
void Fire(); void Fire();
nsresult PostTimerEvent(); nsresult PostTimerEvent();