Backing out rev b567a93a5086 (bug 558306) to fix test orange

This commit is contained in:
Boris Zbarsky 2010-07-15 13:49:28 -04:00
Родитель 389207f85b
Коммит 1d79cd4137
4 изменённых файлов: 83 добавлений и 72 удалений

Просмотреть файл

@ -50,8 +50,6 @@
#include "nsIProxyObjectManager.h"
#include "mozilla/Services.h"
#include <math.h>
NS_IMPL_THREADSAFE_ISUPPORTS2(TimerThread, nsIRunnable, nsIObserver)
TimerThread::TimerThread() :
@ -63,7 +61,8 @@ TimerThread::TimerThread() :
mWaiting(PR_FALSE),
mSleeping(PR_FALSE),
mDelayLineCounter(0),
mMinTimerPeriod(0)
mMinTimerPeriod(0),
mTimeoutAdjustment(0)
{
}
@ -192,27 +191,26 @@ nsresult TimerThread::Shutdown()
// 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)
void TimerThread::UpdateFilter(PRUint32 aDelay, PRIntervalTime aTimeout,
PRIntervalTime aNow)
{
TimeDuration slack = aTimeout - aNow;
PRInt32 slack = (PRInt32) (aTimeout - aNow);
double smoothSlack = 0;
PRUint32 i, filterLength;
static TimeDuration kFilterFeedbackMaxTicks =
TimeDuration::FromMilliseconds(FILTER_FEEDBACK_MAX);
static TimeDuration kFilterFeedbackMinTicks =
TimeDuration::FromMilliseconds(-FILTER_FEEDBACK_MAX);
static PRIntervalTime kFilterFeedbackMaxTicks =
PR_MillisecondsToInterval(FILTER_FEEDBACK_MAX);
if (slack > kFilterFeedbackMaxTicks)
slack = kFilterFeedbackMaxTicks;
else if (slack < kFilterFeedbackMinTicks)
slack = kFilterFeedbackMinTicks;
mDelayLine[mDelayLineCounter & DELAY_LINE_LENGTH_MASK] =
slack.ToMilliseconds();
if (slack > 0) {
if (slack > (PRInt32)kFilterFeedbackMaxTicks)
slack = kFilterFeedbackMaxTicks;
} else {
if (slack < -(PRInt32)kFilterFeedbackMaxTicks)
slack = -(PRInt32)kFilterFeedbackMaxTicks;
}
mDelayLine[mDelayLineCounter & DELAY_LINE_LENGTH_MASK] = slack;
if (++mDelayLineCounter < DELAY_LINE_LENGTH) {
// Startup mode: accumulate a full delay line before filtering.
PR_ASSERT(mTimeoutAdjustment.ToSeconds() == 0);
PR_ASSERT(mTimeoutAdjustment == 0);
filterLength = 0;
} else {
// Past startup: compute number of filter taps based on mMinTimerPeriod.
@ -233,7 +231,7 @@ void TimerThread::UpdateFilter(PRUint32 aDelay, TimeStamp aTimeout,
smoothSlack /= filterLength;
// XXXbe do we need amplification? hacking a fudge factor, need testing...
mTimeoutAdjustment = TimeDuration::FromMilliseconds(smoothSlack * 1.5);
mTimeoutAdjustment = (PRInt32) (smoothSlack * 1.5);
}
#ifdef DEBUG_TIMERS
@ -249,7 +247,6 @@ NS_IMETHODIMP TimerThread::Run()
nsAutoLock lock(mLock);
while (!mShutdown) {
// Have to use PRIntervalTime here, since PR_WaitCondVar takes it
PRIntervalTime waitFor;
if (mSleeping) {
@ -257,13 +254,13 @@ NS_IMETHODIMP TimerThread::Run()
waitFor = PR_MillisecondsToInterval(100);
} else {
waitFor = PR_INTERVAL_NO_TIMEOUT;
TimeStamp now = TimeStamp::Now();
PRIntervalTime now = PR_IntervalNow();
nsTimerImpl *timer = nsnull;
if (!mTimers.IsEmpty()) {
timer = mTimers[0];
if (now >= timer->mTimeout + mTimeoutAdjustment) {
if (!TIMER_LESS_THAN(now, timer->mTimeout + mTimeoutAdjustment)) {
next:
// NB: AddRef before the Release under RemoveTimerInternal to avoid
// mRefCnt passing through zero, in case all other refs than the one
@ -281,7 +278,10 @@ NS_IMETHODIMP TimerThread::Run()
if (PR_LOG_TEST(gTimerLog, PR_LOG_DEBUG)) {
PR_LOG(gTimerLog, PR_LOG_DEBUG,
("Timer thread woke up %dms from when it was supposed to\n",
PRInt32(fabs((now - timer->mTimeout).ToMilliseconds()))));
(now >= timer->mTimeout)
? PR_IntervalToMilliseconds(now - timer->mTimeout)
: -(PRInt32)PR_IntervalToMilliseconds(timer->mTimeout-now))
);
}
#endif
@ -313,20 +313,20 @@ NS_IMETHODIMP TimerThread::Run()
// Update now, as PostTimerEvent plus the locking may have taken a
// tick or two, and we may goto next below.
now = TimeStamp::Now();
now = PR_IntervalNow();
}
}
if (!mTimers.IsEmpty()) {
timer = mTimers[0];
TimeStamp timeout = timer->mTimeout + mTimeoutAdjustment;
PRIntervalTime timeout = timer->mTimeout + mTimeoutAdjustment;
// Don't wait at all (even for PR_INTERVAL_NO_WAIT) if the next timer
// is due now or overdue.
if (now >= timeout)
if (!TIMER_LESS_THAN(now, timeout))
goto next;
waitFor = PR_MillisecondsToInterval((timeout - now).ToMilliseconds());
waitFor = timeout - now;
}
#ifdef DEBUG_TIMERS
@ -411,22 +411,23 @@ PRInt32 TimerThread::AddTimerInternal(nsTimerImpl *aTimer)
if (mShutdown)
return -1;
TimeStamp now = TimeStamp::Now();
PRIntervalTime now = PR_IntervalNow();
PRUint32 count = mTimers.Length();
PRUint32 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?
// Don't break till we have skipped any overdue timers. Do not include
// mTimeoutAdjustment here, because we are really trying to avoid calling
// TIMER_LESS_THAN(t, u), where the t is now + DELAY_INTERVAL_MAX, u is
// now - overdue, and DELAY_INTERVAL_MAX + overdue > DELAY_INTERVAL_LIMIT.
// In other words, we want to use now-based time, now adjusted time, even
// though "overdue" ultimately depends on adjusted time.
// XXX does this hold for TYPE_REPEATING_PRECISE? /be
if (now < timer->mTimeout + mTimeoutAdjustment &&
aTimer->mTimeout < timer->mTimeout) {
if (TIMER_LESS_THAN(now, timer->mTimeout) &&
TIMER_LESS_THAN(aTimer->mTimeout, timer->mTimeout)) {
break;
}
}
@ -472,7 +473,7 @@ void TimerThread::DoAfterSleep()
}
// nuke the stored adjustments, so they get recalibrated
mTimeoutAdjustment = TimeDuration(0);
mTimeoutAdjustment = 0;
mDelayLineCounter = 0;
mSleeping = PR_FALSE;
}

Просмотреть файл

@ -50,16 +50,13 @@
#include "nsTArray.h"
#include "prcvar.h"
#include "mozilla/TimeStamp.h"
#include "prinrval.h"
#include "prlock.h"
class TimerThread : public nsIRunnable,
public nsIObserver
{
public:
typedef mozilla::TimeStamp TimeStamp;
typedef mozilla::TimeDuration TimeDuration;
TimerThread();
NS_HIDDEN_(nsresult) InitLocks();
@ -77,8 +74,8 @@ public:
#define FILTER_DURATION 1e3 /* one second */
#define FILTER_FEEDBACK_MAX 100 /* 1/10th of a second */
void UpdateFilter(PRUint32 aDelay, TimeStamp aTimeout,
TimeStamp aNow);
void UpdateFilter(PRUint32 aDelay, PRIntervalTime aTimeout,
PRIntervalTime aNow);
void DoBeforeSleep();
void DoAfterSleep();
@ -110,10 +107,10 @@ private:
#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
PRInt32 mDelayLine[DELAY_LINE_LENGTH];
PRUint32 mDelayLineCounter;
PRUint32 mMinTimerPeriod; // milliseconds
TimeDuration mTimeoutAdjustment;
PRInt32 mTimeoutAdjustment;
};
#endif /* TimerThread_h___ */

Просмотреть файл

@ -46,9 +46,6 @@
#include "nsThreadUtils.h"
#include "prmem.h"
using mozilla::TimeDuration;
using mozilla::TimeStamp;
static PRInt32 gGenerator = 0;
static TimerThread* gThread = nsnull;
@ -145,12 +142,18 @@ nsTimerImpl::nsTimerImpl() :
mArmed(PR_FALSE),
mCanceled(PR_FALSE),
mGeneration(0),
mDelay(0)
mDelay(0),
mTimeout(0)
{
// XXXbsmedberg: shouldn't this be in Init()?
mEventTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
mCallback.c = nsnull;
#ifdef DEBUG_TIMERS
mStart = 0;
mStart2 = 0;
#endif
}
nsTimerImpl::~nsTimerImpl()
@ -298,8 +301,8 @@ NS_IMETHODIMP nsTimerImpl::SetDelay(PRUint32 aDelay)
// If we're already repeating precisely, update mTimeout now so that the
// new delay takes effect in the future.
if (!mTimeout.IsNull() && mType == TYPE_REPEATING_PRECISE)
mTimeout = TimeStamp::Now();
if (mTimeout != 0 && mType == TYPE_REPEATING_PRECISE)
mTimeout = PR_IntervalNow();
SetDelayInternal(aDelay);
@ -376,32 +379,31 @@ void nsTimerImpl::Fire()
if (mCanceled)
return;
TimeStamp now = TimeStamp::Now();
PRIntervalTime now = PR_IntervalNow();
#ifdef DEBUG_TIMERS
if (PR_LOG_TEST(gTimerLog, PR_LOG_DEBUG)) {
TimeDuration a = now - mStart; // actual delay in intervals
TimeDuration b = TimeDuration::FromMilliseconds(mDelay); // expected delay in intervals
TimeDuration delta = (a > b) ? a - b : b - a;
PRUint32 d = delta.ToMilliseconds(); // delta in ms
PRIntervalTime a = now - mStart; // actual delay in intervals
PRUint32 b = PR_MillisecondsToInterval(mDelay); // expected delay in intervals
PRUint32 d = PR_IntervalToMilliseconds((a > b) ? a - b : b - a); // delta in ms
sDeltaSum += d;
sDeltaSumSquared += double(d) * double(d);
sDeltaNum++;
PR_LOG(gTimerLog, PR_LOG_DEBUG, ("[this=%p] expected delay time %4dms\n", this, mDelay));
PR_LOG(gTimerLog, PR_LOG_DEBUG, ("[this=%p] actual delay time %4dms\n", this, PRInt32(a.ToMilliseconds())));
PR_LOG(gTimerLog, PR_LOG_DEBUG, ("[this=%p] actual delay time %4dms\n", this, PR_IntervalToMilliseconds(a)));
PR_LOG(gTimerLog, PR_LOG_DEBUG, ("[this=%p] (mType is %d) -------\n", this, mType));
PR_LOG(gTimerLog, PR_LOG_DEBUG, ("[this=%p] delta %4dms\n", this, (a > b) ? (PRInt32)d : -(PRInt32)d));
mStart = mStart2;
mStart2 = TimeStamp::TimeStamp();
mStart2 = 0;
}
#endif
TimeStamp timeout = mTimeout;
PRIntervalTime timeout = mTimeout;
if (mType == TYPE_REPEATING_PRECISE) {
// Precise repeating timers advance mTimeout by mDelay without fail before
// calling Fire().
timeout -= TimeDuration::FromMilliseconds(mDelay);
timeout -= PR_MillisecondsToInterval(mDelay);
}
if (gThread)
gThread->UpdateFilter(mDelay, timeout, now);
@ -456,7 +458,7 @@ void nsTimerImpl::Fire()
if (PR_LOG_TEST(gTimerLog, PR_LOG_DEBUG)) {
PR_LOG(gTimerLog, PR_LOG_DEBUG,
("[this=%p] Took %dms to fire timer callback\n",
this, (TimeStamp::Now() - now).ToMilliseconds()));
this, PR_IntervalToMilliseconds(PR_IntervalNow() - now)));
}
#endif
@ -481,7 +483,7 @@ public:
}
#ifdef DEBUG_TIMERS
TimeStamp mInitTime;
PRIntervalTime mInitTime;
#endif
private:
@ -507,10 +509,10 @@ NS_IMETHODIMP nsTimerEvent::Run()
#ifdef DEBUG_TIMERS
if (PR_LOG_TEST(gTimerLog, PR_LOG_DEBUG)) {
TimeStamp now = TimeStamp::Now();
PRIntervalTime now = PR_IntervalNow();
PR_LOG(gTimerLog, PR_LOG_DEBUG,
("[this=%p] time between PostTimerEvent() and Fire(): %dms\n",
this, (now - mInitTime).ToMilliseconds()));
this, PR_IntervalToMilliseconds(now - mInitTime)));
}
#endif
@ -534,7 +536,7 @@ nsresult nsTimerImpl::PostTimerEvent()
#ifdef DEBUG_TIMERS
if (PR_LOG_TEST(gTimerLog, PR_LOG_DEBUG)) {
event->mInitTime = TimeStamp::Now();
event->mInitTime = PR_IntervalNow();
}
#endif
@ -557,19 +559,23 @@ nsresult nsTimerImpl::PostTimerEvent()
void nsTimerImpl::SetDelayInternal(PRUint32 aDelay)
{
TimeDuration delayInterval = TimeDuration::FromMilliseconds(aDelay);
PRIntervalTime delayInterval = PR_MillisecondsToInterval(aDelay);
if (delayInterval > DELAY_INTERVAL_MAX) {
delayInterval = DELAY_INTERVAL_MAX;
aDelay = PR_IntervalToMilliseconds(delayInterval);
}
mDelay = aDelay;
TimeStamp now = TimeStamp::Now();
if (mTimeout.IsNull() || mType != TYPE_REPEATING_PRECISE)
PRIntervalTime now = PR_IntervalNow();
if (mTimeout == 0 || mType != TYPE_REPEATING_PRECISE)
mTimeout = now;
mTimeout += delayInterval;
#ifdef DEBUG_TIMERS
if (PR_LOG_TEST(gTimerLog, PR_LOG_DEBUG)) {
if (mStart.IsNull())
if (mStart == 0)
mStart = now;
else
mStart2 = now;

Просмотреть файл

@ -50,7 +50,6 @@
#include "nsCOMPtr.h"
#include "prlog.h"
#include "mozilla/TimeStamp.h"
#if defined(PR_LOGGING)
static PRLogModuleInfo *gTimerLog = PR_NewLogModule("nsTimerImpl");
@ -75,10 +74,18 @@ enum {
CALLBACK_TYPE_OBSERVER = 3
};
// Two timer deadlines must differ by less than half the PRIntervalTime domain.
#define DELAY_INTERVAL_LIMIT PR_BIT(8 * sizeof(PRIntervalTime) - 1)
// Maximum possible delay (XXX rework to use ms rather than interval ticks).
#define DELAY_INTERVAL_MAX (DELAY_INTERVAL_LIMIT - 1)
// Is interval-time t less than u, even if t has wrapped PRIntervalTime?
#define TIMER_LESS_THAN(t, u) ((t) - (u) > DELAY_INTERVAL_LIMIT)
class nsTimerImpl : public nsITimer
{
public:
typedef mozilla::TimeStamp TimeStamp;
nsTimerImpl();
@ -150,10 +157,10 @@ private:
PRInt32 mGeneration;
PRUint32 mDelay;
TimeStamp mTimeout;
PRIntervalTime mTimeout;
#ifdef DEBUG_TIMERS
TimeStamp mStart, mStart2;
PRIntervalTime mStart, mStart2;
static double sDeltaSum;
static double sDeltaSumSquared;
static double sDeltaNum;