Module: xenomai-jki
Branch: for-upstream
Commit: 1f1b51f70fc6382660ad6bcf43d0979c0b5f7aa7
URL:    
http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=1f1b51f70fc6382660ad6bcf43d0979c0b5f7aa7

Author: Jan Kiszka <jan.kis...@siemens.com>
Date:   Tue Mar  2 18:29:37 2010 +0100

Native: Add fixed syscalls for rt_cond_wait services

Signed-off-by: Jan Kiszka <jan.kis...@siemens.com>

---

 include/native/cond.h       |    8 +++
 include/native/syscall.h    |    2 +
 ksrc/skins/native/syscall.c |  101 ++++++++++++++++++++++++++++++++++---------
 src/skins/native/cond.c     |   82 ++++++++++++++++++++++++-----------
 src/skins/native/init.c     |    4 ++
 5 files changed, 151 insertions(+), 46 deletions(-)

diff --git a/include/native/cond.h b/include/native/cond.h
index 1d38b2c..bca7a63 100644
--- a/include/native/cond.h
+++ b/include/native/cond.h
@@ -38,6 +38,14 @@ typedef struct rt_cond_placeholder {
 
 } RT_COND_PLACEHOLDER;
 
+typedef struct rt_cond_waitstate {
+
+    unsigned lockcnt;
+
+    int prologue_err;
+
+} RT_COND_WAITSTATE;
+
 #if (defined(__KERNEL__) || defined(__XENO_SIM__)) && !defined(DOXYGEN_CPP)
 
 #include <nucleus/synch.h>
diff --git a/include/native/syscall.h b/include/native/syscall.h
index 2e3d7ec..59f0ce4 100644
--- a/include/native/syscall.h
+++ b/include/native/syscall.h
@@ -128,6 +128,8 @@
 #define __native_buffer_inquire     102
 #define __native_queue_flush        103
 #define __native_cond_wait_epilogue 104
+#define __native_cond_wait_prologue2 105
+#define __native_cond_wait_epilogue2 106
 
 struct rt_arg_bulk {
 
diff --git a/ksrc/skins/native/syscall.c b/ksrc/skins/native/syscall.c
index ee6c829..597f3d1 100644
--- a/ksrc/skins/native/syscall.c
+++ b/ksrc/skins/native/syscall.c
@@ -1825,19 +1825,11 @@ static int __rt_cond_delete(struct pt_regs *regs)
        return err;
 }
 
-/*
- * int __rt_cond_wait_prologue(RT_COND_PLACEHOLDER *cph,
- *                            RT_MUTEX_PLACEHOLDER *mph,
- *                            unsigned *plockcnt,
- *                            xntmode_t timeout_mode,
- *                            RTIME *timeoutp)
- */
-
-static int __rt_cond_wait_prologue(struct pt_regs *regs)
+static int
+__rt_cond_wait_prologue_inner(struct pt_regs *regs, RT_COND_WAITSTATE *state)
 {
        RT_COND_PLACEHOLDER cph, mph;
        xntmode_t timeout_mode;
-       unsigned lockcnt;
        RT_MUTEX *mutex;
        RT_COND *cond;
        RTIME timeout;
@@ -1867,16 +1859,15 @@ static int __rt_cond_wait_prologue(struct pt_regs *regs)
                                     sizeof(timeout)))
                return -EFAULT;
 
-       err = rt_cond_wait_prologue(cond, mutex, &lockcnt, timeout_mode, 
timeout);
+       err = rt_cond_wait_prologue(cond, mutex, &state->lockcnt,
+                                   timeout_mode, timeout);
 
-       /* Old user space prevents that we can return -EINTR (it would loop
-          forever if we did). So drop this error. */
-       xnpod_current_thread()->errcode = err != -EINTR ? err : 0;
+       state->prologue_err = err;
 
        /* Reacquire the mutex if it was unlocked in the prologue and we were
           not interrupted. */
