Module: xenomai-gch
Branch: for-forge
Commit: 432479907b0c9871468207a3b614db477ef65e88
URL:    
http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=432479907b0c9871468207a3b614db477ef65e88

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Sun Nov 13 17:15:37 2011 +0100

cobalt: fix pthread_mutex_trylock and pthread_mutex_unlock

pthread_mutex_trylock was broken since the introduction of XNOTHER.
pthread_mutex_unlock was broken with XNOTHER for recursive mutexes.

---

 include/cobalt/syscall.h            |   49 +++++++++++------------
 kernel/cobalt/syscall.c             |   66 +++++++++++++++++++++++++++++--
 kernel/drivers/can/sja1000/Makefile |    3 +-
 lib/cobalt/mutex.c                  |   73 ++++++++++++++++------------------
 4 files changed, 121 insertions(+), 70 deletions(-)

diff --git a/include/cobalt/syscall.h b/include/cobalt/syscall.h
index 56c4700..ab1d16e 100644
--- a/include/cobalt/syscall.h
+++ b/include/cobalt/syscall.h
@@ -42,31 +42,30 @@
 #define __cobalt_clock_settime         16
 #define __cobalt_clock_nanosleep       17
 #define __cobalt_mutex_init            18
-#define __cobalt_mutex_destroy         19
-#define __cobalt_mutex_lock            20
-#define __cobalt_mutex_timedlock       21
-#define __cobalt_mutex_trylock         22
-#define __cobalt_check_init            __cobalt_mutex_trylock
-#define __cobalt_mutex_unlock          23
-#define __cobalt_cond_init             24
-#define __cobalt_cond_destroy          25
-#define __cobalt_cond_wait_prologue    26
-#define __cobalt_cond_wait_epilogue    27
-#define __cobalt_cond_signal           28
-#define __cobalt_cond_broadcast        29
-#define __cobalt_mq_open               30
-#define __cobalt_mq_close              31
-#define __cobalt_mq_unlink             32
-#define __cobalt_mq_getattr            33
-#define __cobalt_mq_setattr            34
-#define __cobalt_mq_send               35
-#define __cobalt_mq_timedsend          36
-#define __cobalt_mq_receive            37
-#define __cobalt_mq_timedreceive       38
-#define __cobalt_thread_probe          39
-#define __cobalt_sched_minprio         40
-#define __cobalt_sched_maxprio         41
-#define __cobalt_unimp_42              42
+#define __cobalt_check_init            19
+#define __cobalt_mutex_destroy         20
+#define __cobalt_mutex_lock            21
+#define __cobalt_mutex_timedlock       22
+#define __cobalt_mutex_trylock         23
+#define __cobalt_mutex_unlock          24
+#define __cobalt_cond_init             25
+#define __cobalt_cond_destroy          26
+#define __cobalt_cond_wait_prologue    27
+#define __cobalt_cond_wait_epilogue    28
+#define __cobalt_cond_signal           29
+#define __cobalt_cond_broadcast        30
+#define __cobalt_mq_open               31
+#define __cobalt_mq_close              32
+#define __cobalt_mq_unlink             33
+#define __cobalt_mq_getattr            34
+#define __cobalt_mq_setattr            35
+#define __cobalt_mq_send               36
+#define __cobalt_mq_timedsend          37
+#define __cobalt_mq_receive            38
+#define __cobalt_mq_timedreceive       39
+#define __cobalt_thread_probe          40
+#define __cobalt_sched_minprio         41
+#define __cobalt_sched_maxprio         42
 #define __cobalt_timer_create          43
 #define __cobalt_timer_delete          44
 #define __cobalt_timer_settime         45
diff --git a/kernel/cobalt/syscall.c b/kernel/cobalt/syscall.c
index dfb2520..140a12d 100644
--- a/kernel/cobalt/syscall.c
+++ b/kernel/cobalt/syscall.c
@@ -1078,6 +1078,8 @@ static int __pthread_mutex_init(union __xeno_mutex __user 
*u_mx,
                                      &mx.shadow_mutex, 
sizeof(u_mx->shadow_mutex));
 }
 
+#define __pthread_mutex_check_init __cobalt_call_not_available
+
 static int __pthread_mutex_destroy(union __xeno_mutex __user *u_mx)
 {
        union __xeno_mutex mx;
@@ -1331,6 +1333,65 @@ static int __pthread_mutex_destroy(union __xeno_mutex 
__user *u_mx)
                                      shadow, sizeof(u_mx->shadow_mutex));
 }
 
