Module: xenomai-3 Branch: next Commit: e6cd9610215b06ee85272f57702354a7e38b5f7c URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=e6cd9610215b06ee85272f57702354a7e38b5f7c
Author: Philippe Gerum <r...@xenomai.org> Date: Fri Nov 4 16:25:15 2016 +0100 cobalt/posix/timer: allow usage with external clocks There is no reason to restrict usage of POSIX timers to the standard POSIX clocks, given that Cobalt allows registering user-defined clocks, and nothing in the implementation assumes a specific clock driving such timers. --- kernel/cobalt/posix/clock.c | 23 +++++++++++++++++++++++ kernel/cobalt/posix/clock.h | 22 +++++++++------------- kernel/cobalt/posix/timer.c | 19 +++++++------------ 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/kernel/cobalt/posix/clock.c b/kernel/cobalt/posix/clock.c index b51cb4c..8dab55b 100644 --- a/kernel/cobalt/posix/clock.c +++ b/kernel/cobalt/posix/clock.c @@ -349,3 +349,26 @@ void cobalt_clock_deregister(struct xnclock *clock) xnclock_deregister(clock); } EXPORT_SYMBOL_GPL(cobalt_clock_deregister); + +struct xnclock *cobalt_clock_find(clockid_t clock_id) +{ + struct xnclock *clock = ERR_PTR(-EINVAL); + spl_t s; + int nr; + + if (clock_id == CLOCK_MONOTONIC || + clock_id == CLOCK_MONOTONIC_RAW || + clock_id == CLOCK_REALTIME) + return &nkclock; + + if (__COBALT_CLOCK_EXT_P(clock_id)) { + nr = __COBALT_CLOCK_EXT_INDEX(clock_id); + xnlock_get_irqsave(&nklock, s); + if (test_bit(nr, cobalt_clock_extids)) + clock = external_clocks[nr]; + xnlock_put_irqrestore(&nklock, s); + } + + return clock; +} +EXPORT_SYMBOL_GPL(cobalt_clock_find); diff --git a/kernel/cobalt/posix/clock.h b/kernel/cobalt/posix/clock.h index 82cb0b6..c77c3a5 100644 --- a/kernel/cobalt/posix/clock.h +++ b/kernel/cobalt/posix/clock.h @@ -26,6 +26,8 @@ #define ONE_BILLION 1000000000 +struct xnclock; + static inline void ns2ts(struct timespec *ts, xnticks_t nsecs) { ts->tv_sec = xnclock_divrem_billion(nsecs, &ts->tv_nsec); @@ -68,21 +70,13 @@ static inline xnticks_t clock_get_ticks(clockid_t clock_id) static inline int clock_flag(int flag, clockid_t clock_id) { - switch(flag & TIMER_ABSTIME) { - case 0: + if ((flag & TIMER_ABSTIME) == 0) return XN_RELATIVE; - case TIMER_ABSTIME: - switch(clock_id) { - case CLOCK_MONOTONIC: - case CLOCK_MONOTONIC_RAW: - return XN_ABSOLUTE; - - case CLOCK_REALTIME: - return XN_REALTIME; - } - } - return -EINVAL; + if (clock_id == CLOCK_REALTIME) + return XN_REALTIME; + + return XN_ABSOLUTE; } int __cobalt_clock_getres(clockid_t clock_id, @@ -118,6 +112,8 @@ int cobalt_clock_register(struct xnclock *clock, void cobalt_clock_deregister(struct xnclock *clock); +struct xnclock *cobalt_clock_find(clockid_t clock_id); + extern DECLARE_BITMAP(cobalt_clock_extids, COBALT_MAX_EXTCLOCKS); #endif /* !_COBALT_POSIX_CLOCK_H */ diff --git a/kernel/cobalt/posix/timer.c b/kernel/cobalt/posix/timer.c index cf1c919..c6190d1 100644 --- a/kernel/cobalt/posix/timer.c +++ b/kernel/cobalt/posix/timer.c @@ -47,6 +47,7 @@ timer_init(struct cobalt_timer *timer, const struct sigevent *__restrict__ evp) /* nklocked, IRQs off. */ { struct cobalt_thread *owner = cobalt_current_thread(), *target = NULL; + struct xnclock *clock; /* * First, try to offload this operation to the extended @@ -59,14 +60,8 @@ timer_init(struct cobalt_timer *timer, /* * Ok, we have no extension available, or we do but it does * not want to overload the standard behavior: handle this - * timer the pure Cobalt way then. We only know about standard - * clocks in this case. + * timer the pure Cobalt way then. */ - if (timer->clockid != CLOCK_MONOTONIC && - timer->clockid != CLOCK_MONOTONIC_RAW && - timer->clockid != CLOCK_REALTIME) - return ERR_PTR(-EINVAL); - if (evp == NULL || evp->sigev_notify == SIGEV_NONE) { target = owner; /* Assume SIGEV_THREAD_ID. */ goto init; @@ -83,11 +78,11 @@ timer_init(struct cobalt_timer *timer, if (target == NULL) return ERR_PTR(-EINVAL); init: - /* - * All standard clocks are based on the core clock, and we - * want to deliver a signal when a timer elapses. - */ - xntimer_init(&timer->timerbase, &nkclock, cobalt_timer_handler, + clock = cobalt_clock_find(timer->clockid); + if (IS_ERR(clock)) + return ERR_PTR(PTR_ERR(clock)); + + xntimer_init(&timer->timerbase, clock, cobalt_timer_handler, target->threadbase.sched, XNTIMER_UGRAVITY); return target; _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git