Cygwin: timerfd: fix overrun computation

- Drop erroneous initial computation of overrun count in settime
  for absolute non-realtime clocks.  It's repeated in thread_func
  and thus counted twice.

- Fix overrun computation for timestamp offsets being a multiple of
  the timer interval.  The timestamp has to be corrected after the
  first offset, otherwise the correction loop counts the intervals
  again.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2019-01-21 11:14:16 +01:00
parent 6ed50a68a1
commit ea99e9fdda
1 changed files with 11 additions and 10 deletions

View File

@ -155,13 +155,18 @@ timerfd_tracker::thread_func ()
/* Make concessions for unexact realtime clock */
if (ts > now)
ts = now - 1;
increment_overrun_count ((now - ts + get_interval () - 1)
/ get_interval ());
LONG64 ov_cnt = (now - ts + get_interval () - 1)
/ get_interval ();
increment_overrun_count (ov_cnt);
ts += get_interval () * ov_cnt;
/* Set exp_ts to current timestamp. Make sure exp_ts ends up
bigger than "now" and fix overrun count as required */
while ((ts += get_interval ()) <= (now = get_clock_now ()))
increment_overrun_count ((now - ts + get_interval () - 1)
/ get_interval ());
while (ts <= (now = get_clock_now ()))
{
increment_overrun_count ((now - ts + get_interval () - 1)
/ get_interval ());
ts += get_interval ();
}
set_exp_ts (ts);
/* NtSetTimer allows periods of up to 24 days only. If the time
is longer, we set the timer up as one-shot timer for each
@ -536,11 +541,7 @@ timerfd_shared::arm_timer (int flags, const struct itimerspec *new_value)
/* If the timestamp was earlier than now, compute number
of overruns and offset DueTime to expire immediately. */
if (DueTime.QuadPart >= 0)
{
LONG64 num_intervals = DueTime.QuadPart / _interval;
increment_overrun_count (num_intervals);
DueTime.QuadPart = -1LL;
}
DueTime.QuadPart = -1LL;
}
}
else