pmtimer and nanouptime
Jonas Trollvik
Jonas.Trollvik at telia.com
Tue Jul 20 10:08:10 PDT 2004
Im not familiar with this,
but what if you try to replace this
if (nsec >= 1000000000) {
nsec -= 1000000000;
++tsp->tv_sec;
}
with
while (nsec >= 1000000000) {
nsec -= 1000000000;
++tsp->tv_sec;
}
- Jonas Trollvik
"YONETANI Tomokazu" <qhwt+dragonfly-bugs at xxxxxxxxxx> wrote in message
news:20040720113917.GC14865 at xxxxxxxxxxxxx
> Hello.
> On my PC, getnanotime() starts to return non-normalized value
> (tv_nsec not between 0 and 999999999) after resuming from S3 state.
> This breaks programs relying on the timespec value returned by
> clock_gettime() to be normalized, and libc_r is one of them.
> After inserting printf() in several places, I found the following things:
>
> - getnanotime() returns non-normalized timespec value when
> basetime.tv_nsec is out of range.
>
> - basetime.tv_nsec becomes out of range when pmtimer_resume() calls
> inittodr(0) which calls set_timeofday(), because nanouptime()
> returns non-normalized value.
>
> - nanouptime() returns non-normalized value when it's called from
> set_timeofday() called from pmtimer_resume(), because of overflow
> in multiplication. The following is modified version of nanouptime()
> I'm using to print out each value used in multiplication.
>
> nanouptime(struct timespec *tsp)
> {
> struct globaldata *gd = mycpu;
> int64_t delta, nsec;
> sysclock_t count, base;
>
> do {
> tsp->tv_sec = gd->gd_time_seconds;
> count = cputimer_count();
> base = gd->gd_cpuclock_base;
> delta = count - base;
> } while (tsp->tv_sec != gd->gd_time_seconds);
> nsec = (cputimer_freq64_nsec * delta) >> 32;
> if (nsec >= 1000000000) {
> nsec -= 1000000000;
> ++tsp->tv_sec;
> }
> tsp->tv_nsec = nsec;
> if (nsec < 0 || 1000000000 <= nsec) {
> printf("nanouptime: nsec went negative;"
> "delta: %lld, count: %u, base: %u, freq64_nsec: %lld"
> "\n",
> delta, count, base, cputimer_freq64_nsec);
> }
> }
>
> And it printed out the following message on the console:
> nanouptime: nsec went negative;delta: 8697958, count: 55705685, base:
47007727, freq64_nsec: 3599591090043
>
> Here (cputimer_freq64_nsec * delta) doesn't fit within signed-64bit
> and nsec becomes negative value, bypassing the following conditional.
> I'm not sure what to change to fix this.
More information about the Bugs
mailing list