paranoid clock checking

This commit is contained in:
David Rose 2001-07-13 16:32:41 +00:00
parent 312e1240f1
commit 0c2864e5ee
6 changed files with 119 additions and 53 deletions

View File

@ -113,47 +113,6 @@ reset() {
set_frame_count(0);
}
////////////////////////////////////////////////////////////////////
// Function: ClockObject::set_real_time
// Access: Published
// Description: Resets the clock to the indicated time. This
// changes only the real time of the clock as reported
// by get_real_time(), but does not immediately change
// the time reported by get_frame_time()--that will
// change after the next call to tick(). Also see
// reset(), set_frame_time(), and set_frame_count().
////////////////////////////////////////////////////////////////////
INLINE void ClockObject::
set_real_time(double time) {
_start_time = _true_clock->get_real_time() - time;
}
////////////////////////////////////////////////////////////////////
// Function: ClockObject::set_frame_time
// Access: Published
// Description: Changes the time as reported for the current frame to
// the indicated time. Normally, the way to adjust the
// frame time is via tick(); this function is provided
// only for occasional special adjustments.
////////////////////////////////////////////////////////////////////
INLINE void ClockObject::
set_frame_time(double time) {
_actual_frame_time = time;
_reported_frame_time = time;
}
////////////////////////////////////////////////////////////////////
// Function: ClockObject::set_frame_count
// Access: Published
// Description: Resets the number of frames counted to the indicated
// number. Also see reset(), set_real_time(), and
// set_frame_time().
////////////////////////////////////////////////////////////////////
INLINE void ClockObject::
set_frame_count(int frame_count) {
_frame_count = frame_count;
}
////////////////////////////////////////////////////////////////////
// Function: ClockObject::get_frame_count
// Access: Published

View File

@ -18,6 +18,7 @@
#include "clockObject.h"
#include "config_express.h"
ClockObject *ClockObject::_global_clock = (ClockObject *)NULL;
@ -39,6 +40,64 @@ ClockObject() {
_max_dt = -1.0;
}
////////////////////////////////////////////////////////////////////
// Function: ClockObject::set_real_time
// Access: Published
// Description: Resets the clock to the indicated time. This
// changes only the real time of the clock as reported
// by get_real_time(), but does not immediately change
// the time reported by get_frame_time()--that will
// change after the next call to tick(). Also see
// reset(), set_frame_time(), and set_frame_count().
////////////////////////////////////////////////////////////////////
void ClockObject::
set_real_time(double time) {
#ifndef NDEBUG
if (this == _global_clock) {
express_cat.warning()
<< "Adjusting global clock's real time by " << time - get_real_time()
<< " seconds.\n";
}
#endif // NDEBUG
_start_time = _true_clock->get_real_time() - time;
}
////////////////////////////////////////////////////////////////////
// Function: ClockObject::set_frame_time
// Access: Published
// Description: Changes the time as reported for the current frame to
// the indicated time. Normally, the way to adjust the
// frame time is via tick(); this function is provided
// only for occasional special adjustments.
////////////////////////////////////////////////////////////////////
void ClockObject::
set_frame_time(double time) {
if (this == _global_clock) {
express_cat.warning()
<< "Adjusting global clock's frame time by " << time - get_frame_time()
<< " seconds.\n";
}
_actual_frame_time = time;
_reported_frame_time = time;
}
////////////////////////////////////////////////////////////////////
// Function: ClockObject::set_frame_count
// Access: Published
// Description: Resets the number of frames counted to the indicated
// number. Also see reset(), set_real_time(), and
// set_frame_time().
////////////////////////////////////////////////////////////////////
void ClockObject::
set_frame_count(int frame_count) {
if (this == _global_clock) {
express_cat.warning()
<< "Adjusting global clock's frame count by "
<< frame_count - get_frame_count() << " frames.\n";
}
_frame_count = frame_count;
}
////////////////////////////////////////////////////////////////////
// Function: ClockObject::tick
// Access: Published

View File

