Module: xenomai-forge
Branch: master
Commit: 6d4f960c7f1e065c90129395c6ca47d64f6b6d72
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=6d4f960c7f1e065c90129395c6ca47d64f6b6d72

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Thu Dec  5 22:07:48 2013 +0100

cobalt/mutex: export through registry

---

 include/cobalt/uapi/mutex.h |    2 +-
 kernel/cobalt/posix/mutex.c |  127 +++++++++++++++++++++++++++++--------------
 kernel/cobalt/posix/mutex.h |    1 +
 3 files changed, 88 insertions(+), 42 deletions(-)

diff --git a/include/cobalt/uapi/mutex.h b/include/cobalt/uapi/mutex.h
index dec09e2..88c95e7 100644
--- a/include/cobalt/uapi/mutex.h
+++ b/include/cobalt/uapi/mutex.h
@@ -32,7 +32,7 @@ union cobalt_mutex_union {
        struct __shadow_mutex {
                unsigned int magic;
                unsigned int lockcnt;
-               struct cobalt_mutex *mutex;
+               xnhandle_t handle;
                union {
                        unsigned int dat_offset;
                        struct mutex_dat *dat;
diff --git a/kernel/cobalt/posix/mutex.c b/kernel/cobalt/posix/mutex.c
index 2b1c515..c94ed79 100644
--- a/kernel/cobalt/posix/mutex.c
+++ b/kernel/cobalt/posix/mutex.c
@@ -62,6 +62,7 @@ static int cobalt_mutex_init_inner(struct __shadow_mutex 
*shadow,
        struct xnsys_ppd *sys_ppd;
        struct cobalt_kqueues *kq;
        spl_t s;
+       int err;
 
        if (!attr)
                attr = &cobalt_default_mutex_attr;
@@ -71,9 +72,12 @@ static int cobalt_mutex_init_inner(struct __shadow_mutex 
*shadow,
 
        kq = cobalt_kqueues(attr->pshared);
        sys_ppd = xnsys_ppd_get(attr->pshared);
+       err = xnregistry_enter("", mutex, &shadow->handle, NULL);
+       if (err < 0)
+               return err;
 
+       mutex->handle = shadow->handle;
        shadow->magic = COBALT_MUTEX_MAGIC;
-       shadow->mutex = mutex;
        shadow->lockcnt = 0;
 
        shadow->attr = *attr;
@@ -97,12 +101,21 @@ static int cobalt_mutex_init_inner(struct __shadow_mutex 
*shadow,
        return 0;
 }
 
-static void cobalt_mutex_destroy_inner(struct cobalt_mutex *mutex,
-                                      struct cobalt_kqueues *q)
+static void 
+cobalt_mutex_destroy_inner(xnhandle_t handle, struct cobalt_kqueues *q)
 {
+       struct cobalt_mutex *mutex;
        spl_t s;
 
        xnlock_get_irqsave(&nklock, s);
+       mutex = xnregistry_fetch(handle);
+       if (!cobalt_obj_active(mutex, COBALT_MUTEX_MAGIC, typeof(*mutex))) {
+               xnlock_put_irqrestore(&nklock, s);
+               printk("mutex_destroy: invalid mutex %x\n", 
+                       mutex ? mutex->magic : ~0);
+               return;
+       }
+       xnregistry_remove(handle);
        list_del(&mutex->link);
        /*
         * synchbase wait queue may not be empty only when this
@@ -110,6 +123,7 @@ static void cobalt_mutex_destroy_inner(struct cobalt_mutex 
*mutex,
         * absence of xnsched_run().
         */
        xnsynch_destroy(&mutex->synchbase);
+       cobalt_mark_deleted(mutex);
        xnlock_put_irqrestore(&nklock, s);
 
        xnheap_free(&xnsys_ppd_get(mutex->attr.pshared)->sem_heap,
@@ -240,30 +254,23 @@ int cobalt_mutex_timedlock_break(struct cobalt_mutex 
*mutex,
 
 int cobalt_mutex_check_init(struct __shadow_mutex __user *u_mx)
 {
-       struct list_head *mutexq, *entry;
        struct cobalt_mutex *mutex;
-       int qnr;
+       xnhandle_t handle;
+       int err;
        spl_t s;
 
-       __xn_get_user(mutex, &u_mx->mutex);
+       __xn_get_user(handle, &u_mx->handle);
 
-       for (qnr = 0; qnr < 2; qnr++) {
-               mutexq = &cobalt_kqueues(qnr)->mutexq;
-               xnlock_get_irqsave(&nklock, s);
-               if (!list_empty(mutexq)) {
-                       list_for_each(entry, mutexq) {
-                               if (entry == &mutex->link)
-                                       goto busy;
-                       }
-               }
-               xnlock_put_irqrestore(&nklock, s);
-       }
+       xnlock_get_irqsave(&nklock, s);
+       mutex = xnregistry_fetch(handle);
+       if (cobalt_obj_active(mutex, COBALT_MUTEX_MAGIC, typeof(*mutex)))
+               /* mutex is already in a queue. */
+               err = -EBUSY;
+       else
+               err = 0;
 
-       return 0;
-busy:
        xnlock_put_irqrestore(&nklock, s);
-       /* mutex is already in a queue. */
-       return -EBUSY;
+       return err;
 }
 
 int cobalt_mutex_init(struct __shadow_mutex __user *u_mx,
@@ -313,23 +320,39 @@ int cobalt_mutex_destroy(struct __shadow_mutex __user 
*u_mx)
 {
        struct cobalt_mutex *mutex;
        struct __shadow_mutex mx;
+       spl_t s;
+       int err;
 
        if (__xn_safe_copy_from_user(&mx, u_mx, sizeof(mx)))
                return -EFAULT;
 
-       mutex = mx.mutex;
-       if (cobalt_kqueues(mutex->attr.pshared) != mutex->owningq)
-               return -EPERM;
+       xnlock_get_irqsave(&nklock, s);
+       mutex = xnregistry_fetch(mx.handle);
+       if (!cobalt_obj_active(mutex, COBALT_MUTEX_MAGIC, typeof(*mutex))) {
+               err = -EINVAL;
+               goto err_unlock;
+       }
+       if (cobalt_kqueues(mutex->attr.pshared) != mutex->owningq) {
+               err = -EPERM;
+               goto err_unlock;
+       }
 
        if (xnsynch_fast_owner_check(mutex->synchbase.fastlock,
-                                    XN_NO_HANDLE) != 0)
-               return -EBUSY;
+                                       XN_NO_HANDLE) != 0) {
+               err = -EBUSY;
+               goto err_unlock;
+       }
 
-       if (!list_empty(&mutex->conds))
-               return -EBUSY;
+       if (!list_empty(&mutex->conds)) {
+               err = -EBUSY;
+         err_unlock:
+               xnlock_put_irqrestore(&nklock, s);
+               return err;
+       }
 
        cobalt_mark_deleted(&mx);
-       cobalt_mutex_destroy_inner(mutex, mutex->owningq);
+       xnlock_put_irqrestore(&nklock, s);
+       cobalt_mutex_destroy_inner(mx.handle, mutex->owningq);
 
        return __xn_safe_copy_to_user(u_mx, &mx, sizeof(*u_mx));
 }
@@ -338,13 +361,18 @@ int cobalt_mutex_trylock(struct __shadow_mutex __user 
*u_mx)
 {
        xnthread_t *cur = xnsched_current_thread();
        struct cobalt_mutex *mutex;
+       xnhandle_t handle;
+       spl_t s;
        int err;
 
-       __xn_get_user(mutex, &u_mx->mutex);
+       __xn_get_user(handle, &u_mx->handle);
 
-       if (!cobalt_obj_active(mutex, COBALT_MUTEX_MAGIC,
-                              struct cobalt_mutex))
-               return -EINVAL;
+       xnlock_get_irqsave(&nklock, s);
+       mutex = xnregistry_fetch(handle);
+       if (!cobalt_obj_active(mutex, COBALT_MUTEX_MAGIC, typeof(*mutex))) {
+               err = -EINVAL;
+               goto err_unlock;
+       }
 
        err = xnsynch_fast_acquire(mutex->synchbase.fastlock,
                                   xnthread_handle(cur));
@@ -364,38 +392,55 @@ int cobalt_mutex_trylock(struct __shadow_mutex __user 
*u_mx)
                err = -EBUSY;
                break;
        }
+  err_unlock:
+       xnlock_put_irqrestore(&nklock, s);
 
        return err;
 }
 
 int cobalt_mutex_lock(struct __shadow_mutex __user *u_mx)
 {
-       struct cobalt_mutex *mutex;
+       xnhandle_t handle;
+       spl_t s;
+       int err;
 
-       __xn_get_user(mutex, &u_mx->mutex);
+       __xn_get_user(handle, &u_mx->handle);
 
-       return cobalt_mutex_timedlock_break(mutex, 0, NULL);
+       xnlock_get_irqsave(&nklock, s);
+       err = cobalt_mutex_timedlock_break(xnregistry_fetch(handle), 0, NULL);
+       xnlock_put_irqrestore(&nklock, s);
+       
+       return err;
 }
 
 int cobalt_mutex_timedlock(struct __shadow_mutex __user *u_mx,
                           const struct timespec __user *u_ts)
 {
-       struct cobalt_mutex *mutex;
+       xnhandle_t handle;
+       spl_t s;
+       int err;
+
+       __xn_get_user(handle, &u_mx->handle);
 
-       __xn_get_user(mutex, &u_mx->mutex);
+       xnlock_get_irqsave(&nklock, s);
+       err = cobalt_mutex_timedlock_break(xnregistry_fetch(handle), 1, u_ts);
+       xnlock_put_irqrestore(&nklock, s);
 
-       return cobalt_mutex_timedlock_break(mutex, 1, u_ts);
+       return err;
 }
 
 int cobalt_mutex_unlock(struct __shadow_mutex __user *u_mx)
 {
        struct cobalt_mutex *mutex;
+       xnhandle_t handle;
        int err;
        spl_t s;
 
-       __xn_get_user(mutex, &u_mx->mutex);
+
+       __xn_get_user(handle, &u_mx->handle);
 
        xnlock_get_irqsave(&nklock, s);
+       mutex = xnregistry_fetch(handle);
        err = cobalt_mutex_release(xnsched_current_thread(), mutex);
        if (err < 0)
                goto out;
@@ -422,7 +467,7 @@ void cobalt_mutexq_cleanup(struct cobalt_kqueues *q)
 
        list_for_each_entry_safe(mutex, tmp, &q->mutexq, link) {
                xnlock_put_irqrestore(&nklock, s);
-               cobalt_mutex_destroy_inner(mutex, q);
+               cobalt_mutex_destroy_inner(mutex->handle, q);
 #if XENO_DEBUG(COBALT)
                printk(XENO_INFO "deleting Cobalt mutex %p\n",
                       mutex);
diff --git a/kernel/cobalt/posix/mutex.h b/kernel/cobalt/posix/mutex.h
index 5007a3b..1d2fe43 100644
--- a/kernel/cobalt/posix/mutex.h
+++ b/kernel/cobalt/posix/mutex.h
@@ -32,6 +32,7 @@ struct cobalt_mutex {
        struct list_head conds;
        pthread_mutexattr_t attr;
        struct cobalt_kqueues *owningq;
+       xnhandle_t handle;
 };
 
 extern const pthread_mutexattr_t cobalt_default_mutex_attr;


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

Reply via email to