static int timer_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { const char *tm_status, *wd_status = ""; int len; if (xnpod_active_p() && xntbase_enabled_p(&nktbase)) { tm_status = "on"; #ifdef CONFIG_XENO_OPT_WATCHDOG wd_status = "+watchdog"; #endif /* CONFIG_XENO_OPT_WATCHDOG */ } else tm_status = "off"; len = sprintf(page, "status=%s%s:setup=%Lu:clock=%Lu:timerdev=%s:clockdev=%s\n", tm_status, wd_status, xnarch_tsc_to_ns(nktimerlat), xntbase_get_rawclock(&nktbase), XNARCH_TIMER_DEVICE, XNARCH_CLOCK_DEVICE); len -= off; if (len <= off + count) *eof = 1; *start = page + off; if (len > count) len = count; if (len < 0) len = 0; return len; }
int xntbase_switch(const char *name, u_long period, xntbase_t **basep) { xntbase_t *oldbase = *basep, *newbase; int err = 0; if (!*basep) /* Switching from no time base to a valid one is ok, we only need to assume that the old time base was the master one. */ oldbase = &nktbase; if (period == XN_APERIODIC_TICK) { if (xntbase_periodic_p(oldbase)) { /* The following call cannot fail. */ xntbase_alloc(name, XN_APERIODIC_TICK, 0, basep); xntbase_free(oldbase); } } else { if (xntbase_periodic_p(oldbase)) xntbase_update(oldbase, period); else { err = xntbase_alloc(name, period, 0, &newbase); if (!err) { int enabled = xntbase_enabled_p(oldbase); *basep = newbase; xntbase_free(oldbase); if (enabled) xntbase_start(newbase); } } } return err; }
void xntbase_start(xntbase_t *base) { xnticks_t start_date; spl_t s; if (base == &nktbase || xntbase_enabled_p(base)) return; trace_mark(xn_nucleus, tbase_start, "base %s", base->name); xnlock_get_irqsave(&nklock, s); start_date = xnarch_get_cpu_time(); /* Only synchronise non-isolated time bases on the master base. */ if (!xntbase_isolated_p(base)) { base->wallclock_offset = xntbase_ns2ticks(base, start_date + nktbase.wallclock_offset); __setbits(base->status, XNTBSET); } start_date += base->tickvalue; __setbits(base->status, XNTBRUN); xnlock_put_irqrestore(&nklock, s); xntslave_start(base2slave(base), start_date, base->tickvalue); }
void xntbase_stop(xntbase_t *base) { if (base == &nktbase || !xntbase_enabled_p(base)) return; xntslave_stop(base2slave(base)); __clrbits(base->status, XNTBRUN | XNTBSET); trace_mark(xn_nucleus, tbase_stop, "base %s", base->name); }
static int timer_vfile_show(struct xnvfile_regular_iterator *it, void *data) { const char *tm_status, *wd_status = ""; if (xnpod_active_p() && xntbase_enabled_p(&nktbase)) { tm_status = testbits(nktbase.status, XNTBLCK) ? "locked" : "on"; #ifdef CONFIG_XENO_OPT_WATCHDOG wd_status = "+watchdog"; #endif /* CONFIG_XENO_OPT_WATCHDOG */ } else tm_status = "off"; xnvfile_printf(it, "status=%s%s:setup=%Lu:clock=%Lu:timerdev=%s:clockdev=%s\n", tm_status, wd_status, xnarch_tsc_to_ns(nktimerlat), xntbase_get_rawclock(&nktbase), XNARCH_TIMER_DEVICE, XNARCH_CLOCK_DEVICE); return 0; }