+static int __pthread_mutex_trylock(union __xeno_mutex __user *u_mx)
+{
+       xnthread_t *cur = xnpod_current_thread();
+       struct __shadow_mutex *shadow;
+       cobalt_mutex_t *mutex;
+       union __xeno_mutex mx;
+       int err;
+
+       if (__xn_safe_copy_from_user(&mx.shadow_mutex,
+                                    &u_mx->shadow_mutex,
+                                    offsetof(struct __shadow_mutex, lock)))
+               return -EFAULT;
+
+       shadow = &mx.shadow_mutex;
+       mutex = shadow->mutex;
+
+       if (!cobalt_obj_active(shadow, COBALT_MUTEX_MAGIC,
+                             struct __shadow_mutex)
+           || !cobalt_obj_active(mutex, COBALT_MUTEX_MAGIC,
+                                struct cobalt_mutex)) {
+               return -EINVAL;
+       }
+
+       err = xnsynch_fast_acquire(mutex->synchbase.fastlock,
+                                  xnthread_handle(cur));
+       switch(err) {
+       case 0:
+               if (xnthread_test_state(cur, XNOTHER))
+                       xnthread_inc_rescnt(cur);
+               shadow->lockcnt = 1;
+               break;
+
+       case -EBUSY:
+/* This should not happen, as recursive mutexes are handled in
+   user-space */
+               if (mutex->attr.type == PTHREAD_MUTEX_RECURSIVE) {
+                       if (shadow->lockcnt == UINT_MAX)
+                               err = -EAGAIN;
+                       else {
+                               ++shadow->lockcnt;
+                               err = 0;
+                       }
+               }
+               break;
+
+       case -EAGAIN:
+               err = -EBUSY;
+               break;
+       }
+
+       if (err == 0 &&
+           __xn_safe_copy_to_user(&u_mx->shadow_mutex.lockcnt,
+                                  &shadow->lockcnt,
+                                  sizeof(u_mx->shadow_mutex.lockcnt)))
+               return -EFAULT;
+
+       return err;
+}
+
 static int __pthread_mutex_lock(union __xeno_mutex __user *u_mx)
 {
        struct __shadow_mutex *shadow;
@@ -2586,14 +2647,11 @@ static struct xnsysent __systab[] = {
        SKINCALL_DEF(__cobalt_clock_settime, __clock_settime, any),
        SKINCALL_DEF(__cobalt_clock_nanosleep, __clock_nanosleep, 
nonrestartable),
        SKINCALL_DEF(__cobalt_mutex_init, __pthread_mutex_init, any),
+       SKINCALL_DEF(__cobalt_check_init, __pthread_mutex_check_init, any),
        SKINCALL_DEF(__cobalt_mutex_destroy, __pthread_mutex_destroy, any),
        SKINCALL_DEF(__cobalt_mutex_lock, __pthread_mutex_lock, primary),
        SKINCALL_DEF(__cobalt_mutex_timedlock, __pthread_mutex_timedlock, 
primary),
-#ifndef CONFIG_XENO_FASTSYNCH
        SKINCALL_DEF(__cobalt_mutex_trylock, __pthread_mutex_trylock, primary),
-#else
-       SKINCALL_DEF(__cobalt_check_init, __pthread_mutex_check_init, any),
-#endif
        SKINCALL_DEF(__cobalt_mutex_unlock, __pthread_mutex_unlock, 
nonrestartable),
        SKINCALL_DEF(__cobalt_cond_init, __pthread_cond_init, any),
        SKINCALL_DEF(__cobalt_cond_destroy, __pthread_cond_destroy, any),
diff --git a/kernel/drivers/can/sja1000/Makefile 
b/kernel/drivers/can/sja1000/Makefile
index 23dc1f5..73e047f 100644
--- a/kernel/drivers/can/sja1000/Makefile
+++ b/kernel/drivers/can/sja1000/Makefile
@@ -1,5 +1,4 @@
-
-ccflags-y := -D__IN_XENOMAI__ -Iinclude/xenomai -Idrivers/xenomai/can 
-Idrivers/xenomai/can/sja1000
+ccflags-y := -D__IN_XENOMAI__ -Iinclude/xenomai -Iinclude/xenomai/cobalt 
-Idrivers/xenomai/can -Idrivers/xenomai/can/sja1000
 
 obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000) += xeno_can_sja1000.o
 obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000_PEAK_PCI) += xeno_can_peak_pci.o
diff --git a/lib/cobalt/mutex.c b/lib/cobalt/mutex.c
index d63e177..94bd488 100644
--- a/lib/cobalt/mutex.c
+++ b/lib/cobalt/mutex.c
@@ -290,36 +290,40 @@ int __wrap_pthread_mutex_trylock(pthread_mutex_t *mutex)
        int err;
 
 #ifdef CONFIG_XENO_FASTSYNCH
