[Xenomai-git] Philippe Gerum : cobalt/posix/timer: allow usage with external clocks
Module: xenomai-3 Branch: master Commit: e6cd9610215b06ee85272f57702354a7e38b5f7c URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=e6cd9610215b06ee85272f57702354a7e38b5f7c Author: Philippe GerumDate: 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 + + if (__COBALT_CLOCK_EXT_P(clock_id)) { + nr = __COBALT_CLOCK_EXT_INDEX(clock_id); + xnlock_get_irqsave(, s); + if (test_bit(nr, cobalt_clock_extids)) + clock = external_clocks[nr]; + xnlock_put_irqrestore(, 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 10 +struct xnclock; + static inline void ns2ts(struct timespec *ts, xnticks_t nsecs) { ts->tv_sec = xnclock_divrem_billion(nsecs, >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(>timerbase, , cobalt_timer_handler, + clock = cobalt_clock_find(timer->clockid); + if (IS_ERR(clock)) + return ERR_PTR(PTR_ERR(clock)); + + xntimer_init(>timerbase, clock, cobalt_timer_handler, target->threadbase.sched,
[Xenomai-git] Philippe Gerum : cobalt/posix/timer: allow usage with external clocks
Module: xenomai-3 Branch: wip/drivers Commit: e6cd9610215b06ee85272f57702354a7e38b5f7c URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=e6cd9610215b06ee85272f57702354a7e38b5f7c Author: Philippe GerumDate: 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 + + if (__COBALT_CLOCK_EXT_P(clock_id)) { + nr = __COBALT_CLOCK_EXT_INDEX(clock_id); + xnlock_get_irqsave(, s); + if (test_bit(nr, cobalt_clock_extids)) + clock = external_clocks[nr]; + xnlock_put_irqrestore(, 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 10 +struct xnclock; + static inline void ns2ts(struct timespec *ts, xnticks_t nsecs) { ts->tv_sec = xnclock_divrem_billion(nsecs, >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(>timerbase, , cobalt_timer_handler, + clock = cobalt_clock_find(timer->clockid); + if (IS_ERR(clock)) + return ERR_PTR(PTR_ERR(clock)); + + xntimer_init(>timerbase, clock, cobalt_timer_handler, target->threadbase.sched,
[Xenomai-git] Philippe Gerum : cobalt/posix/timer: allow usage with external clocks
Module: xenomai-3 Branch: next Commit: e6cd9610215b06ee85272f57702354a7e38b5f7c URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=e6cd9610215b06ee85272f57702354a7e38b5f7c Author: Philippe GerumDate: 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 + + if (__COBALT_CLOCK_EXT_P(clock_id)) { + nr = __COBALT_CLOCK_EXT_INDEX(clock_id); + xnlock_get_irqsave(, s); + if (test_bit(nr, cobalt_clock_extids)) + clock = external_clocks[nr]; + xnlock_put_irqrestore(, 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 10 +struct xnclock; + static inline void ns2ts(struct timespec *ts, xnticks_t nsecs) { ts->tv_sec = xnclock_divrem_billion(nsecs, >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(>timerbase, , cobalt_timer_handler, + clock = cobalt_clock_find(timer->clockid); + if (IS_ERR(clock)) + return ERR_PTR(PTR_ERR(clock)); + + xntimer_init(>timerbase, clock, cobalt_timer_handler, target->threadbase.sched,
[Xenomai-git] Philippe Gerum : cobalt/posix/timer: allow usage with external clocks
Module: xenomai-3 Branch: stable-3.0.x Commit: e6cd9610215b06ee85272f57702354a7e38b5f7c URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=e6cd9610215b06ee85272f57702354a7e38b5f7c Author: Philippe GerumDate: 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 + + if (__COBALT_CLOCK_EXT_P(clock_id)) { + nr = __COBALT_CLOCK_EXT_INDEX(clock_id); + xnlock_get_irqsave(, s); + if (test_bit(nr, cobalt_clock_extids)) + clock = external_clocks[nr]; + xnlock_put_irqrestore(, 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 10 +struct xnclock; + static inline void ns2ts(struct timespec *ts, xnticks_t nsecs) { ts->tv_sec = xnclock_divrem_billion(nsecs, >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(>timerbase, , cobalt_timer_handler, + clock = cobalt_clock_find(timer->clockid); + if (IS_ERR(clock)) + return ERR_PTR(PTR_ERR(clock)); + + xntimer_init(>timerbase, clock, cobalt_timer_handler, target->threadbase.sched,