-       if (lockcnt && err != -EINTR) {
-               epilogue_err = rt_cond_wait_epilogue(mutex, lockcnt);
+       if (state->lockcnt && err != -EINTR) {
+               epilogue_err = rt_cond_wait_epilogue(mutex, state->lockcnt);
 
                /* Only overwrite the prologue if we need to signal -EINTR or
                   the previous error was "less fatal". */
@@ -1885,24 +1876,65 @@ static int __rt_cond_wait_prologue(struct pt_regs *regs)
                        err = epilogue_err;
        }
 
+       return err;
+}
+
+/*
+ * int __rt_cond_wait_prologue(RT_COND_PLACEHOLDER *cph,
+ *                            RT_MUTEX_PLACEHOLDER *mph,
+ *                            unsigned *plockcnt,
+ *                            xntmode_t timeout_mode,
+ *                            RTIME *timeoutp)
+ */
+
+static int __rt_cond_wait_prologue(struct pt_regs *regs)
+{
+       RT_COND_WAITSTATE state;
+       int err;
+
+       err = __rt_cond_wait_prologue_inner(regs, &state);
+
+       /* Old user space prevents that we can return -EINTR (it would loop
+          forever if we did). So drop this error. */
+       xnpod_current_thread()->errcode =
+               (state.prologue_err != -EINTR) ? state.prologue_err : 0;
+
        if (err == -EINTR && __xn_reg_arg3(regs)
            && __xn_safe_copy_to_user((void __user *)__xn_reg_arg3(regs),
-                                     &lockcnt, sizeof(lockcnt)))
+                                     &state.lockcnt, sizeof(state.lockcnt)))
                return -EFAULT;
 
        return err;
 }
 
 /*
- * int __rt_cond_wait_epilogue(RT_MUTEX_PLACEHOLODER *mph, unsigned lockcnt)
+ * int __rt_cond_wait_prologue2(RT_COND_PLACEHOLDER *cph,
+ *                             RT_MUTEX_PLACEHOLDER *mph,
+ *                             RT_COND_WAITSTATE *waitstate,
+ *                             xntmode_t timeout_mode,
+ *                             RTIME *timeoutp)
  */
 
-static int __rt_cond_wait_epilogue(struct pt_regs *regs)
+static int __rt_cond_wait_prologue2(struct pt_regs *regs)
+{
+       RT_COND_WAITSTATE state;
+       int err;
+
+       err = __rt_cond_wait_prologue_inner(regs, &state);
+
+       if (err == -EINTR
+           && __xn_safe_copy_to_user((void __user *)__xn_reg_arg3(regs),
+                                     &state, sizeof(state)))
+               return -EFAULT;
+
+       return err;
+}
+
+static int __rt_cond_wait_epilogue_inner(struct pt_regs *regs)
 {
        RT_COND_PLACEHOLDER mph;
        unsigned lockcnt;
        RT_MUTEX *mutex;
-       int prologue_err, err;
 
        if (__xn_safe_copy_from_user(&mph, (void __user *)__xn_reg_arg1(regs),
                                     sizeof(mph)))
@@ -1914,8 +1946,20 @@ static int __rt_cond_wait_epilogue(struct pt_regs *regs)
                return -ESRCH;
 
        lockcnt = __xn_reg_arg2(regs);
+       return rt_cond_wait_epilogue(mutex, lockcnt);
+}
+
+/*
+ * int __rt_cond_wait_epilogue(RT_MUTEX_PLACEHOLODER *mph, unsigned lockcnt)
+ *
+ * Used with __rt_cond_wait_prologue.
+ */
+
+static int __rt_cond_wait_epilogue(struct pt_regs *regs)
+{
+       int prologue_err, err;
 
-       err = rt_cond_wait_epilogue(mutex, lockcnt);
+       err = __rt_cond_wait_epilogue_inner(regs);
        if (err == -EINTR)
                return err;
 
@@ -1925,6 +1969,17 @@ static int __rt_cond_wait_epilogue(struct pt_regs *regs)
 }
 
 /*
+ * int __rt_cond_wait_epilogue2(RT_MUTEX_PLACEHOLODER *mph, unsigned lockcnt)
+ *
+ * Used with __rt_cond_wait_prologue2.
+ */
+
+static int __rt_cond_wait_epilogue2(struct pt_regs *regs)
+{
+       return __rt_cond_wait_epilogue_inner(regs);
+}
+
+/*
  * int __rt_cond_signal(RT_COND_PLACEHOLDER *ph)
  */
 
