int rt_task_make_periodic_relative_ns(RT_TASK *task, RTIME start_delay, RTIME period) { RTIME idate; int err; spl_t s; xnlock_get_irqsave(&nklock, s); task = rtai_h2obj_validate(task, RTAI_TASK_MAGIC, RT_TASK); if (!task) { err = -EINVAL; goto unlock_and_exit; } idate = start_delay ? xntbase_ticks2ns(rtai_tbase, xntbase_get_time(rtai_tbase)) + start_delay : XN_INFINITE; err = xnpod_set_thread_periodic(&task->thread_base, idate, period); if (task->suspend_depth > 0 && --task->suspend_depth == 0) { xnpod_resume_thread(&task->thread_base, XNSUSP); xnpod_schedule(); } unlock_and_exit: xnlock_put_irqrestore(&nklock, s); return err; }
xnticks_t xntbase_convert(xntbase_t *srcbase, xnticks_t ticks, xntbase_t *dstbase) { /* Twisted, but tries hard not to rescale to nanoseconds * before converting, so that we could save a 64bit multiply in the common cases (i.e. converting to/from master). */ if (dstbase->tickvalue == srcbase->tickvalue) return ticks; if (likely(xntbase_master_p(dstbase))) return xntbase_ticks2ns(srcbase, ticks); /* Periodic to master base. */ if (xntbase_master_p(srcbase)) return xntbase_ns2ticks(dstbase, ticks); /* Master base to periodic. */ /* Periodic to periodic. */ return xntbase_ns2ticks(dstbase, xntbase_ticks2ns(srcbase, ticks)); }
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); }
RTIME rt_get_time_ns(void) { RTIME ticks = xntbase_get_time(rtai_tbase); return xntbase_ticks2ns(rtai_tbase, ticks); }