lkml.org 
[lkml]   [2006]   [Feb]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject2.6.15:kernel/time.c: The Nanosecond and code duplication
    Hi!

    I'm working on an integration of current NTP kernel algorithms for Linux 2.6.
    xtime now has nanosecond resolution, but there's no POSIX like syscall interface
    (clock_getres, clock_gettime, clock_settime) yet.

    There's a hacked-on getnstimeofday() which, what I discovered doesn't actually
    pass along the nanosecond resolution of xtime. It does:

    void getnstimeofday(struct timespec *tv)
    {
    struct timeval x;

    do_gettimeofday(&x);
    tv->tv_sec = x.tv_sec;
    tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
    }

    The proper solution most likely is to define POSIX compatible routines with
    nanosecond resolution, and then define the microsecond-resolution from those, and
    not the other way round.

    Also there are severe religious wars on how a clock interface should look like for
    a particular architecture. Besides the time interpolator there are architecture-
    specific get_offset() calls. While making some people happy, it causes a code
    explosion considering amount and complexity of code. I'd strongly prefer one time
    variable (xtime) and an interpolator for the time elapsed since xtime was updates,
    combinded with a method how to get consistent time. That's bad IMHO.

    To make a long story short, here's a patch (just for inspiring you) I made to get
    the nanoseconds available to other modules and to user land (via new methods
    outside this patch):

    Index: kernel/time.c
    ===================================================================
    RCS file: /root/LinuxCVS/Kernel/kernel/time.c,v
    retrieving revision 1.1.1.6.2.1
    diff -u -r1.1.1.6.2.1 time.c
    --- kernel/time.c 11 Feb 2006 18:16:28 -0000 1.1.1.6.2.1
    +++ kernel/time.c 12 Feb 2006 17:30:51 -0000
    @@ -1405,26 +1407,36 @@
    }
    EXPORT_SYMBOL(timespec_trunc);

    -#ifdef CONFIG_TIME_INTERPOLATION
    +/* get system time with nanosecond accuracy */
    void getnstimeofday (struct timespec *tv)
    {
    - unsigned long seq,sec,nsec;
    -
    + unsigned long seq, nsec, sec, offset;
    do {
    seq = read_seqbegin(&xtime_lock);
    +#ifdef CONFIG_TIME_INTERPOLATION
    + offset = time_interpolator_get_offset();
    +#else
    + offset = 0;
    +#endif
    sec = xtime.tv_sec;
    - nsec = xtime.tv_nsec+time_interpolator_get_offset();
    + nsec = xtime.tv_nsec + offset;
    } while (unlikely(read_seqretry(&xtime_lock, seq)));

    +#ifdef CONFIG_TIME_INTERPOLATION
    while (unlikely(nsec >= NSEC_PER_SEC)) {
    nsec -= NSEC_PER_SEC;
    ++sec;
    }
    +#endif
    tv->tv_sec = sec;
    tv->tv_nsec = nsec;
    }
    EXPORT_SYMBOL_GPL(getnstimeofday);

    +#ifdef CONFIG_TIME_INTERPOLATION
    +/* this is a mess: there are also architecture-dependent ``do_gettimeofday()''
    + * and ``do_settimeofday()''
    + */
    int do_settimeofday (struct timespec *tv)
    {
    time_t wtm_sec, sec = tv->tv_sec;
    @@ -1451,42 +1463,14 @@

    void do_gettimeofday (struct timeval *tv)
    {
    - unsigned long seq, nsec, usec, sec, offset;
    - do {
    - seq = read_seqbegin(&xtime_lock);
    - offset = time_interpolator_get_offset();
    - sec = xtime.tv_sec;
    - nsec = xtime.tv_nsec;
    - } while (unlikely(read_seqretry(&xtime_lock, seq)));
    + struct timespec ts;

    - usec = (nsec + offset) / 1000;
    -
    - while (unlikely(usec >= USEC_PER_SEC)) {
    - usec -= USEC_PER_SEC;
    - ++sec;
    - }
    -
    - tv->tv_sec = sec;
    - tv->tv_usec = usec;
    + getnstimeofday(&ts);
    + tv->tv_sec = ts.tv_sec;
    + tv->tv_usec = (ts.tv_nsec + 500) / 1000;
    }

    EXPORT_SYMBOL(do_gettimeofday);
    -
    -
    -#else
    -/*
    - * Simulate gettimeofday using do_gettimeofday which only allows a timeval
    - * and therefore only yields usec accuracy
    - */
    -void getnstimeofday(struct timespec *tv)
    -{
    - struct timeval x;
    -
    - do_gettimeofday(&x);
    - tv->tv_sec = x.tv_sec;
    - tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
    -}
    -EXPORT_SYMBOL_GPL(getnstimeofday);
    #endif

    void getnstimestamp(struct timespec *ts)

    Regards,
    Ulrich

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2006-02-13 09:31    [W:3.172 / U:0.288 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site