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 > >