@ -81,9 +81,9 @@ PUBLISHED:
INLINE double get_real_time() const;
INLINE void reset();
INLINE void set_real_time(double time);
INLINE void set_frame_time(double time);
INLINE void set_frame_count(int frame_count);
void set_real_time(double time);
void set_frame_time(double time);
void set_frame_count(int frame_count);
INLINE int get_frame_count() const;
INLINE double get_frame_rate() const;

View File

@ -88,15 +88,15 @@ get_never_destruct() {
// it is available.
bool
get_use_high_res_clock() {
static bool got_use_high_res_clock = false;
static bool use_high_res_clock;
return config_express.GetBool("use-high-res-clock", true);
}
if (!got_use_high_res_clock) {
use_high_res_clock = config_express.GetBool("use-high-res-clock", true);
got_use_high_res_clock = true;
}
return use_high_res_clock;
// Set this to true to double-check the results of the high-resolution
// clock against the system clock. This has no effect if NDEBUG is
// defined.
bool
get_paranoid_clock() {
return config_express.GetBool("paranoid-clock", false);
}
const int patchfile_window_size =

View File

@ -36,6 +36,7 @@ NotifyCategoryDecl(express, EXPCL_PANDAEXPRESS, EXPTP_PANDAEXPRESS);
bool EXPCL_PANDAEXPRESS get_leak_memory();
bool EXPCL_PANDAEXPRESS get_never_destruct();
bool EXPCL_PANDAEXPRESS get_use_high_res_clock();
bool EXPCL_PANDAEXPRESS get_paranoid_clock();
extern const int patchfile_window_size;
extern const int patchfile_increment_size;

View File

@ -21,6 +21,8 @@
#include "config_express.h"
#include "numeric_types.h"
#include "math.h" // for fabs()
TrueClock *TrueClock::_global_ptr = NULL;
#if defined(WIN32_VC)
@ -41,6 +43,7 @@ static BOOL _has_high_res;
static PN_int64 _frequency;
static PN_int64 _init_count;
static long _init_sec;
static bool _paranoid_clock;
void get_true_time_of_day(ulong &sec, ulong &usec) {
struct timeb tb;
@ -55,7 +58,30 @@ get_real_time() const {
LARGE_INTEGER count;
QueryPerformanceCounter(&count);
return (double)(count.QuadPart - _init_count) / (double)_frequency;
double time = (double)(count.QuadPart - _init_count) / (double)_frequency;
#ifndef NDEBUG
if (_paranoid_clock) {
// Now double-check the high-resolution clock against the system
// clock.
struct timeb tb;
ftime(&tb);
double sys_time = (double)(tb.time - _init_sec) + (double)tb.millitm / 1000.0;
if (fabs(time - sys_time) > 0.5) {
// Too much variance!
express_cat.error()
<< "Clock error! High resolution clock reads " << time
<< " while system clock reads " << sys_time << ".\n";
_init_count =
(PN_int64)(count.QuadPart - sys_time * (double)_frequency);
time = (double)(count.QuadPart - _init_count) / (double)_frequency;
express_cat.error()
<< "High resolution clock reset to " << time << ".\n";
}
}
#endif // NDEBUG
return time;
} else {
// No high-resolution clock; return the best information we have.
@ -72,6 +98,8 @@ TrueClock() {
_has_high_res = QueryPerformanceFrequency((LARGE_INTEGER *)&_frequency);
}
_paranoid_clock = get_paranoid_clock();
if (_has_high_res) {
LARGE_INTEGER count;
QueryPerformanceCounter(&count);
@ -93,6 +121,25 @@ TrueClock() {
ftime(&tb);
_init_sec = tb.time;
}
#ifndef NDEBUG
else if (_paranoid_clock) {
express_cat.warning()
<< "Not trusting the high resolution clock." << endl;
struct timeb tb;
ftime(&tb);
_init_sec = tb.time;
// Also set the QueryPerformance counter to exactly match the sys
// time, before we get started.
double sys_time = (double)(tb.time - _init_sec) + (double)tb.millitm / 1000.0;
LARGE_INTEGER count;
QueryPerformanceCounter(&count);
_init_count =
(PN_int64)(count.QuadPart - sys_time * (double)_frequency);
}
#endif
}