char *xntimer_format_time(xnticks_t value, int periodic, char *buf, size_t bufsz) { unsigned long ms, us, ns; char *p = buf; xnticks_t s; if (periodic) { snprintf(buf, bufsz, "%Lut", value); return buf; } if (value == 0 && bufsz > 1) { strcpy(buf, "-"); return buf; } s = xnarch_divrem_billion(value, &ns); us = ns / 1000; ms = us / 1000; us %= 1000; if (s) p += snprintf(p, bufsz, "%Lus", s); if (ms || (s && us)) p += snprintf(p, bufsz - (p - buf), "%lums", ms); if (us) p += snprintf(p, bufsz - (p - buf), "%luus", us); return buf; }
int __wrap_clock_gettime(clockid_t clock_id, struct timespec *tp) { int err; #ifdef XNARCH_HAVE_NONPRIV_TSC if (clock_id == CLOCK_MONOTONIC && __pse51_sysinfo.tickval == 1) { unsigned long long ns; unsigned long rem; ns = xnarch_tsc_to_ns(__xn_rdtsc()); tp->tv_sec = xnarch_divrem_billion(ns, &rem); tp->tv_nsec = rem; return 0; } #endif /* XNARCH_HAVE_NONPRIV_TSC */ err = -XENOMAI_SKINCALL2(__pse51_muxid, __pse51_clock_gettime, clock_id, tp); if (!err) return 0; errno = err; return -1; }
/** * Read the host-synchronised realtime clock. * * Obtain the current time with NTP corrections from the Linux domain * * @param tp pointer to a struct timespec * * @retval 0 on success; * @retval -1 if no suitable NTP-corrected clocksource is availabel * * @see * <a href="http://www.opengroup.org/onlinepubs/000095399/functions/gettimeofday.html"> * Specification.</a> * */ static int do_clock_host_realtime(struct timespec *tp) { #ifdef CONFIG_XENO_OPT_HOSTRT cycle_t now, base, mask, cycle_delta; unsigned long mult, shift, nsec, rem; struct xnvdso_hostrt_data *hostrt_data; unsigned int seq; hostrt_data = get_hostrt_data(); BUG_ON(!hostrt_data); if (unlikely(!hostrt_data->live)) return -1; /* * Note: Disabling HW interrupts around writes to hostrt_data ensures * that a reader (on the Xenomai side) cannot interrupt a writer (on * the Linux kernel side) on the same CPU. The sequence counter is * required when a reader is interleaved by a writer on a different * CPU. This follows the approach from userland, where tasking the * spinlock is not possible. */ retry: seq = xnread_seqcount_begin(&hostrt_data->seqcount); now = xnarch_get_cpu_tsc(); base = hostrt_data->cycle_last; mask = hostrt_data->mask; mult = hostrt_data->mult; shift = hostrt_data->shift; tp->tv_sec = hostrt_data->wall_time_sec; nsec = hostrt_data->wall_time_nsec; if (xnread_seqcount_retry(&hostrt_data->seqcount, seq)) goto retry; /* * At this point, we have a consistent copy of the fundamental * data structure - calculate the interval between the current * and base time stamp cycles, and convert the difference * to nanoseconds. */ cycle_delta = (now - base) & mask; nsec += (cycle_delta * mult) >> shift; /* Convert to the desired sec, usec representation */ tp->tv_sec += xnarch_divrem_billion(nsec, &rem); tp->tv_nsec = rem; return 0; #else /* CONFIG_XENO_OPT_HOSTRT */ return -EINVAL; #endif }