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