TIMER: Timing updates

- Reliably align clock measurements on tick boundary before measuring.
- Use consistent timebase for time measurements in sim_idle_ms_sleep()

Windows:
- Properly restore system clock tick size on exit.
- Use highest resolution time for ms time measurements
This commit is contained in:
Mark Pizzolato 2018-08-06 19:54:29 -07:00
parent 482b6f1be4
commit 0d9f195f1c

View file

@ -200,23 +200,23 @@ uint32 i, tot, tim;
sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL); sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL);
#if defined(MS_MIN_GRANULARITY) && (MS_MIN_GRANULARITY != 1) #if defined(MS_MIN_GRANULARITY) && (MS_MIN_GRANULARITY != 1)
real_sim_idle_ms_sleep (1); /* Start sampling on a tick boundary */ real_sim_idle_ms_sleep (2); /* Start sampling on a tick boundary */
for (i = 0, tot = 0; i < sleep1Samples; i++) for (i = 0, tot = 0; i < sleep1Samples; i++)
tot += real_sim_idle_ms_sleep (1); tot += real_sim_idle_ms_sleep (1);
tim = tot / sleep1Samples; /* Truncated average */ tim = tot / sleep1Samples; /* Truncated average */
real_sim_os_sleep_min_ms = tim; real_sim_os_sleep_min_ms = tim;
real_sim_idle_ms_sleep (1); /* Start sampling on a tick boundary */ real_sim_idle_ms_sleep (2); /* Start sampling on a tick boundary */
for (i = 0, tot = 0; i < sleep1Samples; i++) for (i = 0, tot = 0; i < sleep1Samples; i++)
tot += real_sim_idle_ms_sleep (real_sim_os_sleep_min_ms + 1); tot += real_sim_idle_ms_sleep (real_sim_os_sleep_min_ms + 1);
tim = tot / sleep1Samples; /* Truncated average */ tim = tot / sleep1Samples; /* Truncated average */
real_sim_os_sleep_inc_ms = tim - real_sim_os_sleep_min_ms; real_sim_os_sleep_inc_ms = tim - real_sim_os_sleep_min_ms;
#endif /* defined(MS_MIN_GRANULARITY) && (MS_MIN_GRANULARITY != 1) */ #endif /* defined(MS_MIN_GRANULARITY) && (MS_MIN_GRANULARITY != 1) */
sim_idle_ms_sleep (1); /* Start sampling on a tick boundary */ sim_idle_ms_sleep (2); /* Start sampling on a tick boundary */
for (i = 0, tot = 0; i < sleep1Samples; i++) for (i = 0, tot = 0; i < sleep1Samples; i++)
tot += sim_idle_ms_sleep (1); tot += sim_idle_ms_sleep (1);
tim = tot / sleep1Samples; /* Truncated average */ tim = tot / sleep1Samples; /* Truncated average */
sim_os_sleep_min_ms = tim; sim_os_sleep_min_ms = tim;
sim_idle_ms_sleep (1); /* Start sampling on a tick boundary */ sim_idle_ms_sleep (2); /* Start sampling on a tick boundary */
for (i = 0, tot = 0; i < sleep1Samples; i++) for (i = 0, tot = 0; i < sleep1Samples; i++)
tot += sim_idle_ms_sleep (sim_os_sleep_min_ms + 1); tot += sim_idle_ms_sleep (sim_os_sleep_min_ms + 1);
tim = tot / sleep1Samples; /* Truncated average */ tim = tot / sleep1Samples; /* Truncated average */
@ -236,29 +236,33 @@ return sim_os_sleep_min_ms;
#if defined(SIM_ASYNCH_IO) #if defined(SIM_ASYNCH_IO)
uint32 sim_idle_ms_sleep (unsigned int msec) uint32 sim_idle_ms_sleep (unsigned int msec)
{ {
uint32 start_time = sim_os_msec(); struct timespec start_time, end_time, done_time, delta_time;
struct timespec done_time; uint32 delta_ms;
t_bool timedout = FALSE; t_bool timedout = FALSE;
clock_gettime(CLOCK_REALTIME, &done_time); clock_gettime(CLOCK_REALTIME, &start_time);
done_time.tv_sec += (msec/1000); end_time = start_time;
done_time.tv_nsec += 1000000*(msec%1000); end_time.tv_sec += (msec/1000);
if (done_time.tv_nsec >= 1000000000) { end_time.tv_nsec += 1000000*(msec%1000);
done_time.tv_sec += done_time.tv_nsec/1000000000; if (end_time.tv_nsec >= 1000000000) {
done_time.tv_nsec = done_time.tv_nsec%1000000000; end_time.tv_sec += end_time.tv_nsec/1000000000;
end_time.tv_nsec = end_time.tv_nsec%1000000000;
} }
pthread_mutex_lock (&sim_asynch_lock); pthread_mutex_lock (&sim_asynch_lock);
sim_idle_wait = TRUE; sim_idle_wait = TRUE;
if (pthread_cond_timedwait (&sim_asynch_wake, &sim_asynch_lock, &done_time)) if (pthread_cond_timedwait (&sim_asynch_wake, &sim_asynch_lock, &end_time))
timedout = TRUE; timedout = TRUE;
else else
sim_asynch_check = 0; /* force check of asynch queue now */ sim_asynch_check = 0; /* force check of asynch queue now */
sim_idle_wait = FALSE; sim_idle_wait = FALSE;
pthread_mutex_unlock (&sim_asynch_lock); pthread_mutex_unlock (&sim_asynch_lock);
clock_gettime(CLOCK_REALTIME, &done_time);
if (!timedout) { if (!timedout) {
AIO_UPDATE_QUEUE; AIO_UPDATE_QUEUE;
} }
return sim_os_msec() - start_time; sim_timespec_diff (&delta_time, &done_time, &start_time);
delta_ms = (uint32)((delta_time.tv_sec * 1000) + (delta_time.tv_nsec / 1000000));
return delta_ms;
} }
#else #else
uint32 sim_idle_ms_sleep (unsigned int msec) uint32 sim_idle_ms_sleep (unsigned int msec)
@ -370,7 +374,6 @@ return quo;
void sim_os_sleep (unsigned int sec) void sim_os_sleep (unsigned int sec)
{ {
sleep (sec); sleep (sec);
return;
} }
uint32 sim_os_ms_sleep_init (void) uint32 sim_os_ms_sleep_init (void)
@ -416,24 +419,26 @@ const t_bool rtc_avail = TRUE;
uint32 sim_os_msec (void) uint32 sim_os_msec (void)
{ {
return timeGetTime (); __int64 nowTime;
GetSystemTimeAsFileTime ((FILETIME *)&nowTime);
return (uint32)(((nowTime + 5000) / 10000) & 0xFFFFFFFF);
} }
void sim_os_sleep (unsigned int sec) void sim_os_sleep (unsigned int sec)
{ {
Sleep (sec * 1000); Sleep (sec * 1000);
return;
} }
static TIMECAPS timers;
void sim_timer_exit (void) void sim_timer_exit (void)
{ {
timeEndPeriod (sim_idle_rate_ms); timeEndPeriod (timers.wPeriodMin);
return;
} }
uint32 sim_os_ms_sleep_init (void) uint32 sim_os_ms_sleep_init (void)
{ {
TIMECAPS timers;
MMRESULT mm_status; MMRESULT mm_status;
mm_status = timeGetDevCaps (&timers, sizeof (timers)); mm_status = timeGetDevCaps (&timers, sizeof (timers));
@ -493,7 +498,6 @@ return 0;
void sim_os_sleep (unsigned int sec) void sim_os_sleep (unsigned int sec)
{ {
return;
} }
uint32 sim_os_ms_sleep_init (void) uint32 sim_os_ms_sleep_init (void)
@ -535,7 +539,6 @@ return (uint32) millis;
void sim_os_sleep (unsigned int sec) void sim_os_sleep (unsigned int sec)
{ {
sleep (sec); sleep (sec);
return;
} }
uint32 sim_os_ms_sleep_init (void) uint32 sim_os_ms_sleep_init (void)
@ -594,7 +597,6 @@ return msec;
void sim_os_sleep (unsigned int sec) void sim_os_sleep (unsigned int sec)
{ {
sleep (sec); sleep (sec);
return;
} }
uint32 sim_os_ms_sleep_init (void) uint32 sim_os_ms_sleep_init (void)
@ -821,7 +823,6 @@ int32 tmr;
for (tmr = 0; tmr <= SIM_NTIMERS; tmr++) for (tmr = 0; tmr <= SIM_NTIMERS; tmr++)
if (rtc_initd[tmr] != 0) if (rtc_initd[tmr] != 0)
sim_rtcn_init (rtc_initd[tmr], tmr); sim_rtcn_init (rtc_initd[tmr], tmr);
return;
} }
int32 sim_rtcn_init (int32 time, int32 tmr) int32 sim_rtcn_init (int32 time, int32 tmr)