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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Thu Jan  9 16:20:38 2014 +0100

cobalt/posix/sem: fixup count upon aborted sleep

---

 kernel/cobalt/posix/sem.c |   36 ++++++++++++++++++++----------------
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/kernel/cobalt/posix/sem.c b/kernel/cobalt/posix/sem.c
index e4ec209..b898d65 100644
--- a/kernel/cobalt/posix/sem.c
+++ b/kernel/cobalt/posix/sem.c
@@ -85,7 +85,7 @@ int cobalt_sem_destroy_inner(xnhandle_t handle)
 
 struct cobalt_sem *
 cobalt_sem_init_inner(const char *name, struct __shadow_sem *sm, 
-               int flags, unsigned int value)
+                     int flags, unsigned int value)
 {
        struct list_head *semq;
        struct cobalt_sem *sem, *osem;
@@ -351,7 +351,7 @@ static int sem_destroy(struct __shadow_sem *sm)
  *
  */
 
-static inline int sem_trywait_internal(struct cobalt_sem *sem)
+static inline int sem_trywait_inner(struct cobalt_sem *sem)
 {
        if (sem == NULL || sem->magic != COBALT_SEM_MAGIC)
                return -EINVAL;
@@ -394,15 +394,15 @@ static int sem_trywait(xnhandle_t handle)
        spl_t s;
 
        xnlock_get_irqsave(&nklock, s);
-       err = sem_trywait_internal(xnregistry_fetch(handle));
+       err = sem_trywait_inner(xnregistry_fetch(handle));
        xnlock_put_irqrestore(&nklock, s);
 
        return err;
 }
 
 static inline int
-sem_timedwait_internal(xnhandle_t handle, int timed,
-                      const struct timespec __user *u_ts)
+sem_wait_inner(xnhandle_t handle, int timed,
+              const struct timespec __user *u_ts)
 {
        struct cobalt_sem *sem;
        struct timespec ts;
@@ -414,7 +414,7 @@ sem_timedwait_internal(xnhandle_t handle, int timed,
 
        sem = xnregistry_fetch(handle);
 
-       ret = sem_trywait_internal(sem);
+       ret = sem_trywait_inner(sem);
        if (ret != -EAGAIN) {
                xnlock_put_irqrestore(&nklock, s);
                return ret;
@@ -424,12 +424,12 @@ sem_timedwait_internal(xnhandle_t handle, int timed,
                if (u_ts == NULL ||
                        __xn_safe_copy_from_user(&ts, u_ts, sizeof(ts))) {
                        ret = -EFAULT;
-                       goto out;
+                       goto fail;
                }
 
                if (ts.tv_nsec >= ONE_BILLION) {
                        ret = -EINVAL;
-                       goto out;
+                       goto fail;
                }
 
                tmode = sem->flags & SEM_RAWCLOCK ? XN_ABSOLUTE : XN_REALTIME;
@@ -437,12 +437,16 @@ sem_timedwait_internal(xnhandle_t handle, int timed,
        } else
                info = xnsynch_sleep_on(&sem->synchbase, 
                                        XN_INFINITE, XN_RELATIVE);
+       if (info & XNRMID) {
+               ret = -EINVAL;
+               goto out;
+       }
 
        ret = 0;
-       if (info & XNRMID)
-               ret = -EINVAL;
-       else if (info & (XNBREAK|XNTIMEO))
+       if (info & (XNBREAK|XNTIMEO))
                ret = (info & XNBREAK) ? -EINTR : -ETIMEDOUT;
+fail:
+       atomic_long_inc(&sem->datp->value);
 out:
        xnlock_put_irqrestore(&nklock, s);
 
@@ -484,7 +488,7 @@ out:
  */
 static int sem_wait(xnhandle_t handle)
 {
-       return sem_timedwait_internal(handle, 0, NULL);
+       return sem_wait_inner(handle, 0, NULL);
 }
 
 /**
@@ -524,12 +528,12 @@ static int sem_wait(xnhandle_t handle)
 static int sem_timedwait(xnhandle_t handle,
                         const struct timespec __user *abs_timeout)
 {
-       return sem_timedwait_internal(handle, 1, abs_timeout);
+       return sem_wait_inner(handle, 1, abs_timeout);
 }
 
 int sem_post_inner(struct cobalt_sem *sem, struct cobalt_kqueues *ownq, int 
bcast)
 {
-       if (!sem || sem->magic != COBALT_SEM_MAGIC)
+       if (sem == NULL || sem->magic != COBALT_SEM_MAGIC)
                return -EINVAL;
 
 #if XENO_DEBUG(COBALT)
@@ -544,8 +548,8 @@ int sem_post_inner(struct cobalt_sem *sem, struct 
cobalt_kqueues *ownq, int bcas
                if (atomic_long_inc_return(&sem->datp->value) <= 0) {
                        if (xnsynch_wakeup_one_sleeper(&sem->synchbase))
                                xnsched_run();
-               } else if ((sem->flags & SEM_PULSE))
-                               atomic_long_set(&sem->datp->value, 0);
+               } else if (sem->flags & SEM_PULSE)
+                       atomic_long_set(&sem->datp->value, 0);
        } else {
                if (atomic_long_read(&sem->datp->value) < 0) {
                        atomic_long_set(&sem->datp->value, 0);


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

Reply via email to