Hi,
I found another problem in pmie. When using a large sample interval
(where one hour is large, for example), the calculation of sleep time
wraps in pmie, and becomes negative. This snippet of code in pmie::
sleepTight() exhibits the problem:
for (;;) { /* loop to catch early wakeup from sginap */
curr = getReal();
delay = CLK_TCK * (long)(sched - curr);
if (delay < 1) return;
sginap(delay);
Because delay is a long, and CLK_TCK is 1000000, as soon as the delta
between the current time and the next scheduled time goes beyond a
certain size, the multiply-by-CLK_TCK causes a wrap.
When you look at the sginap implementation on non-IRIX platforms, you
can see that all it does is convert back from ticks to seconds right
away, and then calls sleep/usleep.
In fixing this I've taken the approach of using nanosleep(3) instead
of sginap. This is a POSIX-specified high-resolution sleep interface
(exists on all platforms I've checked - IRIX, Linux, MacOSX, Cygwin,
FreeBSD - I think all PCP platforms are covered), which is handy in
that it returns the time remaining if interrupted (which means extra
gettimeofday calls and struct timeval arithmetic isn't needed).
I've added a QA test which mimics the original observed problem, and
verified that its now fixed and that the other pmie tests still pass.
Over time, all sginap/sleep/usleep calls should probably be phased out
in preference for nanosleep(3) - I've only tackled pmie and pmval with
this patch though.
cheers.
--
Nathan
use-nanosleep-not-sginap
Description: Text Data
312-pmie-large-delta
Description: Text Data
|