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); }
static inline void xntimer_dequeue_periodic(xntimer_t *timer) { unsigned slot = (xntlholder_date(&timer->plink) & XNTIMER_WHEELMASK); unsigned cpu = xnsched_cpu(timer->sched); struct percpu_cascade *pc = &base2slave(timer->base)->cascade[cpu]; xntlist_remove(&pc->wheel[slot], &timer->plink); __setbits(timer->status, XNTIMER_DEQUEUED); }
static inline void xntimer_enqueue_periodic(xntimer_t *timer) { unsigned slot = (xntlholder_date(&timer->plink) & XNTIMER_WHEELMASK); unsigned cpu = xnsched_cpu(timer->sched); struct percpu_cascade *pc = &base2slave(timer->base)->cascade[cpu]; /* Just prepend the new timer to the proper slot. */ xntlist_insert(&pc->wheel[slot], &timer->plink); __clrbits(timer->status, XNTIMER_DEQUEUED); xnstat_counter_inc(&timer->scheduled); }
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); }
void xntbase_adjust_time(xntbase_t *base, xnsticks_t delta) { xnticks_t now; #ifdef CONFIG_XENO_OPT_TIMING_PERIODIC if (xntbase_isolated_p(base)) { /* Only update the specified isolated base. */ base->wallclock_offset += delta; __setbits(base->status, XNTBSET); xntslave_adjust(base2slave(base), delta); } else { xnholder_t *holder; #endif /* CONFIG_XENO_OPT_TIMING_PERIODIC */ /* Update all non-isolated bases in the system. */ nktbase.wallclock_offset += xntbase_ticks2ns(base, delta); now = xnarch_get_cpu_time() + nktbase.wallclock_offset; xntimer_adjust_all_aperiodic(xntbase_ticks2ns(base, delta)); #ifdef CONFIG_XENO_OPT_TIMING_PERIODIC for (holder = getheadq(&nktimebaseq); holder != NULL; holder = nextq(&nktimebaseq, holder)) { xntbase_t *tbase = link2tbase(holder); if (tbase == &nktbase || xntbase_isolated_p(tbase)) continue; tbase->wallclock_offset = xntbase_ns2ticks(tbase, now) - xntbase_get_jiffies(tbase); xntslave_adjust(base2slave(tbase), delta); } } #endif /* CONFIG_XENO_OPT_TIMING_PERIODIC */ trace_mark(xn_nucleus, tbase_adjust, "base %s delta %Lu", base->name, delta); }
void xntbase_free(xntbase_t *base) { spl_t s; if (base == &nktbase) return; xntslave_destroy(base2slave(base)); xntbase_remove_proc(base); xnlock_get_irqsave(&nklock, s); removeq(&nktimebaseq, &base->link); xnlock_put_irqrestore(&nklock, s); xnarch_free_host_mem(base, sizeof(*base)); }
void xntbase_tick(xntbase_t *base) { spl_t s; xnlock_get_irqsave(&nklock, s); trace_mark(xn_nucleus, tbase_tick, "base %s", base->name); if (base == &nktbase) xntimer_tick_aperiodic(); else { xntslave_t *slave = base2slave(base); xntimer_tick_periodic_inner(slave); } xnlock_put_irqrestore(&nklock, s); }
int xntbase_update(xntbase_t *base, u_long period) { spl_t s; if (base == &nktbase || base->tickvalue == period) return 0; if (period == XN_APERIODIC_TICK) return -EINVAL; xnlock_get_irqsave(&nklock, s); base->tickvalue = period; base->ticks2sec = 1000000000UL / period; xntslave_update(base2slave(base), period); xnlock_put_irqrestore(&nklock, s); return 0; }