Module: xenomai-forge
Branch: master
Commit: f595f891b2637167c9a7e07ece111d114c4eb704
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=f595f891b2637167c9a7e07ece111d114c4eb704

Author: Philippe Gerum <r...@xenomai.org>
Date:   Mon Aug  5 16:27:27 2013 +0200

cobalt/posix, lib/cobalt: direct reading of CLOCK_REALTIME (no syscall)

At some point, we may use the time source CLOCK_HOST_REALTIME is based
on whenever available, for implementing Xenomai's core clock
XN_REALTIME mode.

---

 include/cobalt/kernel/clock.h     |    1 +
 include/cobalt/uapi/kernel/vdso.h |    3 +++
 kernel/cobalt/clock.c             |    4 +++-
 kernel/cobalt/sys.c               |    2 ++
 lib/cobalt/clock.c                |   10 ++++++++--
 testsuite/clocktest/clocktest.c   |   12 ++++++++++++
 6 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/include/cobalt/kernel/clock.h b/include/cobalt/kernel/clock.h
index fbe74d9..945fb28 100644
--- a/include/cobalt/kernel/clock.h
+++ b/include/cobalt/kernel/clock.h
@@ -35,6 +35,7 @@ struct xnsched;
 struct xntimerdata;
 
 struct xnclock {
+       /** ns */
        xnticks_t wallclock_offset;
        /** ns */
        xnticks_t resolution;
diff --git a/include/cobalt/uapi/kernel/vdso.h 
b/include/cobalt/uapi/kernel/vdso.h
index a4c5d80..9146873 100644
--- a/include/cobalt/uapi/kernel/vdso.h
+++ b/include/cobalt/uapi/kernel/vdso.h
@@ -43,11 +43,14 @@ struct xnvdso {
 
        /* XNVDSO_FEAT_HOST_REALTIME */
        struct xnvdso_hostrt_data hostrt_data;
+       /* XNVDSO_FEAT_WALLCLOCK_OFFSET */
+       unsigned long long wallclock_offset;
 };
 
 /* For each shared feature, add a flag below. */
 
 #define XNVDSO_FEAT_HOST_REALTIME      0x0000000000000001ULL
+#define XNVDSO_FEAT_WALLCLOCK_OFFSET   0x0000000000000002ULL
 
 static inline int xnvdso_test_feature(struct xnvdso *vdso,
                                      unsigned long long feature)
diff --git a/kernel/cobalt/clock.c b/kernel/cobalt/clock.c
index b189500..735b204 100644
--- a/kernel/cobalt/clock.c
+++ b/kernel/cobalt/clock.c
@@ -28,6 +28,7 @@
 #include <cobalt/kernel/timer.h>
 #include <cobalt/kernel/clock.h>
 #include <cobalt/kernel/arith.h>
+#include <cobalt/kernel/vdso.h>
 #include <asm/xenomai/calibration.h>
 
 unsigned long nktimerlat;
@@ -288,7 +289,7 @@ static void adjust_clock_timers(struct xnclock *clock, 
xnsticks_t delta)
  *
  * @param clock The clock to adjust.
  *
- * @param delta The adjustment value expressed in raw clock ticks.
+ * @param delta The adjustment value expressed in nanoseconds.
  *
  * @note This routine must be entered nklock locked, interrupts off.
  *
@@ -309,6 +310,7 @@ void xnclock_adjust(struct xnclock *clock, xnsticks_t delta)
        xnticks_t now;
 
        nkclock.wallclock_offset += delta;
+       nkvdso->wallclock_offset = nkclock.wallclock_offset;
        now = xnclock_read_monotonic(clock) + nkclock.wallclock_offset;
        adjust_clock_timers(clock, delta);
 
diff --git a/kernel/cobalt/sys.c b/kernel/cobalt/sys.c
index df6fc93..4003ac0 100644
--- a/kernel/cobalt/sys.c
+++ b/kernel/cobalt/sys.c
@@ -30,6 +30,7 @@
 #include <cobalt/kernel/select.h>
 #include <cobalt/kernel/shadow.h>
 #include <cobalt/kernel/lock.h>
+#include <cobalt/kernel/vdso.h>
 #include <cobalt/kernel/sys.h>
 
 cpumask_t nkaffinity = CPU_MASK_ALL;
@@ -53,6 +54,7 @@ static int enable_timesource(void)
 
        nkclock.wallclock_offset =
                xnclock_get_host_time() - xnclock_read_monotonic(&nkclock);
+       nkvdso->wallclock_offset = nkclock.wallclock_offset;
 
        for_each_realtime_cpu(cpu) {
                htickval = xntimer_grab_hardware(cpu);
diff --git a/lib/cobalt/clock.c b/lib/cobalt/clock.c
index 28c63cd..680a622 100644
--- a/lib/cobalt/clock.c
+++ b/lib/cobalt/clock.c
@@ -43,7 +43,7 @@ COBALT_IMPL(int, clock_getres, (clockid_t clock_id, struct 
timespec *tp))
        return -1;
 }
 
-static int __do_clock_host_realtime(struct timespec *ts, void *tzp)
+static int __do_clock_host_realtime(struct timespec *ts)
 {
        unsigned long long now, base, mask, cycle_delta;
        struct xnvdso_hostrt_data *hostrt_data;
@@ -89,7 +89,7 @@ COBALT_IMPL(int, clock_gettime, (clockid_t clock_id, struct 
timespec *tp))
 
        switch (clock_id) {
        case CLOCK_HOST_REALTIME:
-               ret = __do_clock_host_realtime(tp, NULL);
+               ret = __do_clock_host_realtime(tp);
                break;
        case CLOCK_MONOTONIC:
        case CLOCK_MONOTONIC_RAW:
@@ -97,6 +97,12 @@ COBALT_IMPL(int, clock_gettime, (clockid_t clock_id, struct 
timespec *tp))
                tp->tv_sec = cobalt_divrem_billion(ns, &rem);
                tp->tv_nsec = rem;
                return 0;
+       case CLOCK_REALTIME:
+               ns = cobalt_ticks_to_ns(__xn_rdtsc());
+               ns += vdso->wallclock_offset;
+               tp->tv_sec = cobalt_divrem_billion(ns, &rem);
+               tp->tv_nsec = rem;
+               return 0;
        default:
                ret = -XENOMAI_SKINCALL2(__cobalt_muxid,
                                         sc_cobalt_clock_gettime,
diff --git a/testsuite/clocktest/clocktest.c b/testsuite/clocktest/clocktest.c
index 1ae704b..3a34998 100644
--- a/testsuite/clocktest/clocktest.c
+++ b/testsuite/clocktest/clocktest.c
@@ -109,6 +109,16 @@ static void show_hostrt_diagnostics(void)
        printf("shift            : %u\n\n", vdso->hostrt_data.shift);
 }
 
+static void show_realtime_offset(void)
+{
+       if (!xnvdso_test_feature(vdso, XNVDSO_FEAT_HOST_REALTIME)) {
+               printf("XNVDSO_FEAT_WALLCLOCK_OFFSET not available\n");
+               return;
+       }
+
+       printf("Wallclock offset : %llu\n", vdso->wallclock_offset);
+}
+
 static inline unsigned long long read_clock(clockid_t clock_id)
 {
        struct timespec ts;
@@ -120,6 +130,8 @@ static inline unsigned long long read_clock(clockid_t 
clock_id)
                        clock_id);
                if (clock_id == CLOCK_HOST_REALTIME)
                        show_hostrt_diagnostics();
+               else if (clock_id == CLOCK_REALTIME)
+                       show_realtime_offset();
 
                exit(-1);
        }


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to