Module: xenomai-forge
Branch: next
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

Reply via email to