Module: xenomai-3
Branch: master
Commit: 2b2efee02f28ea9cb7494413f4fc555cb83fbeda
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=2b2efee02f28ea9cb7494413f4fc555cb83fbeda

Author: Jan Kiszka <jan.kis...@siemens.com>
Date:   Fri Mar 13 19:20:09 2015 +0100

cobalt/posix/sem: Increment semaphore on interrupted sem_wait

When leaving sem_wait due to an interruption, don't forget to increment
the semaphore again as the acquisition was unsuccessful. For this we
can use sem_post_inner, we just have to move it unmodified up in the
file.

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

---

 kernel/cobalt/posix/sem.c |   68 +++++++++++++++++++++++----------------------
 1 file changed, 35 insertions(+), 33 deletions(-)

diff --git a/kernel/cobalt/posix/sem.c b/kernel/cobalt/posix/sem.c
index ab97fb3..fc89c24 100644
--- a/kernel/cobalt/posix/sem.c
+++ b/kernel/cobalt/posix/sem.c
@@ -241,6 +241,37 @@ static int sem_trywait(xnhandle_t handle)
        return err;
 }
 
+static int sem_post_inner(struct cobalt_sem *sem, struct cobalt_kqueues *ownq, 
int bcast)
+{
+       if (sem == NULL || sem->magic != COBALT_SEM_MAGIC)
+               return -EINVAL;
+
+#if XENO_DEBUG(USER)
+       if (ownq && ownq != sem_kqueue(sem))
+               return -EPERM;
+#endif
+
+       if (atomic_read(&sem->state->value) == SEM_VALUE_MAX)
+               return -EINVAL;
+
+       if (!bcast) {
+               if (atomic_inc_return(&sem->state->value) <= 0) {
+                       if (xnsynch_wakeup_one_sleeper(&sem->synchbase))
+                               xnsched_run();
+               } else if (sem->flags & SEM_PULSE)
+                       atomic_set(&sem->state->value, 0);
+       } else {
+               if (atomic_read(&sem->state->value) < 0) {
+                       atomic_set(&sem->state->value, 0);
+                       if (xnsynch_flush(&sem->synchbase, 0) ==
+                               XNSYNCH_RESCHED)
+                               xnsched_run();
+               }
+       }
+
+       return 0;
+}
+
 static int sem_wait(xnhandle_t handle)
 {
        struct cobalt_sem *sem;
@@ -256,10 +287,12 @@ static int sem_wait(xnhandle_t handle)
 
        ret = 0;
        info = xnsynch_sleep_on(&sem->synchbase, XN_INFINITE, XN_RELATIVE);
-       if (info & XNRMID)
+       if (info & XNRMID) {
                ret = -EINVAL;
-       else if (info & XNBREAK)
+       } else if (info & XNBREAK) {
+               sem_post_inner(sem, sem->owningq, 0);
                ret = -EINTR;
+       }
 out:
        xnlock_put_irqrestore(&nklock, s);
 
@@ -335,37 +368,6 @@ int __cobalt_sem_timedwait(struct cobalt_sem_shadow __user 
*u_sem,
        return ret;
 }
 
-int sem_post_inner(struct cobalt_sem *sem, struct cobalt_kqueues *ownq, int 
bcast)
-{
-       if (sem == NULL || sem->magic != COBALT_SEM_MAGIC)
-               return -EINVAL;
-
-#if XENO_DEBUG(USER)
-       if (ownq && ownq != sem_kqueue(sem))
-               return -EPERM;
-#endif
-
-       if (atomic_read(&sem->state->value) == SEM_VALUE_MAX)
-               return -EINVAL;
-
-       if (!bcast) {
-               if (atomic_inc_return(&sem->state->value) <= 0) {
-                       if (xnsynch_wakeup_one_sleeper(&sem->synchbase))
-                               xnsched_run();
-               } else if (sem->flags & SEM_PULSE)
-                       atomic_set(&sem->state->value, 0);
-       } else {
-               if (atomic_read(&sem->state->value) < 0) {
-                       atomic_set(&sem->state->value, 0);
-                       if (xnsynch_flush(&sem->synchbase, 0) ==
-                               XNSYNCH_RESCHED)
-                               xnsched_run();
-               }
-       }
-
-       return 0;
-}
-
 static int sem_post(xnhandle_t handle)
 {
        struct cobalt_sem *sm;


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

Reply via email to