Re: [RFC/RFT] calloutng

From: Oliver Pinter <oliver.pntr_at_gmail.com>
Date: Sat, 15 Dec 2012 11:52:38 +0100
On 12/15/12, Bruce Evans <brde_at_optusnet.com.au> wrote:
> On Fri, 14 Dec 2012, Oliver Pinter wrote:
>
>> 635 -       return tticks;
>> 636 +       getbinuptime(&pbt);
>> 637 +       bt.sec = data / 1000;
>> 638 +       bt.frac = (data % 1000) * (uint64_t)1844674407309000LL;
>> 639 +       bintime_add(&bt, &pbt);
>> 640 +       return bt;
>
> Style bugs: missing spaces around return value in new and old code.
>
>> 641  }
>>
>> What is this 1844674407309000LL constant?
>
> This is
>
>      2**64 / 10**6 * 10**3
>
> obfuscated by printing it in hex and doing the scaling by powers of
> 10 manually, and then giving it a bogus type using the abominable long
> long misfeature.  I try to kill this obfuscation and the abimination
> whenever I see them.  In sys/time.h, this resulted in a related binary
> conversion using a scale factor of
>
>      ((uint64_t)1 << 63) / (1000000000 >> 1).
>
> Here the power of 2 term is 2**63.   2**64 cannot be used since it exceeds
> uintmax_t.  The power of 10 term is 10**9.  This is divided by 2 to
> compensate for dividing 2**64 by 2.  The abomination is avoided by using
> smaller literal values and expandling them to 64-bit values using shifts.
>
> Long long suffixes on literal constants are only needed to support C90
> compilers with the long long extension on 32-bit systems anyway.
> Otherwise, C90+extension compilers will warn about literal constants
> larger than ULONG_MAX (which can only occur on 32-bit systems).  Since
> C99 is now the default, the warnings would only without LL in the above
> if you use nonstandard CFLAGS.
>
> The above has to convert from the bad units of milliseconds to the bloated
> units of bintimes, and it is less refined than most other bintime
> conversions.  I think that since it doesn't try to be optimal, it should
> just use the standard bintime conversions after first converting
> milliseconds to a timeval.  It already does essentially that with its
> divisions by 1000:
>
>  	struct timeval tv;
>
>  	tv.tv_sec = data / 1000;
>  	tv.tv_usec = data % 1000 * 1000;
>  	timeval2bintime(&tv, &bt);
>
> The compliler will probably optimize /1000 and %1000 to shifts in both
> this and the above.  Then timeval2bintime() does the almost the same
> multiplication as above, but spelled differently accuracy.  Both give
> unnecessary inaccuracy in the conversion to weenieseconds: the first
> gives:
>
>  	bt.frac = data % 1000 * (2**64 / 10**6 * 10**3);
>
> the second gives:
>
>  	bt.frac = data % 1000 * 1000 * (2**64 / 10**6);
>
> Because of the different grouping of the multiplications, the second
> is unfortunately slower (1 more multiplication that cannot be done at
> compile time).  The second also gives unnecessary (but findamental to
> the method) inaccuracy by pulling out the factor of 1000.  The first
> gives the same inaccuracy, and now it is because the constant is not
> correctly rounded.  It should be
>
>  	2.0**64 / 10**3 = 1844674407309551.616 (exactly)
>  	                = 1844674407309552     (rounded to nearest int)
>
> but is actually rounded down to a multiple of 1000.
>
> It would be better to round the scale factors so that the conversions
> are inverses of each other and tticks can be recovered from bt, but
> this is impossible.  I tried to make the bintime conversions invert
> most values correctly by rounding to nearest, but phk didn't like this
> and the result is the bogus comment about always rounding down in time.h.
> So when you start with 999 msec in tticks, the resulting bt will be
> rounded down a little and converting back will give 998 msec; the
> next round of conversions will reduce 1 more, and so on until you
> reach a value that is exactly representable in both milliseconds and
> weenieseconds (875?).  This despite weenieseconds providing vastly
> more accuracy than can be measured and vastly more accuracy than needed
> to represent all other time values in the kernel in a unique way.  Just
> not in a unique way that is expressible using simple scaling conversions.
> The conversions that give uniqueness can still be monotonic, but can't
> be nonlinear in the same way that simple scaling gives.

Thanks for the detailed answer. :)

>
> Bruce
>
Received on Sat Dec 15 2012 - 09:52:40 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:33 UTC