Module: xenomai-forge
Branch: next
Commit: 7532802bcc9310a94af20ae8547970a9650e6384
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=7532802bcc9310a94af20ae8547970a9650e6384

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Fri Dec  6 21:27:51 2013 +0100

cobalt: use registry for condvars

---

 include/cobalt/uapi/cond.h |    2 +-
 kernel/cobalt/posix/cond.c |   64 +++++++++++++++++++++++++++++---------------
 kernel/cobalt/posix/cond.h |    1 +
 3 files changed, 44 insertions(+), 23 deletions(-)

diff --git a/include/cobalt/uapi/cond.h b/include/cobalt/uapi/cond.h
index de37315..0c6157a 100644
--- a/include/cobalt/uapi/cond.h
+++ b/include/cobalt/uapi/cond.h
@@ -27,7 +27,7 @@ union cobalt_cond_union {
        struct __shadow_cond {
                unsigned int magic;
                struct cobalt_condattr attr;
-               struct cobalt_cond *cond;
+               xnhandle_t handle;
                union {
                        unsigned int pending_signals_offset;
                        unsigned long *pending_signals;
diff --git a/kernel/cobalt/posix/cond.c b/kernel/cobalt/posix/cond.c
index 5572431..87dd09d 100644
--- a/kernel/cobalt/posix/cond.c
+++ b/kernel/cobalt/posix/cond.c
@@ -54,16 +54,24 @@
 #include "clock.h"
 
 static inline void
-cond_destroy_internal(struct cobalt_cond *cond, struct cobalt_kqueues *q)
+cond_destroy_internal(xnhandle_t handle, struct cobalt_kqueues *q)
 {
+       struct cobalt_cond *cond;
        spl_t s;
 
        xnlock_get_irqsave(&nklock, s);
+       cond = xnregistry_fetch(handle);
+       if (!cobalt_obj_active(cond, COBALT_COND_MAGIC, typeof(*cond))) {
+               xnlock_put_irqrestore(&nklock, s);
+               return;
+       }
+       xnregistry_remove(handle);
        list_del(&cond->link);
        /* synchbase wait queue may not be empty only when this function is
           called from cobalt_cond_pkg_cleanup, hence the absence of
           xnsched_run(). */
        xnsynch_destroy(&cond->synchbase);
+       cobalt_mark_deleted(cond);
        xnlock_put_irqrestore(&nklock, s);
        xnheap_free(&xnsys_ppd_get(cond->attr.pshared)->sem_heap,
                    cond->pending_signals);
@@ -99,9 +107,9 @@ static inline int
 pthread_cond_init(struct __shadow_cond *cnd, const pthread_condattr_t *attr)
 {
        int synch_flags = XNSYNCH_PRIO | XNSYNCH_NOPIP, err;
-       struct list_head *condq, *entry;
+       struct cobalt_cond *cond, *old_cond;
+       struct list_head *condq;
        struct xnsys_ppd *sys_ppd;
-       struct cobalt_cond *cond;
        spl_t s;
 
        if (attr == NULL)
@@ -139,18 +147,23 @@ pthread_cond_init(struct __shadow_cond *cnd, const 
pthread_condattr_t *attr)
        if (cnd->magic != COBALT_COND_MAGIC || list_empty(condq))
                goto do_init;
 
-       list_for_each(entry, condq) {
-               if (entry == &cnd->cond->link) {
-                       if (attr->pshared) {
-                               cond_destroy_internal(cnd->cond,
-                                                     cobalt_kqueues(1));
-                               goto do_init;
-                       }
-                       err = -EBUSY;
-                       goto err_free_pending_signals;
-               }
+       old_cond = xnregistry_fetch(cnd->handle);
+       if (!cobalt_obj_active(old_cond, COBALT_COND_MAGIC, typeof(*old_cond)))
+               goto do_init;
+
+       if (attr->pshared == 0) {
+               err = -EBUSY;
+               goto err_free_pending_signals;
        }
+       xnlock_put_irqrestore(&nklock, s);
+       cond_destroy_internal(cnd->handle, cobalt_kqueues(1));
+       xnlock_get_irqsave(&nklock, s);
 do_init:
+       err = xnregistry_enter("", cond, &cond->handle, NULL);
+       if (err < 0)
+               goto err_free_pending_signals;
+
+       cnd->handle = cond->handle;
        cnd->attr = *attr;
        cnd->pending_signals_offset =
                xnheap_mapped_offset(&sys_ppd->sem_heap,
@@ -158,7 +171,6 @@ do_init:
        cnd->mutex_datp = (struct mutex_dat *)~0UL;
 
        cnd->magic = COBALT_COND_MAGIC;
-       cnd->cond = cond;
 
        cond->magic = COBALT_COND_MAGIC;
        xnsynch_init(&cond->synchbase, synch_flags, NULL);
@@ -205,11 +217,16 @@ do_init:
 static inline int pthread_cond_destroy(struct __shadow_cond *cnd)
 {
        struct cobalt_cond *cond;
+       int pshared;
        spl_t s;
 
        xnlock_get_irqsave(&nklock, s);
-
-       cond = cnd->cond;
+       cond = xnregistry_fetch(cnd->handle);
+       if (cond == NULL) {
+               xnlock_put_irqrestore(&nklock, s);
+               return -EINVAL;
+       }
+       
        if (!cobalt_obj_active(cnd, COBALT_COND_MAGIC, struct __shadow_cond)
            || !cobalt_obj_active(cond, COBALT_COND_MAGIC, struct cobalt_cond)) 
{
                xnlock_put_irqrestore(&nklock, s);
@@ -227,11 +244,10 @@ static inline int pthread_cond_destroy(struct 
__shadow_cond *cnd)
        }
 
        cobalt_mark_deleted(cnd);
-       cobalt_mark_deleted(cond);
-
+       pshared = cond->attr.pshared;
        xnlock_put_irqrestore(&nklock, s);
 
-       cond_destroy_internal(cond, cobalt_kqueues(cond->attr.pshared));
+       cond_destroy_internal(cnd->handle, cobalt_kqueues(pshared));
 
        return 0;
 }
@@ -403,7 +419,9 @@ int cobalt_cond_wait_prologue(struct __shadow_cond __user 
*u_cnd,
        xnhandle_t handle;
        int err, perr = 0;
 
-       __xn_get_user(cnd, &u_cnd->cond);
+       __xn_get_user(handle, &u_cnd->handle);
+       cnd = xnregistry_fetch(handle);
+
        __xn_get_user(handle, &u_mx->handle);
        mx = xnregistry_fetch(handle);
 
@@ -461,7 +479,9 @@ int cobalt_cond_wait_epilogue(struct __shadow_cond __user 
*u_cnd,
        xnhandle_t handle;
        int err;
 
-       __xn_get_user(cnd, &u_cnd->cond);
+       __xn_get_user(handle, &u_cnd->handle);
+       cnd = xnregistry_fetch(handle);
+
        __xn_get_user(handle, &u_mx->handle);
        mx = xnregistry_fetch(handle);
 
@@ -515,7 +535,7 @@ void cobalt_condq_cleanup(struct cobalt_kqueues *q)
 
        list_for_each_entry_safe(cond, tmp, &q->condq, link) {
                xnlock_put_irqrestore(&nklock, s);
-               cond_destroy_internal(cond, q);
+               cond_destroy_internal(cond->handle, q);
 #if XENO_DEBUG(COBALT)
                printk(XENO_INFO "deleting Cobalt condvar %p\n", cond);
 #endif /* XENO_DEBUG(COBALT) */
diff --git a/kernel/cobalt/posix/cond.h b/kernel/cobalt/posix/cond.h
index 26f5544..84946df 100644
--- a/kernel/cobalt/posix/cond.h
+++ b/kernel/cobalt/posix/cond.h
@@ -39,6 +39,7 @@ struct cobalt_cond {
        pthread_condattr_t attr;
        struct cobalt_mutex *mutex;
        struct cobalt_kqueues *owningq;
+       xnhandle_t handle;
 };
 
 extern const pthread_condattr_t cobalt_default_cond_attr;


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to