-       unsigned long status;
+       xnarch_atomic_t *ownerp;
        xnhandle_t cur;
 
        cur = xeno_get_current();
        if (cur == XN_NO_HANDLE)
                return EPERM;
 
-       status = xeno_get_current_mode();
-       if (unlikely(status & XNOTHER))
-               goto do_syscall;
-
        if (unlikely(cb_try_read_lock(&shadow->lock, s)))
                return EINVAL;
 
        if (unlikely(shadow->magic != COBALT_MUTEX_MAGIC)) {
-               err = -EINVAL;
+               err = EINVAL;
                goto out;
        }
 
-       if (unlikely(status & XNRELAX)) {
-               do {
-                       err = XENOMAI_SYSCALL1(__xn_sys_migrate,
-                                              XENOMAI_XENO_DOMAIN);
-               } while (err == -EINTR);
-
-               if (err < 0)
-                       goto out;
+       ownerp = get_ownerp(shadow);
+       err = xnsynch_fast_owner_check(ownerp, cur);
+       if (err == 0) {
+               if (shadow->attr.type == PTHREAD_MUTEX_RECURSIVE) {
+                       if (shadow->lockcnt == UINT_MAX)
+                               err = EAGAIN;
+                       else {
+                               ++shadow->lockcnt;
+                               err = 0;
+                       }
+               } else
+                       err = EBUSY;
+               goto out;
        }
 
-       err = xnsynch_fast_acquire(get_ownerp(shadow), cur);
+       if (unlikely(xeno_get_current_mode() & (XNOTHER | XNRELAX)))
+               goto do_syscall;
+
+       err = xnsynch_fast_acquire(ownerp, cur);
 
        if (likely(!err)) {
                shadow->lockcnt = 1;
@@ -327,29 +331,23 @@ int __wrap_pthread_mutex_trylock(pthread_mutex_t *mutex)
                return 0;
        }
 
-       if (err == -EBUSY && shadow->attr.type == PTHREAD_MUTEX_RECURSIVE) {
-               if (shadow->lockcnt == UINT_MAX)
-                       err = -EAGAIN;
-               else {
-                       ++shadow->lockcnt;
-                       err = 0;
-               }
-       } else
-               err = -EBUSY;
-
-  out:
-       cb_read_unlock(&shadow->lock, s);
-       return -err;
+       err = EBUSY;
+       goto out;
 
 do_syscall:
-#endif /* !CONFIG_XENO_FASTSYNCH */
+#endif /* CONFIG_XENO_FASTSYNCH */
 
        do {
-               err = XENOMAI_SKINCALL1(__cobalt_muxid,
-                                       __cobalt_mutex_trylock, shadow);
-       } while (err == -EINTR);
+               err = -XENOMAI_SKINCALL1(__cobalt_muxid,
+                                        __cobalt_mutex_trylock, shadow);
+       } while (err == EINTR);
 
-       return -err;
+#ifdef CONFIG_XENO_FASTSYNCH
+  out:
+       cb_read_unlock(&shadow->lock, s);
+#endif /* CONFIG_XENO_FASTSYNCH */
+
+       return err;
 }
 
 int __wrap_pthread_mutex_unlock(pthread_mutex_t *mutex)
@@ -360,15 +358,12 @@ int __wrap_pthread_mutex_unlock(pthread_mutex_t *mutex)
 
 #ifdef CONFIG_XENO_FASTSYNCH
        xnarch_atomic_t *ownerp;
-       unsigned long status;
        xnhandle_t cur;
 
        cur = xeno_get_current();
        if (cur == XN_NO_HANDLE)
                return EPERM;
 
-       status = xeno_get_current_mode();
-
        if (unlikely(cb_try_read_lock(&shadow->lock, s)))
                return EINVAL;
 
@@ -377,9 +372,6 @@ int __wrap_pthread_mutex_unlock(pthread_mutex_t *mutex)
                goto out_err;
        }
 
-       if (unlikely(status & XNOTHER))
-               goto do_syscall;
-
        ownerp = get_ownerp(shadow);
 
        err = xnsynch_fast_owner_check(ownerp, cur);
@@ -391,6 +383,9 @@ int __wrap_pthread_mutex_unlock(pthread_mutex_t *mutex)
                goto out;
        }
 
+       if (unlikely(xeno_get_current_mode() & XNOTHER))
+               goto do_syscall;
+
        if (likely(xnsynch_fast_release(ownerp, cur))) {
          out:
                cb_read_unlock(&shadow->lock, s);


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to