On Sun, Aug 09, 2020 at 09:46:00PM +0100, Julian Smith wrote:

> I've just used adjfreq() directly to correct my hardware clock, which
> was running an hour ahead of UTC (due to my hardware previously running
> Windows).
> 
> But i've struggled to understand the adjfreq(2) man page, so ended up
> finding a value for <freq> by trial and error.
> 
> I ended up with this code:
> 
>     double x = 1.5;
>     int64_t newfreq = ((1ll << 32) * 1e9) * x;
>     adjfreq(newfreq, NULL);

This does not look like actual code, first arg should be a pointer.

> 
> In this table, the second column is the increment in the time as shown
> by running date(1) twice, over a 10 second period as measured using my
> phone as a timer, for different values of x:
> 
>     x      10s
>     -------------
>     0      10
>     0.1    12
>     0.25   13
>     0.5    15
>     0.75   17
>     0.8    19
>     0.9    19
>     1.0    21
>     1.1     1
>     1.25:   3
>     1.5:    6
>     1.75:   8
>     2:     10
>     2.25:  10
>     2.5:   10

The only user of adjfreq(2) in base is ntpd(8), which caps it's
adjustments between +/-MAX_FREQUENCY_ADJUST = 128e-5.

It is very well possible the calculations in the kernel go wrong with
large(r) values. The API exists for gradual adjustments, not for
anything big.  Scott Cheloha <[email protected]> has been working
on the kernel side of things, he might know more, so I Cc'ed him,
don't know if her reads misc@.

        -Otto

> 
> So using x=1.5 makes OpenBSD's clock run at 0.6x of real time. I used
> this value to correct the one hour error in just over two hours.
> 
> But i wonder whether anyone could explain the values in the above
> table? The code in src/sys/kern/kern_tc.c:tc_windup() might be
> relevant, but i'm not sure what exactly it is doing.
> 
> As far as i can tell, the actual int64 values corresponding to the
> values of x above are:
> 
> x=0.000000 newfreq=0
> x=0.100000 newfreq=429496729600000000
> x=0.250000 newfreq=1073741824000000000
> x=0.500000 newfreq=2147483648000000000
> x=0.750000 newfreq=3221225472000000000
> x=0.800000 newfreq=3435973836800000000
> x=0.900000 newfreq=3865470566400000000
> x=1.000000 newfreq=4294967296000000000
> x=1.100000 newfreq=4724464025600000000
> x=1.250000 newfreq=5368709120000000000
> x=1.500000 newfreq=6442450944000000000
> x=1.750000 newfreq=7516192768000000000
> x=2.000000 newfreq=8589934592000000000
> x=2.250000 newfreq=-9223372036854775808
> x=2.500000 newfreq=-9223372036854775808
> 
> So these values increase monotonically, except for presumably wrapping
> errors for x=2.25 and x=2.5. So how come there is a big difference in
> behaviour between x=1.0 (21x) and x=1.1 (1x) ?
> 
> Thanks for any help here,
> 
> - Jules
> 
> -- 
> http://op59.net
> 
> 

Reply via email to