Deleted Added
full compact
22c22
< * $FreeBSD: head/sys/cddl/dev/dtrace/amd64/dtrace_subr.c 194850 2009-06-24 16:03:57Z avg $
---
> * $FreeBSD: head/sys/cddl/dev/dtrace/amd64/dtrace_subr.c 195710 2009-07-15 17:07:39Z avg $
368a369
> static uint64_t nsec_scale;
369a371,373
> /* See below for the explanation of this macro. */
> #define SCALE_SHIFT 28
>
403a408
> uint64_t tsc_f;
406d410
< struct pcpu *cp;
407a412,438
> /*
> * Get TSC frequency known at this moment.
> * This should be constant if TSC is invariant.
> * Otherwise tick->time conversion will be inaccurate, but
> * will preserve monotonic property of TSC.
> */
> tsc_f = tsc_freq;
>
> /*
> * The following line checks that nsec_scale calculated below
> * doesn't overflow 32-bit unsigned integer, so that it can multiply
> * another 32-bit integer without overflowing 64-bit.
> * Thus minimum supported TSC frequency is 62.5MHz.
> */
> KASSERT(tsc_f > (NANOSEC >> (32 - SCALE_SHIFT)), ("TSC frequency is too low"));
>
> /*
> * We scale up NANOSEC/tsc_f ratio to preserve as much precision
> * as possible.
> * 2^28 factor was chosen quite arbitrarily from practical
> * considerations:
> * - it supports TSC frequencies as low as 62.5MHz (see above);
> * - it provides quite good precision (e < 0.01%) up to THz
> * (terahertz) values;
> */
> nsec_scale = ((uint64_t)NANOSEC << SCALE_SHIFT) / tsc_f;
>
415c446
< if ((cp = pcpu_find(i)) == NULL)
---
> if (pcpu_find(i) == NULL)
442c473,487
< return ((rdtsc() + tsc_skew[curcpu]) * (int64_t) 1000000000 / tsc_freq);
---
> uint64_t tsc;
> uint32_t lo;
> uint32_t hi;
>
> /*
> * We split TSC value into lower and higher 32-bit halves and separately
> * scale them with nsec_scale, then we scale them down by 2^28
> * (see nsec_scale calculations) taking into account 32-bit shift of
> * the higher half and finally add.
> */
> tsc = rdtsc() + tsc_skew[curcpu];
> lo = tsc;
> hi = tsc >> 32;
> return (((lo * nsec_scale) >> SCALE_SHIFT) +
> ((hi * nsec_scale) << (32 - SCALE_SHIFT)));