author | Boris Zbarsky <bzbarsky@mit.edu> |
Wed, 13 Feb 2013 10:11:53 -0500 (2013-02-13) | |
changeset 121747 | bffcfc510a9cac94f1a8700e327951a4019cd847 |
parent 121746 | 32b985353206dc8ee08ccf16794c5cbc65656327 |
child 121748 | 04f0afec7a035c8330a241eaffa02ea3707c1058 |
push id | 24307 |
push user | emorley@mozilla.com |
push date | Thu, 14 Feb 2013 10:47:46 +0000 (2013-02-14) |
treeherder | mozilla-central@aceeea086ccb [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | brendan |
bugs | 618479 |
milestone | 21.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/xpcom/threads/TimerThread.cpp +++ b/xpcom/threads/TimerThread.cpp @@ -412,41 +412,26 @@ nsresult TimerThread::RemoveTimer(nsTime // This function must be called from within a lock int32_t TimerThread::AddTimerInternal(nsTimerImpl *aTimer) { if (mShutdown) return -1; 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. - // 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 + TimerAdditionComparator c(now, mTimeoutAdjustment, aTimer); + nsTimerImpl** insertSlot = mTimers.InsertElementSorted(aTimer, c); - if (now < timer->mTimeout + mTimeoutAdjustment && - aTimer->mTimeout < timer->mTimeout) { - break; - } - } - - if (!mTimers.InsertElementAt(i, aTimer)) + if (!insertSlot) return -1; aTimer->mArmed = true; NS_ADDREF(aTimer); - return i; + return insertSlot - mTimers.Elements(); } bool TimerThread::RemoveTimerInternal(nsTimerImpl *aTimer) { if (!mTimers.RemoveElement(aTimer)) return false; ReleaseTimerInternal(aTimer);
--- a/xpcom/threads/TimerThread.h +++ b/xpcom/threads/TimerThread.h @@ -76,9 +76,44 @@ private: #define DELAY_LINE_LENGTH (1u << DELAY_LINE_LENGTH_LOG2) int32_t mDelayLine[DELAY_LINE_LENGTH]; // milliseconds uint32_t mDelayLineCounter; uint32_t mMinTimerPeriod; // milliseconds 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___ */
--- a/xpcom/threads/nsTimerImpl.h +++ b/xpcom/threads/nsTimerImpl.h @@ -47,16 +47,17 @@ public: typedef mozilla::TimeStamp TimeStamp; nsTimerImpl(); static NS_HIDDEN_(nsresult) Startup(); static NS_HIDDEN_(void) Shutdown(); friend class TimerThread; + friend class TimerAdditionComparator; void Fire(); nsresult PostTimerEvent(); void SetDelayInternal(uint32_t aDelay); NS_DECL_ISUPPORTS NS_DECL_NSITIMER