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