1
0
Fork 0

There was an integer overflow in the way elapsed_time_ms. Because the

SGTimeStamp "-" operator returns it's result in usec's, there is an upper bound of 37.8 minutes on the maximum difference this operator can reliably report
before the math overflows.  I change the global "int elapsed_time_ms" variable
to a "double sim_time_ms" and restructured how the value is calculated.
----
The practical result of the overflow bug is that a large negative dt was
passed to the event manager and the end effect was that no events would
be run until their counters caught up ... in another 37.8 minutes or so.
This commit is contained in:
curt 2002-04-20 14:52:43 +00:00
parent 89324e0cfe
commit 586d767ab6
6 changed files with 21 additions and 23 deletions

View file

@ -264,10 +264,10 @@ setAircraftDir (const char * dir)
/**
* Return the number of milliseconds elapsed since simulation started.
*/
static long
static double
getElapsedTime_ms ()
{
return globals->get_elapsed_time_ms();
return globals->get_sim_time_ms();
}

View file

@ -42,7 +42,7 @@ FGGlobals *globals;
// Constructor
FGGlobals::FGGlobals() :
elapsed_time_ms(0L),
sim_time_ms(0.0),
#if defined(FX) && defined(XMESA)
fullscreen( true ),
#endif

View file

@ -80,7 +80,7 @@ class FGGlobals
private:
// Number of milliseconds elapsed since the start of the program.
long elapsed_time_ms;
double sim_time_ms;
// Root of FlightGear data tree
string fg_root;
@ -174,8 +174,9 @@ public:
FGGlobals();
~FGGlobals();
inline long get_elapsed_time_ms () const { return elapsed_time_ms; }
inline void set_elapsed_time_ms (long t) { elapsed_time_ms = t; }
inline double get_sim_time_ms () const { return sim_time_ms; }
inline void inc_sim_time_ms (double dt) { sim_time_ms += dt; }
inline void set_sim_time_ms (double t) { sim_time_ms = t; }
inline const string &get_fg_root () const { return fg_root; }
inline void set_fg_root (const string &root) { fg_root = root; }

View file

@ -79,11 +79,11 @@ FGLogger::unbind ()
void
FGLogger::update (int dt)
{
long elapsed_ms = globals->get_elapsed_time_ms();
double sim_time_ms = globals->get_sim_time_ms();
for (unsigned int i = 0; i < _logs.size(); i++) {
if ((elapsed_ms - _logs[i].last_time_ms) >= _logs[i].interval_ms) {
_logs[i].last_time_ms = elapsed_ms;
(*_logs[i].output) << globals->get_elapsed_time_ms();
if ((sim_time_ms - _logs[i].last_time_ms) >= _logs[i].interval_ms) {
_logs[i].last_time_ms = sim_time_ms;
(*_logs[i].output) << globals->get_sim_time_ms();
for (unsigned int j = 0; j < _logs[i].nodes.size(); j++) {
(*_logs[i].output) << _logs[i].delimiter
<< _logs[i].nodes[j]->getStringValue();
@ -102,7 +102,7 @@ FGLogger::update (int dt)
FGLogger::Log::Log ()
: output(0),
interval_ms(0),
last_time_ms(-999999L),
last_time_ms(-999999.0),
delimiter(',')
{
}

View file

@ -57,7 +57,7 @@ private:
vector<SGPropertyNode *> nodes;
ostream * output;
long interval_ms;
long last_time_ms;
double last_time_ms;
char delimiter;
};

View file

@ -241,7 +241,7 @@ ssgSimpleState *default_state;
ssgSimpleState *hud_and_panel;
ssgSimpleState *menus;
SGTimeStamp start_time_stamp;
SGTimeStamp last_time_stamp;
SGTimeStamp current_time_stamp;
void fgBuildRenderStates( void ) {
@ -393,10 +393,11 @@ void trRenderFrame( void ) {
// Update all Visuals (redraws anything graphics related)
void fgRenderFrame( void ) {
static long old_elapsed_ms = 0;
int dt_ms = int(globals->get_elapsed_time_ms() - old_elapsed_ms);
old_elapsed_ms = globals->get_elapsed_time_ms();
// Update the elapsed time.
current_time_stamp.stamp();
int dt_ms = (current_time_stamp - last_time_stamp) / 1000L;
globals->inc_sim_time_ms( dt_ms );
last_time_stamp = current_time_stamp;
// Process/manage pending events
global_events.update( dt_ms );
@ -440,17 +441,13 @@ void fgRenderFrame( void ) {
if ( fgGetBool("/sim/startup/splash-screen") ) {
fgSplashUpdate(0.0);
}
start_time_stamp.stamp(); // Keep resetting the start time
// Keep resetting sim time while the sim is initializing
globals->set_sim_time_ms( 0.0 );
} else {
// idle_state is now 1000 meaning we've finished all our
// initializations and are running the main loop, so this will
// now work without seg faulting the system.
// Update the elapsed time.
current_time_stamp.stamp();
globals->set_elapsed_time_ms( (current_time_stamp - start_time_stamp)
/ 1000L );
// calculate our current position in cartesian space
scenery.set_center( scenery.get_next_center() );