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:
parent
482b6f1be4
commit
0d9f195f1c
1 changed files with 25 additions and 24 deletions
49
sim_timer.c
49
sim_timer.c
|
@ -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)
|
||||||
|
|
Loading…
Add table
Reference in a new issue