Module: xenomai-gch Branch: for-forge Commit: d67f5d8763dfcc690bb1b659778b15c370494340 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=d67f5d8763dfcc690bb1b659778b15c370494340
Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org> Date: Sun Dec 11 19:53:58 2011 +0100 cobalt: move timers system calls to timer.c --- include/cobalt/time.h | 48 +---------- kernel/cobalt/syscall.c | 96 +------------------ kernel/cobalt/timer.c | 235 +++++++++++++++++++++++------------------------ kernel/cobalt/timer.h | 15 +++ 4 files changed, 138 insertions(+), 256 deletions(-) diff --git a/include/cobalt/time.h b/include/cobalt/time.h index 3c10681..8e9f66a 100644 --- a/include/cobalt/time.h +++ b/include/cobalt/time.h @@ -65,53 +65,7 @@ */ #define CLOCK_HOST_REALTIME 42 -#if defined(__KERNEL__) || defined(__XENO_SIM__) - -struct sigevent; - -struct timespec; - -#ifdef __cplusplus -extern "C" { -#endif - -int clock_getres(clockid_t clock_id, - struct timespec *res); - -int clock_gettime(clockid_t clock_id, - struct timespec *tp); - -int clock_settime(clockid_t clock_id, - const struct timespec *tp); - -int clock_nanosleep(clockid_t clock_id, - int flags, - const struct timespec *rqtp, - struct timespec *rmtp); - -int nanosleep(const struct timespec *rqtp, - struct timespec *rmtp); - -int timer_create(clockid_t clockid, - const struct sigevent *__restrict__ evp, - timer_t *__restrict__ timerid); - -int timer_delete(timer_t timerid); - -int timer_settime(timer_t timerid, - int flags, - const struct itimerspec *__restrict__ value, - struct itimerspec *__restrict__ ovalue); - -int timer_gettime(timer_t timerid, struct itimerspec *value); - -int timer_getoverrun(timer_t timerid); - -#ifdef __cplusplus -} -#endif - -#else /* !(__KERNEL__ || __XENO_SIM__) */ +#if !(defined(__KERNEL__) || defined(__XENO_SIM__)) #ifdef __cplusplus extern "C" { diff --git a/kernel/cobalt/syscall.c b/kernel/cobalt/syscall.c index 286c5f7..4420f23 100644 --- a/kernel/cobalt/syscall.c +++ b/kernel/cobalt/syscall.c @@ -43,92 +43,6 @@ int cobalt_muxid; -static int __timer_create(clockid_t clock, - const struct sigevent __user *u_sev, - timer_t __user *u_tm) -{ - union __xeno_sem sm, __user *u_sem; - struct sigevent sev, *evp = &sev; - timer_t tm; - int ret; - - if (u_sev) { - if (__xn_safe_copy_from_user(&sev, u_sev, sizeof(sev))) - return -EFAULT; - - if (sev.sigev_notify == SIGEV_THREAD_ID) { - u_sem = sev.sigev_value.sival_ptr; - - if (__xn_safe_copy_from_user(&sm, u_sem, sizeof(sm))) - return -EFAULT; - - sev.sigev_value.sival_ptr = &sm.native_sem; - } - } else - evp = NULL; - - ret = timer_create(clock, evp, &tm); - if (ret) - return -thread_get_errno(); - - if (__xn_safe_copy_to_user(u_tm, &tm, sizeof(tm))) { - timer_delete(tm); - return -EFAULT; - } - - return 0; -} - -static int __timer_delete(timer_t tm) -{ - int ret = timer_delete(tm); - return ret == 0 ? 0 : -thread_get_errno(); -} - -static int __timer_settime(timer_t tm, - int flags, - const struct itimerspec __user *u_newval, - struct itimerspec __user *u_oldval) -{ - struct itimerspec newv, oldv, *oldvp; - int ret; - - oldvp = u_oldval == 0 ? NULL : &oldv; - - if (__xn_safe_copy_from_user(&newv, u_newval, sizeof(newv))) - return -EFAULT; - - ret = timer_settime(tm, flags, &newv, oldvp); - if (ret) - return -thread_get_errno(); - - if (oldvp && __xn_safe_copy_to_user(u_oldval, oldvp, sizeof(oldv))) { - timer_settime(tm, flags, oldvp, NULL); - return -EFAULT; - } - - return 0; -} - -static int __timer_gettime(timer_t tm, - struct itimerspec __user *u_val) -{ - struct itimerspec val; - int ret; - - ret = timer_gettime(tm, &val); - if (ret) - return -thread_get_errno(); - - return __xn_safe_copy_to_user(u_val, &val, sizeof(val)); -} - -static int __timer_getoverrun(timer_t tm) -{ - int ret = timer_getoverrun(tm); - return ret >= 0 ? ret : -thread_get_errno(); -} - static int fd_valid_p(int fd) { cobalt_assoc_t *assoc; @@ -359,11 +273,11 @@ static struct xnsysent __systab[] = { SKINCALL_DEF(sc_cobalt_mq_timedsend, cobalt_mq_timedsend, primary), SKINCALL_DEF(sc_cobalt_mq_receive, cobalt_mq_receive, primary), SKINCALL_DEF(sc_cobalt_mq_timedreceive, cobalt_mq_timedreceive, primary), - SKINCALL_DEF(sc_cobalt_timer_create, __timer_create, any), - SKINCALL_DEF(sc_cobalt_timer_delete, __timer_delete, any), - SKINCALL_DEF(sc_cobalt_timer_settime, __timer_settime, primary), - SKINCALL_DEF(sc_cobalt_timer_gettime, __timer_gettime, any), - SKINCALL_DEF(sc_cobalt_timer_getoverrun, __timer_getoverrun, any), + SKINCALL_DEF(sc_cobalt_timer_create, cobalt_timer_create, any), + SKINCALL_DEF(sc_cobalt_timer_delete, cobalt_timer_delete, any), + SKINCALL_DEF(sc_cobalt_timer_settime, cobalt_timer_settime, primary), + SKINCALL_DEF(sc_cobalt_timer_gettime, cobalt_timer_gettime, any), + SKINCALL_DEF(sc_cobalt_timer_getoverrun, cobalt_timer_getoverrun, any), SKINCALL_DEF(sc_cobalt_mutexattr_init, cobalt_mutexattr_init, any), SKINCALL_DEF(sc_cobalt_mutexattr_destroy, cobalt_mutexattr_destroy, any), SKINCALL_DEF(sc_cobalt_mutexattr_gettype, cobalt_mutexattr_gettype, any), diff --git a/kernel/cobalt/timer.c b/kernel/cobalt/timer.c index 2dba4a2..7e76003 100644 --- a/kernel/cobalt/timer.c +++ b/kernel/cobalt/timer.c @@ -33,8 +33,7 @@ typedef struct { siginfo_t info; xnpholder_t link; -#define link2siginfo(iaddr) \ - ((cobalt_siginfo_t *)(((char *)iaddr) - offsetof(cobalt_siginfo_t, link))) +#define link2siginfo(iaddr) container_of(iaddr, cobalt_siginfo_t, link) } cobalt_siginfo_t; @@ -46,8 +45,7 @@ struct cobalt_timer { xnholder_t link; /* link in process or global timers queue. */ -#define link2tm(laddr, member) \ - ((struct cobalt_timer *)(((char *)laddr) - offsetof(struct cobalt_timer, member))) +#define link2tm(laddr, member) container_of(laddr, struct cobalt_timer, member) xnholder_t tlink; /* link in thread timers queue. */ @@ -79,31 +77,6 @@ static void cobalt_base_timer_handler(xntimer_t *xntimer) timer->si.info.si_value.sival_ptr = NULL; } -/* Must be called with nklock locked, irq off. */ -void cobalt_timer_notified(cobalt_siginfo_t * si) -{ - struct cobalt_timer *timer = link2tm(si, si); - xnticks_t now; - - /* We need this two staged overruns count. The overruns count returned by - timer_getoverrun is the count of overruns which occured between the time - the signal was queued and the time this signal was accepted by the - application. - In other words, if the timer elapses again after cobalt_timer_notified get - called (i.e. the signal is accepted by the application), the signal shall - be queued again, and later overruns should count for that new - notification, not the one the application is currently handling. */ - - if (!xntimer_interval(&timer->timerbase)) { - timer->overruns = 0; - return; - } - - now = xnclock_read_raw(); - - timer->overruns = xntimer_get_overruns(&timer->timerbase, now); -} - /** * Create a timer object. * @@ -145,12 +118,12 @@ void cobalt_timer_notified(cobalt_siginfo_t * si) * Specification.</a> * */ -int timer_create(clockid_t clockid, - const struct sigevent *__restrict__ evp, - timer_t * __restrict__ timerid) +static inline int timer_create(clockid_t clockid, + const struct sigevent *__restrict__ evp, + timer_t * __restrict__ timerid) { struct __shadow_sem *shadow_sem = NULL; - int err = EINVAL, semval, signo; + int err = -EINVAL, semval, signo; struct cobalt_timer *timer; xnholder_t *holder; sem_t *sem; @@ -172,7 +145,7 @@ int timer_create(clockid_t clockid, signo = SIGALRM; if (evp) { if (evp->sigev_notify != SIGEV_THREAD_ID) { - err = ENOSYS; + err = -ENOSYS; goto error; } @@ -191,7 +164,7 @@ int timer_create(clockid_t clockid, holder = getq(&timer_freeq); if (holder == NULL) { - err = EAGAIN; + err = -EAGAIN; goto unlock_and_error; } @@ -214,25 +187,25 @@ int timer_create(clockid_t clockid, appendq(&cobalt_kqueues(0)->timerq, &timer->link); xnlock_put_irqrestore(&nklock, s); - *timerid = (timer_t) (timer - timer_pool); + *timerid = (timer_t)(timer - timer_pool); return 0; unlock_and_error: xnlock_put_irqrestore(&nklock, s); error: - thread_set_errno(err); - return -1; + return err; } -int cobalt_timer_delete_inner(timer_t timerid, cobalt_kqueues_t *q, int force) +static inline int +cobalt_timer_delete_inner(timer_t timerid, cobalt_kqueues_t *q, int force) { struct cobalt_timer *timer; spl_t s; int err; if ((unsigned)timerid >= COBALT_TIMER_MAX) { - err = EINVAL; + err = -EINVAL; goto error; } @@ -241,12 +214,12 @@ int cobalt_timer_delete_inner(timer_t timerid, cobalt_kqueues_t *q, int force) timer = &timer_pool[(unsigned long)timerid]; if (!xntimer_active_p(&timer->timerbase)) { - err = EINVAL; + err = -EINVAL; goto unlock_and_error; } if (!force && timer->owningq != cobalt_kqueues(0)) { - err = EPERM; + err = -EPERM; goto unlock_and_error; } @@ -265,34 +238,12 @@ int cobalt_timer_delete_inner(timer_t timerid, cobalt_kqueues_t *q, int force) unlock_and_error: xnlock_put_irqrestore(&nklock, s); error: - thread_set_errno(err); - return -1; + return err; } -/** - * Delete a timer object. - * - * This service deletes the timer @a timerid. - * - * @param timerid identifier of the timer to be removed; - * - * @retval 0 on success; - * @retval -1 with @a errno set if: - * - EINVAL, @a timerid is invalid; - * - EPERM, the timer @a timerid does not belong to the current process. - * - * @see - * <a href="http://www.opengroup.org/onlinepubs/000095399/functions/timer_delete.html"> - * Specification.</a> - * - */ -int timer_delete(timer_t timerid) -{ - return cobalt_timer_delete_inner(timerid, cobalt_kqueues(0), 0); -} - -static void cobalt_timer_gettime_inner(struct cobalt_timer *__restrict__ timer, - struct itimerspec *__restrict__ value) +static inline void +cobalt_timer_gettime_inner(struct cobalt_timer *__restrict__ timer, + struct itimerspec *__restrict__ value) { if (xntimer_running_p(&timer->timerbase)) { ns2ts(&value->it_value, @@ -356,30 +307,30 @@ static void cobalt_timer_gettime_inner(struct cobalt_timer *__restrict__ timer, * Specification.</a> * */ -int timer_settime(timer_t timerid, - int flags, - const struct itimerspec *__restrict__ value, - struct itimerspec *__restrict__ ovalue) +static inline int +timer_settime(timer_t timerid, int flags, + const struct itimerspec *__restrict__ value, + struct itimerspec *__restrict__ ovalue) { pthread_t cur = cobalt_current_thread(); struct cobalt_timer *timer; spl_t s; int err; - if (!cur || xnpod_interrupt_p()) { - err = EPERM; + if (!cur) { + err = -EPERM; goto error; } if ((unsigned)timerid >= COBALT_TIMER_MAX) { - err = EINVAL; + err = -EINVAL; goto error; } if ((unsigned long)value->it_value.tv_nsec >= ONE_BILLION || ((unsigned long)value->it_interval.tv_nsec >= ONE_BILLION && (value->it_value.tv_sec != 0 || value->it_value.tv_nsec != 0))) { - err = EINVAL; + err = -EINVAL; goto error; } @@ -388,13 +339,13 @@ int timer_settime(timer_t timerid, timer = &timer_pool[(unsigned long)timerid]; if (!xntimer_active_p(&timer->timerbase)) { - err = EINVAL; + err = -EINVAL; goto unlock_and_error; } #if XENO_DEBUG(POSIX) if (timer->owningq != cobalt_kqueues(0)) { - err = EPERM; + err = -EPERM; goto unlock_and_error; } #endif /* XENO_DEBUG(POSIX) */ @@ -440,8 +391,7 @@ int timer_settime(timer_t timerid, unlock_and_error: xnlock_put_irqrestore(&nklock, s); error: - thread_set_errno(err); - return -1; + return err; } /** @@ -470,14 +420,14 @@ int timer_settime(timer_t timerid, * Specification.</a> * */ -int timer_gettime(timer_t timerid, struct itimerspec *value) +static inline int timer_gettime(timer_t timerid, struct itimerspec *value) { struct cobalt_timer *timer; spl_t s; int err; if ((unsigned)timerid >= COBALT_TIMER_MAX) { - err = EINVAL; + err = -EINVAL; goto error; } @@ -486,13 +436,13 @@ int timer_gettime(timer_t timerid, struct itimerspec *value) timer = &timer_pool[(unsigned long)timerid]; if (!xntimer_active_p(&timer->timerbase)) { - err = EINVAL; + err = -EINVAL; goto unlock_and_error; } #if XENO_DEBUG(POSIX) if (timer->owningq != cobalt_kqueues(0)) { - err = EPERM; + err = -EPERM; goto unlock_and_error; } #endif /* XENO_DEBUG(POSIX) */ @@ -506,38 +456,94 @@ int timer_gettime(timer_t timerid, struct itimerspec *value) unlock_and_error: xnlock_put_irqrestore(&nklock, s); error: - thread_set_errno(err); - return -1; + return err; } -/** - * Get expiration overruns count since the most recent timer expiration - * signal delivery. - * - * This service returns @a timerid expiration overruns count since the most - * recent timer expiration signal delivery. If this count is more than @a - * DELAYTIMER_MAX expirations, @a DELAYTIMER_MAX is returned. - * - * @param timerid Timer identifier. - * - * @return the overruns count on success; - * @return -1 with @a errno set if: - * - EINVAL, @a timerid is invalid; - * - EPERM, the timer @a timerid does not belong to the current process. - * - * @see - * <a href="http://www.opengroup.org/onlinepubs/000095399/functions/timer_getoverrun.html"> - * Specification.</a> - * - */ -int timer_getoverrun(timer_t timerid) +int cobalt_timer_delete(timer_t timerid) +{ + return cobalt_timer_delete_inner(timerid, cobalt_kqueues(0), 0); +} + +int cobalt_timer_create(clockid_t clock, + const struct sigevent __user *u_sev, + timer_t __user *u_tm) +{ + union __xeno_sem sm, __user *u_sem; + struct sigevent sev, *evp = &sev; + timer_t tm; + int ret; + + if (u_sev) { + if (__xn_safe_copy_from_user(&sev, u_sev, sizeof(sev))) + return -EFAULT; + + if (sev.sigev_notify == SIGEV_THREAD_ID) { + u_sem = sev.sigev_value.sival_ptr; + + if (__xn_safe_copy_from_user(&sm, u_sem, sizeof(sm))) + return -EFAULT; + + sev.sigev_value.sival_ptr = &sm.native_sem; + } + } else + evp = NULL; + + ret = timer_create(clock, evp, &tm); + if (ret) + return ret; + + if (__xn_safe_copy_to_user(u_tm, &tm, sizeof(tm))) { + cobalt_timer_delete(tm); + return -EFAULT; + } + + return 0; +} + +int cobalt_timer_settime(timer_t tm, int flags, + const struct itimerspec __user *u_newval, + struct itimerspec __user *u_oldval) +{ + struct itimerspec newv, oldv, *oldvp; + int ret; + + oldvp = u_oldval == 0 ? NULL : &oldv; + + if (__xn_safe_copy_from_user(&newv, u_newval, sizeof(newv))) + return -EFAULT; + + ret = timer_settime(tm, flags, &newv, oldvp); + if (ret) + return ret; + + if (oldvp && __xn_safe_copy_to_user(u_oldval, oldvp, sizeof(oldv))) { + timer_settime(tm, flags, oldvp, NULL); + return -EFAULT; + } + + return 0; +} + +int cobalt_timer_gettime(timer_t tm, struct itimerspec __user *u_val) +{ + struct itimerspec val; + int ret; + + ret = timer_gettime(tm, &val); + if (ret) + return ret; + + return __xn_safe_copy_to_user(u_val, &val, sizeof(val)); +} + +int cobalt_timer_getoverrun(timer_t timerid) { struct cobalt_timer *timer; int overruns, err; spl_t s; if ((unsigned)timerid >= COBALT_TIMER_MAX) { - err = EINVAL; + err = -EINVAL; goto error; } @@ -546,13 +552,13 @@ int timer_getoverrun(timer_t timerid) timer = &timer_pool[(unsigned long)timerid]; if (!xntimer_active_p(&timer->timerbase)) { - err = EINVAL; + err = -EINVAL; goto unlock_and_error; } #if XENO_DEBUG(POSIX) if (timer->owningq != cobalt_kqueues(0)) { - err = EPERM; + err = -EPERM; goto unlock_and_error; } #endif /* XENO_DEBUG(POSIX) */ @@ -566,8 +572,7 @@ int timer_getoverrun(timer_t timerid) unlock_and_error: xnlock_put_irqrestore(&nklock, s); error: - thread_set_errno(err); - return -1; + return err; } void cobalt_timer_init_thread(pthread_t new_thread) @@ -627,9 +632,3 @@ void cobalt_timer_pkg_cleanup(void) } /*@}*/ - -EXPORT_SYMBOL_GPL(timer_create); -EXPORT_SYMBOL_GPL(timer_delete); -EXPORT_SYMBOL_GPL(timer_settime); -EXPORT_SYMBOL_GPL(timer_gettime); -EXPORT_SYMBOL_GPL(timer_getoverrun); diff --git a/kernel/cobalt/timer.h b/kernel/cobalt/timer.h index c94b8f6..cd5c719 100644 --- a/kernel/cobalt/timer.h +++ b/kernel/cobalt/timer.h @@ -21,6 +21,21 @@ #include "thread.h" /* For struct itimerspec. */ +int cobalt_timer_create(clockid_t clock, + const struct sigevent __user *u_sev, + timer_t __user *u_tm); + +int cobalt_timer_delete(timer_t tm); + +int cobalt_timer_settime(timer_t tm, + int flags, + const struct itimerspec __user *u_newval, + struct itimerspec __user *u_oldval); + +int cobalt_timer_gettime(timer_t tm, struct itimerspec __user *u_val); + +int cobalt_timer_getoverrun(timer_t tm); + void cobalt_timer_init_thread(pthread_t new); void cobalt_timer_cleanup_thread(pthread_t zombie); _______________________________________________ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git