[lkml]   [2006]   [Aug]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    SubjectRe: Linux time code
    >> I was talking about the UTS/leapsecond bits w/ Ted just the other day
    >> and had a similar thought! To me it makes quite a bit of sense to
    >> generate UTC and UTS from TAI, just as you do in the above, since UTC =
    >> TAI + leapsecond offset, just as local time = GMT + timezone offset.

    > However the difficulty would be that while NTP provides leapsecond +/-
    > notifiers, it doesn't provide the absolute UTC offset from TAI. So there
    > isn't a way for the kernel to generate TAI, from a UTC settimeofday
    > call. Some method to distribute and inform the kernel of the absolute
    > leapsecond offset (tai_minus_utc in your code above) would be necessary.

    Well, there are several possibilities. For the opinion of experts on
    the subject see paper #7 from

    Levine, J., and D. Mills. Using the Network Time Protocol to transmit
    International Atomic Time (TAI). Proc. Precision Time and Time Interval
    (PTTI) Applications and Planning Meeting (Reston VA, November 2000).{ps,pdf}

    This describes an NTP extension to disseminate leap second times.

    GPS broadcasts the absolute offset of UTC from GPS, which is itself
    19 s from TAI, so you can get TAI.

    You can also poll
    every few months. Note that a directory listing will
    tell you if anything has changed, since that's a symlink
    to the real file, whose name includes an update timestamp.

    You can also just accumulate the +/- notifiers to figure out the offset.

    I think this can be entered very easily using sysctl.

    > Additionally creating UTS and UTC at the same time would be a bit
    > complicated. Your solution above isn't quite UTS, since it only handles
    > the leap insertion, however the insertion case is the one that causes
    > users most of the pain (since the clock goes backward), so it may very
    > well be good enough.

    It's not that it's hard to implement leap deletion, but it's code
    on a moderately hot path (gettimeofday() is a very popular system
    call) that will, as far as anyone knows, never be used.

    If you want the full version, try:

    case CLOCK_UTS:
    /* Recommended for gettimeofday() & time() */
    /* See */
    clock_gettime(CLOCK_TAI, tp);
    tp->tv_sec -= tai_minus_utc;

    if (tp->tv_sec > next_leap_second) {
    tp->tv_sec += (next_leap_second & 1) ? -1 : 1;

    } else if (next_leap_second - tp->tv_sec < 1000) {
    /* 1000 UTC/TAI seconds = 999 or 1001 UTS seconds */
    uint32_t offset = next_leap_second - tp->tv_sec + 1;
    offset *= MILLION;
    offset += (uint32_t)(BILLION - tp->tv_nsec)/1000;
    if (next_leap_second & 1) {
    /* Negative (deleted) leap second */
    if ((tp->tv_nsec += offset) >= BILLION) {
    tp->tv_nsec -= BILLION;
    } else {
    /* Positive (inserted) leap second */
    if ((tp->tv_nsec -= offset) < 0) {
    tp->tv_nsec += BILLION;

    Note that this code does not interact nicely with updates to tai_minus_utc
    and next_leap_second. An RCU-like scheme would involve a pre- and
    post-leap tai_minus_utc, which lets you schedule a new leap by:

    <wait for idle>
    # At this point, everyone knows that next_leap_second has passed, and
    # so pre_tai_utc is don't care
    pre_tai_utc = post_tai_utc;
    <wait for idle>
    # Now next_leap_second is don't care.
    next_leap_second = <announced time>
    <wait for idle>
    # Now post_tai_utc can be rewritten.

    Which doesn't require any locking on the part of the reader, just not
    blocking during the conversion.

    > Overall, I like your idea quite a bit. Might we look forward to a
    > patch? :)

    Um, the UTS one I talked about, or the two-phase grab-raw and
    convert-to-portable implementation technique? If the latter,
    can we come to some agreement about the questions asked therein?

    There's a very nice implementation in PHK's FreeBSD timecounter code.
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to
    More majordomo info at
    Please read the FAQ at

     \ /
      Last update: 2006-08-24 04:37    [W:0.024 / U:16.028 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site