Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Jun 2009 14:07:43 +0300
From:      Andriy Gapon <avg@icyb.net.ua>
To:        Thomas Backman <serenity@exscape.org>
Cc:        John Birrell <jb@freebsd.org>, FreeBSD current <freebsd-current@freebsd.org>
Subject:   Re: DTrace "timestamp" wraps at about 2^33 (64-bit value)?
Message-ID:  <4A3F65FF.7050200@icyb.net.ua>
In-Reply-To: <668B820A-AAA7-4A40-8CF5-7DDCFDCD95FC@exscape.org>
References:  <668B820A-AAA7-4A40-8CF5-7DDCFDCD95FC@exscape.org>

next in thread | previous in thread | raw e-mail | index | archive | help
on 20/06/2009 19:29 Thomas Backman said the following:
> It appears the DTrace "timestamp" variable is wrapping around way, way
> too quickly - it only goes to somewhere slightly above 2^33 (in
> practice, at least), and since it's in nanoseconds, that's not a lot.
> (2^33 ns is less than 10 seconds, actually. 2^64 is 584.55 years, however!)
[snip]
> uint64_t
> dtrace_gethrtime()
> {
>     return ((rdtsc() + tsc_skew[curcpu]) * (int64_t) 1000000000 / tsc_freq);

It appears that (rdtsc() + X) * 10^9 overflows 64-bit value for sufficiently small
values of rdtsc.
BTW, I think it would have been better/clearer to use uint64_t in the cast.

I think that to minimize overflow and sufficiently accurate result a formula like
the following could be used:

x = rdtsc() + tsc_skew[curcpu];
sec = x / tsc_freq;
r = x % tsc_freq;
res = sec * 10^9 + (r * 10^9 / tsc_freq);

I have not tested the formula.
I have suspicions about its accuracy in the edge cases,
esp. if tsc_freq > (2^64 - 1) / 10^9 (not sure if have that in reality).

-- 
Andriy Gapon



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4A3F65FF.7050200>