paranoid clock checking
This commit is contained in:
parent
312e1240f1
commit
0c2864e5ee
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue