From 586d767ab6a2ff9900cf043bad5696c983f14fd8 Mon Sep 17 00:00:00 2001 From: curt Date: Sat, 20 Apr 2002 14:52:43 +0000 Subject: [PATCH] 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. --- src/Main/fg_props.cxx | 4 ++-- src/Main/globals.cxx | 2 +- src/Main/globals.hxx | 7 ++++--- src/Main/logger.cxx | 10 +++++----- src/Main/logger.hxx | 2 +- src/Main/main.cxx | 19 ++++++++----------- 6 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/Main/fg_props.cxx b/src/Main/fg_props.cxx index 33f9e2028..152dbae1e 100644 --- a/src/Main/fg_props.cxx +++ b/src/Main/fg_props.cxx @@ -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(); } diff --git a/src/Main/globals.cxx b/src/Main/globals.cxx index b03f7f0a8..44ba968c4 100644 --- a/src/Main/globals.cxx +++ b/src/Main/globals.cxx @@ -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 diff --git a/src/Main/globals.hxx b/src/Main/globals.hxx index 67bea6200..ee8036c88 100644 --- a/src/Main/globals.hxx +++ b/src/Main/globals.hxx @@ -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; } diff --git a/src/Main/logger.cxx b/src/Main/logger.cxx index cef1a46e1..7958300bb 100644 --- a/src/Main/logger.cxx +++ b/src/Main/logger.cxx @@ -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(',') { } diff --git a/src/Main/logger.hxx b/src/Main/logger.hxx index fe2bc7948..2929c421c 100644 --- a/src/Main/logger.hxx +++ b/src/Main/logger.hxx @@ -57,7 +57,7 @@ private: vector nodes; ostream * output; long interval_ms; - long last_time_ms; + double last_time_ms; char delimiter; }; diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 94909df9c..5e758d7d6 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -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() );