Switch to fixed-delay scheduling from fixed-rate so our interval being blocked

won't cause multiple calls to calibrate.  Since a fixed-delay Interval can't be
used with a RunQueue, move the calibrate interval onto the Timer's thread and
switch to floats for the drift ratio so synchronization isn't needed around
updating it as a double.



git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@497 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
Charlie Groves
2008-05-20 21:05:46 +00:00
parent 551475ce8d
commit 14dd85bb45
@@ -24,7 +24,6 @@ package com.threerings.media.timer;
import com.samskivert.Log;
import com.samskivert.swing.RuntimeAdjust;
import com.samskivert.util.Interval;
import com.samskivert.util.RunQueue;
import com.threerings.media.MediaPrefs;
/**
@@ -72,12 +71,12 @@ public abstract class CalibratingTimer
_startStamp = _priorCurrent = current();
_driftMilliStamp = System.currentTimeMillis();
_driftTimerStamp = current();
_calibrateInterval = new Interval(RunQueue.AWT) {
_calibrateInterval = new Interval() {
@Override public void expired () {
calibrate();
}
};
_calibrateInterval.schedule(5000, true);
_calibrateInterval.schedule(CALIBRATE_INTERVAL, CALIBRATE_INTERVAL, false);
}
/**
@@ -93,7 +92,7 @@ public abstract class CalibratingTimer
*/
public void clearMaxDriftRatio ()
{
_maxDriftRatio = 1.0;
_maxDriftRatio = 1.0F;
}
/** Returns the difference between _startStamp and current() */
@@ -111,44 +110,48 @@ public abstract class CalibratingTimer
/** Calculates the drift factor from the time elapsed from the last calibrate call. */
protected void calibrate ()
{
long current = current();
double elapsedTimer = (current - _driftTimerStamp);
double elapsedMillis = System.currentTimeMillis() - _driftMilliStamp;
double drift = elapsedMillis / (elapsedTimer / _milliDivider);
long currentTimer = current();
long currentMillis = System.currentTimeMillis();
long elapsedTimer = currentTimer - _driftTimerStamp;
int elapsedMillis = (int)(currentMillis - _driftMilliStamp);
float drift = elapsedMillis / (elapsedTimer / _milliDivider);
if (_debugCalibrate.getValue()) {
Log.warning("Calibrating [timer=" + elapsedTimer + ", millis=" + elapsedMillis
+ ", drift=" + drift + ", timerstamp=" + _driftTimerStamp + ", millistamp="
+ _driftMilliStamp + ", current=" + current + "]");
+ _driftMilliStamp + ", current=" + currentTimer + "]");
}
if (elapsedTimer < 0) {
Log.warning("The timer has decided to live in the past, resetting drift[previousTimer="
+ _driftTimerStamp + ", currentTimer=" + current + ", previousMillis="
+ _driftMilliStamp + ", currentMillis=" + System.currentTimeMillis() + "]");
_driftRatio = 1.0;
+ _driftTimerStamp + ", currentTimer=" + currentTimer + ", previousMillis="
+ _driftMilliStamp + ", currentMillis=" + currentMillis + "]");
_driftRatio = 1.0F;
} else if (drift > MAX_ALLOWED_DRIFT_RATIO || drift < MIN_ALLOWED_DRIFT_RATIO) {
Log.warning("Calibrating [drift=" + drift + "]");
// Keep the drift somewhat sane between .01 and 10
_driftRatio = Math.min(Math.max(.01, drift), 10);
_driftRatio = (float)Math.min(Math.max(.01, drift), 10);
if (Math.abs(drift - 1.0) > Math.abs(_maxDriftRatio - 1.0)) {
_maxDriftRatio = drift;
}
} else if (_driftRatio != 1.0) {
// If we're within bounds now but we weren't before, reset _driftFactor and log it
_driftRatio = 1.0;
_driftRatio = 1.0F;
Log.warning("Calibrating [drift=" + drift + "]");
}
_driftMilliStamp = System.currentTimeMillis();
_driftTimerStamp = current();
_driftMilliStamp = currentMillis;
_driftTimerStamp = currentTimer;
}
/** Return the current value for this timer. */
public abstract long current ();
/** The largest drift ratio we'll allow without correcting. */
protected static final double MAX_ALLOWED_DRIFT_RATIO = 1.1;
protected static final float MAX_ALLOWED_DRIFT_RATIO = 1.1F;
/** The smallest drift ratio we'll allow without correcting. */
protected static final double MIN_ALLOWED_DRIFT_RATIO = 0.9;
protected static final float MIN_ALLOWED_DRIFT_RATIO = 0.9F;
/** Milliseconds between calibrate calls. */
protected static final int CALIBRATE_INTERVAL = 5000;
/** current() value when the timer was started. */
protected long _startStamp;
@@ -169,14 +172,14 @@ public abstract class CalibratingTimer
protected long _driftTimerStamp;
/** Ratio of currentTimeMillis to timer millis. */
protected double _driftRatio = 1.0;
protected float _driftRatio = 1.0F;
/** The largest drift we've had to adjust for. */
protected double _maxDriftRatio = 1.0;
protected float _maxDriftRatio = 1.0F;
/** Interval that fires every five seconds to run the calibration. */
protected Interval _calibrateInterval;
/** A debug hook that toggles dumping of calibration values. */
protected static RuntimeAdjust.BooleanAdjust _debugCalibrate = new RuntimeAdjust.BooleanAdjust(
"Toggles calibrations statistics", "narya.media.timer",