microuptime change between 4.7 and 4.8-RELEASE

Toshiaki Takada toshiaki at ipinfusion.com
Thu May 22 19:01:22 PDT 2003


Recently, I got below message on 4.7-RELEASE:

  microuptime() went backwards (10202511.496740 -> 10202511.-694845498)

Looking through FreeBSD kernel source code, it seems the
warning comes from mi_switch() @ kern_synch.c.

I also checked mailing list archive to solve this problem,
then most of people says enabling APM might cause problem,
so apm should be removed from kernel configuration file.

But even though apm is disabled in our configuration file,
I can still see the same message.

Checking 4.8-RELEASE kernel source code, microupdate()
function seems to be changed between 4.7 and 4.8.
According to CVS, it has changed from to  It looks like something has been fixed.

Below is the function from 4.8-RELEASE.

619 void
620 microuptime(struct timeval *tv)
622 {
623         struct timecounter *tc;
625         tc = timecounter;
626         tv->tv_sec = tc->tc_offset_sec;
627         tv->tv_usec = tc->tc_offset_micro;
628         tv->tv_usec += ((u_int64_t)tco_delta(tc) * tc->tc_scale_micro) >> 32;
629         while (tv->tv_usec < 0) {
630                 tv->tv_usec += 1000000;
631                 if (tv->tv_sec > 0)
632                         tv->tv_sec--;
633         }
634         while (tv->tv_usec >= 1000000) {
635                 tv->tv_usec -= 1000000;
636                 tv->tv_sec++;
637         }
638 }

I have a couple of quesitons about this function.  Actually,
I'm not so familiar with FreeBSD kernel code, so please
correct me if I am wrong.

1) At right side of formula in line 628, "tco_delta(tc) *
   tc->tc_scale_micro" is casted to (u_int64_t), then shift
   32 bits to right.

   My question is, is it possible that the result of
   "tco_delta(tc) * tc->tc_scale_micro" has more than
   0x8000000000000000 ?

   If YES, the value will be shifted and added into
   tv->tv_usec.  However tv_usec is defined as signed long,
   so tv_usec will have negative value as a result.

   Actually, I'm not sure what kind of value tco_delta(tc)
   or tc->tc_scale_micro can have, however these two values
   should have unsigned value, so I guess logically it is
   possible to have a value more than 0x8000000000000000.

2) Line 629 through 633 were added in 4.8-RELEASE.

   Because of 1), tv_usec may have negative value, I guess
   those 5 lines was added in order to avoid the negative

   However, if right side of formula in 628 should have
   always positive value, is it OK to decrement tv_sec in
   line 632?

Actually, I've got the same warning with 4.8-RELEASE.
See below:

  microuptime() went backwards (2155766.705136 -> 2155071.302722)

tv_usec doesn't have negative value, while tv_sec goes
backwards about 695 secs.  This is because the changes has
been made in microuptime() function.  It seems the original
value of timeval was almost same as first warning.

And also, I looked through mailing list, in most of cases,
tv_usec of new time has around -695000000.

Is there any possible reason?
please kindly clarify those questions.


-- Toshiaki Takada

More information about the freebsd-questions mailing list