Module: xenomai-forge Branch: master Commit: ff9bf8b1325bd5a34a65c8f5358803958831d836 URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=ff9bf8b1325bd5a34a65c8f5358803958831d836
Author: Philippe Gerum <r...@xenomai.org> Date: Mon Jan 20 16:08:32 2014 +0100 cobalt/posix/timer: fix timer creation sequence wrt extension code We must call the extension code from atomic context when present. In addition, the companion siginfo data must be fully built before we do that. --- kernel/cobalt/posix/process.h | 2 -- kernel/cobalt/posix/syscall.c | 3 +-- kernel/cobalt/posix/timer.c | 60 ++++++++++++++++++++--------------------- 3 files changed, 30 insertions(+), 35 deletions(-) diff --git a/kernel/cobalt/posix/process.h b/kernel/cobalt/posix/process.h index fb79b45..1ba7e00 100644 --- a/kernel/cobalt/posix/process.h +++ b/kernel/cobalt/posix/process.h @@ -37,8 +37,6 @@ struct cobalt_process { struct list_head uqds; struct rb_root usems; struct list_head sigwaiters; - - /* timers */ DECLARE_BITMAP(timers_map, CONFIG_XENO_OPT_NRTIMERS); struct cobalt_timer *timers[CONFIG_XENO_OPT_NRTIMERS]; }; diff --git a/kernel/cobalt/posix/syscall.c b/kernel/cobalt/posix/syscall.c index 5504161..4f4759b 100644 --- a/kernel/cobalt/posix/syscall.c +++ b/kernel/cobalt/posix/syscall.c @@ -57,9 +57,8 @@ static void *cobalt_process_attach(void) INIT_LIST_HEAD(&cc->kqueues.monitorq); INIT_LIST_HEAD(&cc->kqueues.eventq); INIT_LIST_HEAD(&cc->uqds); - xntree_init(&cc->usems); INIT_LIST_HEAD(&cc->sigwaiters); - + xntree_init(&cc->usems); bitmap_fill(cc->timers_map, CONFIG_XENO_OPT_NRTIMERS); return cc; diff --git a/kernel/cobalt/posix/timer.c b/kernel/cobalt/posix/timer.c index e38ed3d..cbb9938 100644 --- a/kernel/cobalt/posix/timer.c +++ b/kernel/cobalt/posix/timer.c @@ -184,63 +184,61 @@ static inline int timer_create(clockid_t clockid, if (timer == NULL) return -ENOMEM; - /* We may bail out early, don't unlink yet. */ + timer->sigp.si.si_errno = 0; + timer->sigp.si.si_code = SI_TIMER; + timer->sigp.si.si_overrun = 0; + INIT_LIST_HEAD(&timer->sigp.next); + timer->clockid = clockid; + timer->overruns = 0; + + xnlock_get_irqsave(&nklock, s); + + ret = timer_alloc_id(cc); + if (ret < 0) + goto out; + + timer_id = ret; + if (evp == NULL) { + timer->sigp.si.si_int = timer_id; signo = SIGALRM; } else { if (evp->sigev_notify == SIGEV_NONE) signo = 0; /* Don't notify. */ else { signo = evp->sigev_signo; - if (signo < 1 || signo > _NSIG) { - ret = -EINVAL; - goto err_free_timer; - } + if (signo < 1 || signo > _NSIG) + goto fail; timer->sigp.si.si_value = evp->sigev_value; } } timer->sigp.si.si_signo = signo; - timer->sigp.si.si_errno = 0; - timer->sigp.si.si_code = SI_TIMER; - timer->sigp.si.si_overrun = 0; - INIT_LIST_HEAD(&timer->sigp.next); - timer->clockid = clockid; - timer->overruns = 0; + timer->sigp.si.si_tid = timer_id; + timer->id = timer_id; target = timer_init(timer, evp); - if (target == NULL) { - ret = -EINVAL; - goto err_free_timer; - } + if (target == NULL) + goto fail; + if (IS_ERR(target)) { ret = PTR_ERR(target); - goto err_free_timer; + goto fail; } timer->target = xnthread_host_pid(&target->threadbase); - - xnlock_get_irqsave(&nklock, s); - ret = timer_alloc_id(cc); - if (ret < 0) - goto unlock_and_error; - - timer_id = ret; - if (evp == NULL) - timer->sigp.si.si_int = timer_id; - timer->sigp.si.si_tid = timer_id; cc->timers[timer_id] = timer; - timer->id = timer_id; + xnlock_put_irqrestore(&nklock, s); *timerid = timer_id; return 0; - -unlock_and_error: +fail: + timer_free_id(cc, timer_id); +out: xnlock_put_irqrestore(&nklock, s); - - err_free_timer: + kfree(timer); return ret; _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git