@@ -4113,6 +4168,10 @@ static xnsysent_t __systab[] = {
                {&__rt_cond_wait_prologue, __xn_exec_primary},
        [__native_cond_wait_epilogue] = 
                {&__rt_cond_wait_epilogue, __xn_exec_primary},
+       [__native_cond_wait_prologue2] =
+               {&__rt_cond_wait_prologue2, __xn_exec_primary},
+       [__native_cond_wait_epilogue2] =
+               {&__rt_cond_wait_epilogue2, __xn_exec_primary},
        [__native_cond_signal] = {&__rt_cond_signal, __xn_exec_any},
        [__native_cond_broadcast] = {&__rt_cond_broadcast, __xn_exec_any},
        [__native_cond_inquire] = {&__rt_cond_inquire, __xn_exec_any},
diff --git a/src/skins/native/cond.c b/src/skins/native/cond.c
index f874678..7c5c101 100644
--- a/src/skins/native/cond.c
+++ b/src/skins/native/cond.c
@@ -22,6 +22,8 @@
 
 extern int __native_muxid;
 
+static int have_new_cond_syscalls;
+
 int rt_cond_create(RT_COND *cond, const char *name)
 {
        return XENOMAI_SKINCALL2(__native_muxid, __native_cond_create, cond,
@@ -39,16 +41,16 @@ int rt_cond_delete(RT_COND *cond)
        return XENOMAI_SKINCALL1(__native_muxid, __native_cond_delete, cond);
 }
 
-int rt_cond_wait(RT_COND *cond, RT_MUTEX *mutex, RTIME timeout)
+static int rt_cond_wait_old(RT_COND *cond, RT_MUTEX *mutex, RTIME timeout,
+                           xntmode_t timeout_mode)
 {
-       int saved_lockcnt, err;
-
+       int err;
 #ifdef CONFIG_XENO_FASTSYNCH
-       saved_lockcnt = mutex->lockcnt;
+       int saved_lockcnt = mutex->lockcnt;
 
        err = XENOMAI_SKINCALL5(__native_muxid,
                                __native_cond_wait_prologue, cond, mutex,
-                               NULL, XN_RELATIVE, &timeout);
+                               NULL, timeout_mode, &timeout);
 
        while (err == -EINTR)
                err = XENOMAI_SKINCALL2(__native_muxid,
@@ -60,7 +62,7 @@ int rt_cond_wait(RT_COND *cond, RT_MUTEX *mutex, RTIME 
timeout)
 #else /* !CONFIG_XENO_FASTSYNCH */
        err = XENOMAI_SKINCALL5(__native_muxid,
                                 __native_cond_wait_prologue, cond, mutex,
-                                &saved_lockcnt, XN_RELATIVE, &timeout);
+                                &saved_lockcnt, timeout_mode, &timeout);
 
        while (err == -EINTR)
                err = XENOMAI_SKINCALL2(__native_muxid,
@@ -72,36 +74,56 @@ int rt_cond_wait(RT_COND *cond, RT_MUTEX *mutex, RTIME 
timeout)
        return err;
 }
 
-int rt_cond_wait_until(RT_COND *cond, RT_MUTEX *mutex, RTIME timeout)
+static int rt_cond_wait_new(RT_COND *cond, RT_MUTEX *mutex, RTIME timeout,
+                           xntmode_t timeout_mode)
 {
-       int saved_lockcnt, err;
+       RT_COND_WAITSTATE state;
+       int saved_lockcnt;
+       int err;
 
 #ifdef CONFIG_XENO_FASTSYNCH
        saved_lockcnt = mutex->lockcnt;
+#endif
 
        err = XENOMAI_SKINCALL5(__native_muxid,
-                               __native_cond_wait_prologue, cond, mutex,
-                               NULL, XN_REALTIME, &timeout);
-
-       while (err == -EINTR)
-               err = XENOMAI_SKINCALL2(__native_muxid,
-                                       __native_cond_wait_epilogue, mutex,
-                                       saved_lockcnt);
+                               __native_cond_wait_prologue2, cond, mutex,
+                               &state, timeout_mode, &timeout);
+
+       if (err == -EINTR) {
+#ifndef CONFIG_XENO_FASTSYNCH
+               saved_lockcnt = state.lockcnt;
+#endif
+               do {
+                       err = XENOMAI_SKINCALL2(__native_muxid,
+                                               __native_cond_wait_epilogue2,
+                                               mutex, saved_lockcnt);
+               } while (err == -EINTR);
+
+               if (!err || state.prologue_err != -EIDRM)
+                       err = state.prologue_err;
+       }
 
+#ifdef CONFIG_XENO_FASTSYNCH
        mutex->lockcnt = saved_lockcnt;
+#endif
 
-#else /* !CONFIG_XENO_FASTSYNCH */
-       err = XENOMAI_SKINCALL5(__native_muxid,
-                               __native_cond_wait_prologue, cond, mutex,
-                               &saved_lockcnt, XN_REALTIME, &timeout);
+       return err;
+}
 
-       while (err == -EINTR)
-               err = XENOMAI_SKINCALL2(__native_muxid,
-                                       __native_cond_wait_epilogue, mutex,
-                                       saved_lockcnt);
-#endif /* !CONFIG_XENO_FASTSYNCH */
+int rt_cond_wait(RT_COND *cond, RT_MUTEX *mutex, RTIME timeout)
+{
+       if (have_new_cond_syscalls)
+               return rt_cond_wait_new(cond, mutex, timeout, XN_RELATIVE);
+       else
+               return rt_cond_wait_old(cond, mutex, timeout, XN_RELATIVE);
+}
 
-       return err;
+int rt_cond_wait_until(RT_COND *cond, RT_MUTEX *mutex, RTIME timeout)
+{
+       if (have_new_cond_syscalls)
+               return rt_cond_wait_new(cond, mutex, timeout, XN_REALTIME);
+       else
+               return rt_cond_wait_old(cond, mutex, timeout, XN_REALTIME);
 }
 
 int rt_cond_signal(RT_COND *cond)
@@ -119,3 +141,13 @@ int rt_cond_inquire(RT_COND *cond, RT_COND_INFO *info)
        return XENOMAI_SKINCALL2(__native_muxid, __native_cond_inquire, cond,
                                 info);
 }
+
+void __native_cond_init(void)
+{
+       int err = XENOMAI_SKINCALL5(__native_muxid,
+                                   __native_cond_wait_prologue2, NULL, NULL,
+                                   NULL, XN_REALTIME, NULL);
+
+       have_new_cond_syscalls = (err != -ENOSYS);
+}
+
diff --git a/src/skins/native/init.c b/src/skins/native/init.c
index e85784a..c4b94c0 100644
--- a/src/skins/native/init.c
+++ b/src/skins/native/init.c
@@ -28,6 +28,8 @@
 
 int __native_muxid = -1;
 
+void __native_cond_init(void);
+
 #ifndef HAVE___THREAD
 pthread_key_t __native_tskey;
 
@@ -56,4 +58,6 @@ void __init_xeno_interface(void)
                xeno_bind_skin(XENO_SKIN_MAGIC, "native", "xeno_native", NULL);
 
        __native_muxid = __xn_mux_shifted_id(__native_muxid);
+
+       __native_cond_init();
 }


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

Reply via email to