--- include/nucleus/timer.h | 25 +++++++++++++++++++------ ksrc/drivers/testing/timerbench.c | 9 ++++----- ksrc/nucleus/pod.c | 12 ++++++++---- ksrc/nucleus/timer.c | 25 ++++++++++++++++++++----- ksrc/skins/native/alarm.c | 2 +- ksrc/skins/posix/timer.c | 3 ++- ksrc/skins/psos+/tm.c | 2 +- ksrc/skins/vxworks/wdLib.c | 2 +- sim/skins/posix/testsuite/xntest.c | 2 +- sim/skins/vxworks/testsuite/xntest.c | 2 +- 10 files changed, 58 insertions(+), 26 deletions(-) Index: xenomai/include/nucleus/timer.h =================================================================== --- xenomai.orig/include/nucleus/timer.h +++ xenomai/include/nucleus/timer.h @@ -31,9 +31,14 @@ #define XNTIMER_WHEELMASK (XNTIMER_WHEELSIZE - 1) #endif /* CONFIG_XENO_OPT_TIMING_PERIODIC || CONFIG_XENO_OPT_TIMER_WHEEL */ +/* Timer status */ #define XNTIMER_DEQUEUED 0x00000001 #define XNTIMER_KILLED 0x00000002 +/* Timer mode */ +#define XNTIMER_RELATIVE 0 +#define XNTIMER_ABSOLUTE 1 + /* These flags are available to the real-time interfaces */ #define XNTIMER_SPARE0 0x01000000 #define XNTIMER_SPARE1 0x02000000 @@ -268,7 +273,8 @@ typedef struct xntmops { xnticks_t (*get_raw_clock)(void); void (*do_timer_start)(xntimer_t *timer, xnticks_t value, - xnticks_t interval); + xnticks_t interval, + int mode); void (*do_timer_stop)(xntimer_t *timer); xnticks_t (*get_timer_date)(xntimer_t *timer); xnticks_t (*get_timer_timeout)(xntimer_t *timer); @@ -291,7 +297,8 @@ void xntimer_init(xntimer_t *timer, void xntimer_destroy(xntimer_t *timer); /*! - * \fn void xntimer_start(xntimer_t *timer,xnticks_t value,xnticks_t interval) + * \fn void xntimer_start(xntimer_t *timer,xnticks_t value,xnticks_t interval, + * int mode) * \brief Arm a timer. * * Activates a timer so that the associated timeout handler will be @@ -302,14 +309,19 @@ void xntimer_destroy(xntimer_t *timer); * * @param timer The address of a valid timer descriptor. * - * @param value The relative date of the initial timer shot, expressed - * in clock ticks (see note). + * @param value The date of the initial timer shot, expressed in clock ticks + * (see note). * * @param interval The reload value of the timer. It is a periodic * interval value to be used for reprogramming the next timer shot, * expressed in clock ticks (see note). If @a interval is equal to * XN_INFINITE, the timer will not be reloaded after it has expired. * + * @param mode The timer mode. It can be either XNTIMER_RELATIVE or + * XNTIMER_ABSOLUTE to define if @a value shall be interpreted as a relative + * or absolute date. Absolute dates are based on the nucleus time returned by + * xnpod_get_time(). + * * @return 0 is always returned. * * Environments: @@ -332,9 +344,10 @@ void xntimer_destroy(xntimer_t *timer); */ static inline void xntimer_start(xntimer_t *timer, - xnticks_t value, xnticks_t interval) + xnticks_t value, xnticks_t interval, + int mode) { - nktimer->do_timer_start(timer, value, interval); + nktimer->do_timer_start(timer, value, interval, mode); } /*! Index: xenomai/ksrc/drivers/testing/timerbench.c =================================================================== --- xenomai.orig/ksrc/drivers/testing/timerbench.c +++ xenomai/ksrc/drivers/testing/timerbench.c @@ -175,8 +175,8 @@ void timer_proc(xntimer_t *timer) ctx->start_time = rtdm_clock_read(); /* FIXME: convert to RTDM timers */ - xntimer_start(&ctx->timer, xnpod_ns2ticks(ctx->date-ctx->start_time), - XN_INFINITE); + xntimer_start(&ctx->timer, xnpod_ns2ticks(ctx->date), + XN_INFINITE, XNTIMER_ABSOLUTE); if (++ctx->curr.test_loops < ctx->samples_per_sec) return; @@ -320,9 +320,8 @@ int rt_tmbench_ioctl_nrt(struct rtdm_dev ctx->date = ctx->start_time + ctx->period; /* FIXME: convert to RTDM timers */ - xntimer_start(&ctx->timer, - xnpod_ns2ticks(ctx->date-rtdm_clock_read()), - XN_INFINITE); + xntimer_start(&ctx->timer, xnpod_ns2ticks(ctx->date), + XN_INFINITE, XNTIMER_ABSOLUTE); ); } } Index: xenomai/ksrc/nucleus/pod.c =================================================================== --- xenomai.orig/ksrc/nucleus/pod.c +++ xenomai/ksrc/nucleus/pod.c @@ -1429,7 +1429,8 @@ void xnpod_suspend_thread(xnthread_t *th a call to xnpod_suspend_thread(thread,XNDELAY,0,NULL). */ __setbits(thread->status, XNDELAY); xntimer_set_sched(&thread->rtimer, thread->sched); - xntimer_start(&thread->rtimer, timeout, XN_INFINITE); + xntimer_start(&thread->rtimer, timeout, XN_INFINITE, + XNTIMER_RELATIVE); } #ifdef __XENO_SIM__ if (nkpod->schedhook) @@ -3101,7 +3102,8 @@ int xnpod_start_timer(u_long nstick, xni if (XNARCH_HOST_TICK) { xnlock_get_irqsave(&nklock, s); xntimer_start(&nkpod->htimer, delta, - XNARCH_HOST_TICK / nkpod->tickvalue); + XNARCH_HOST_TICK / nkpod->tickvalue, + XNTIMER_RELATIVE); xnlock_put_irqrestore(&nklock, s); } @@ -3390,14 +3392,16 @@ int xnpod_set_thread_periodic(xnthread_t xntimer_set_sched(&thread->ptimer, thread->sched); if (idate == XN_INFINITE) { - xntimer_start(&thread->ptimer, period, period); + xntimer_start(&thread->ptimer, period, period, + XNTIMER_RELATIVE); thread->pexpect = xntimer_get_raw_expiry(&thread->ptimer) + xntimer_interval(&thread->ptimer); } else { now = xnpod_get_time(); if (idate > now) { - xntimer_start(&thread->ptimer, idate - now, period); + xntimer_start(&thread->ptimer, idate, period, + XNTIMER_ABSOLUTE); thread->pexpect = xntimer_get_raw_expiry(&thread->ptimer) + xntimer_interval(&thread->ptimer); Index: xenomai/ksrc/nucleus/timer.c =================================================================== --- xenomai.orig/ksrc/nucleus/timer.c +++ xenomai/ksrc/nucleus/timer.c @@ -93,14 +93,22 @@ static inline void xntimer_next_remote_s } static void xntimer_do_start_aperiodic(xntimer_t *timer, - xnticks_t value, xnticks_t interval) + xnticks_t value, xnticks_t interval, + int mode) { + xnticks_t date; + if (!testbits(timer->status, XNTIMER_DEQUEUED)) xntimer_dequeue_aperiodic(timer); - xntimerh_date(&timer->aplink) = - xnarch_get_cpu_tsc() + xnarch_ns_to_tsc(value); + if (mode == XNTIMER_RELATIVE) + date = xnarch_ns_to_tsc(value) + xnarch_get_cpu_tsc(); + else + date = xnarch_ns_to_tsc(value - nkpod->wallclock_offset); + + xntimerh_date(&timer->aplink) = date; timer->interval = xnarch_ns_to_tsc(interval); + xntimer_enqueue_aperiodic(timer); if (xntimer_heading_p(timer)) { if (xntimer_sched(timer) != xnpod_current_sched()) @@ -287,13 +295,20 @@ static inline void xntimer_dequeue_perio } static void xntimer_do_start_periodic(xntimer_t *timer, - xnticks_t value, xnticks_t interval) + xnticks_t value, xnticks_t interval, + int mode) { if (!testbits(timer->status, XNTIMER_DEQUEUED)) xntimer_dequeue_periodic(timer); - xntlholder_date(&timer->plink) = nkpod->jiffies + value; + if (mode == XNTIMER_RELATIVE) + value += nkpod->jiffies; + else + value -= nkpod->wallclock_offset; + + xntlholder_date(&timer->plink) = value; timer->interval = interval; + xntimer_enqueue_periodic(timer); } Index: xenomai/ksrc/skins/native/alarm.c =================================================================== --- xenomai.orig/ksrc/skins/native/alarm.c +++ xenomai/ksrc/skins/native/alarm.c @@ -360,7 +360,7 @@ int rt_alarm_start(RT_ALARM *alarm, RTIM goto unlock_and_exit; } - xntimer_start(&alarm->timer_base, value, interval); + xntimer_start(&alarm->timer_base, value, interval, XNTIMER_RELATIVE); unlock_and_exit: Index: xenomai/ksrc/skins/posix/timer.c =================================================================== --- xenomai.orig/ksrc/skins/posix/timer.c +++ xenomai/ksrc/skins/posix/timer.c @@ -372,7 +372,8 @@ int timer_settime(timer_t timerid, start = 1; xntimer_start(&timer->timerbase, - start, ts2ticks_ceil(&value->it_interval)); + start, ts2ticks_ceil(&value->it_interval), + XNTIMER_RELATIVE); timer->owner = cur; inith(&timer->tlink); appendq(&timer->owner->timersq, &timer->tlink); Index: xenomai/ksrc/skins/psos+/tm.c =================================================================== --- xenomai.orig/ksrc/skins/psos+/tm.c +++ xenomai/ksrc/skins/psos+/tm.c @@ -91,7 +91,7 @@ static u_long tm_start_event_timer(u_lon appendq(&psostimerq, &tm->link); appendgq(&tm->owner->alarmq, tm); - xntimer_start(&tm->timerbase, ticks, interval); + xntimer_start(&tm->timerbase, ticks, interval, XNTIMER_RELATIVE); xnlock_put_irqrestore(&nklock, s); Index: xenomai/ksrc/skins/vxworks/wdLib.c =================================================================== --- xenomai.orig/ksrc/skins/vxworks/wdLib.c +++ xenomai/ksrc/skins/vxworks/wdLib.c @@ -183,7 +183,7 @@ STATUS wdStart(WDOG_ID wdog_id, int time wd->handler = handler; wd->arg = arg; - xntimer_start(&wd->timerbase, timeout, XN_INFINITE); + xntimer_start(&wd->timerbase, timeout, XN_INFINITE, XNTIMER_RELATIVE); xnlock_put_irqrestore(&nklock, s); return OK; Index: xenomai/sim/skins/posix/testsuite/xntest.c =================================================================== --- xenomai.orig/sim/skins/posix/testsuite/xntest.c +++ xenomai/sim/skins/posix/testsuite/xntest.c @@ -79,7 +79,7 @@ void xntest_start(void) xnlock_get_irqsave(&test_lock, s); xntimer_init(&watchdog, interrupt_test); - xntimer_start(&watchdog, xnpod_ns2ticks(test_timeout * 1000000000ULL), XN_INFINITE); + xntimer_start(&watchdog, xnpod_ns2ticks(test_timeout * 1000000000ULL), XN_INFINITE, XNTIMER_RELATIVE); initq(&marks_q); tests=0; Index: xenomai/sim/skins/vxworks/testsuite/xntest.c =================================================================== --- xenomai.orig/sim/skins/vxworks/testsuite/xntest.c +++ xenomai/sim/skins/vxworks/testsuite/xntest.c @@ -79,7 +79,7 @@ void xntest_start(void) xnlock_get_irqsave(&test_lock, s); xntimer_init(&watchdog, interrupt_test); - xntimer_start(&watchdog, xnpod_ns2ticks(test_timeout * 1000000000ULL), XN_INFINITE); + xntimer_start(&watchdog, xnpod_ns2ticks(test_timeout * 1000000000ULL), XN_INFINITE, XNTIMER_RELATIVE); initq(&marks_q); tests=0;