void xnclock_core_local_shot(struct xnsched *sched) { struct xntimerdata *tmd; struct xntimer *timer; xnsticks_t delay; xntimerh_t *h; /* * Do not reprogram locally when inside the tick handler - * will be done on exit anyway. Also exit if there is no * pending timer. */ if (sched->status & XNINTCK) return; tmd = xnclock_this_timerdata(&nkclock); h = xntimerq_head(&tmd->q); if (h == NULL) return; /* * Here we try to defer the host tick heading the timer queue, * so that it does not preempt a real-time activity uselessly, * in two cases: * * 1) a rescheduling is pending for the current CPU. We may * assume that a real-time thread is about to resume, so we * want to move the host tick out of the way until the host * kernel resumes, unless there is no other outstanding * timers. * * 2) the current thread is running in primary mode, in which * case we may also defer the host tick until the host kernel * resumes. * * The host tick deferral is cleared whenever Xenomai is about * to yield control to the host kernel (see ___xnsched_run()), * or a timer with an earlier timeout date is scheduled, * whichever comes first. */ sched->lflags &= ~XNHDEFER; timer = container_of(h, struct xntimer, aplink); if (unlikely(timer == &sched->htimer)) { if (xnsched_resched_p(sched) || !xnthread_test_state(sched->curr, XNROOT)) { h = xntimerq_second(&tmd->q); if (h) { sched->lflags |= XNHDEFER; timer = container_of(h, struct xntimer, aplink); } } }
int xntimer_heading_p(struct xntimer *timer) { struct xnsched *sched = timer->sched; xntimerq_t *q; xntimerh_t *h; q = xntimer_percpu_queue(timer); h = xntimerq_head(q); if (h == &timer->aplink) return 1; if (sched->lflags & XNHDEFER) { h = xntimerq_second(q); if (h == &timer->aplink) return 1; } return 0; }