[Xenomai-git] Philippe Gerum : cobalt/posix/sem: fix spurious wakeup on aborted wait

2015-08-15 Thread git repository hosting
Module: xenomai-3
Branch: master
Commit: 081cbb8b150f30a019245dfb0e2f0b92cc7f2dfd
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=081cbb8b150f30a019245dfb0e2f0b92cc7f2dfd

Author: Philippe Gerum r...@xenomai.org
Date:   Wed Jul 29 10:13:08 2015 +0200

cobalt/posix/sem: fix spurious wakeup on aborted wait

sem_wait() must not pull any waiter from the sleep queue when undoing
do_trywait() upon XNBREAK.

At this chance, fold a few routines to avoid unnecessary hops,
improving readability too.

---

 kernel/cobalt/posix/sem.c |  148 +
 1 file changed, 69 insertions(+), 79 deletions(-)

diff --git a/kernel/cobalt/posix/sem.c b/kernel/cobalt/posix/sem.c
index 1c47f2a..dc7ff0d 100644
--- a/kernel/cobalt/posix/sem.c
+++ b/kernel/cobalt/posix/sem.c
@@ -1,5 +1,6 @@
 /*
  * Written by Gilles Chanteperdrix gilles.chanteperd...@xenomai.org.
+ * Copyright (C) 2014,2015 Philippe Gerum r...@xenomai.org
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -30,6 +31,18 @@ static inline struct cobalt_resources *sem_kqueue(struct 
cobalt_sem *sem)
return cobalt_current_resources(pshared);
 }
 
+static inline int sem_check(struct cobalt_sem *sem)
+{
+   if (sem == NULL || sem-magic != COBALT_SEM_MAGIC)
+   return -EINVAL;
+
+   if (IS_ENABLED(CONFIG_XENO_OPT_DEBUG_POSIX_SYNCHRO) 
+   sem-resnode.scope  sem-resnode.scope != sem_kqueue(sem))
+   return -EPERM;
+
+   return 0;
+}
+
 int __cobalt_sem_destroy(xnhandle_t handle)
 {
struct cobalt_sem *sem;
@@ -170,51 +183,44 @@ static int sem_destroy(struct cobalt_sem_shadow *sm)
spl_t s;
 
xnlock_get_irqsave(nklock, s);
+
if (sm-magic != COBALT_SEM_MAGIC) {
ret = -EINVAL;
-   goto error;
+   goto fail;
}
 
sem = xnregistry_lookup(sm-handle, NULL);
-   if (!cobalt_obj_active(sem, COBALT_SEM_MAGIC, typeof(*sem))) {
-   ret = -EINVAL;
-   goto error;
-   }
-
-   if (sem-resnode.scope  sem_kqueue(sem) != sem-resnode.scope) {
-   ret = -EPERM;
-   goto error;
-   }
+   ret = sem_check(sem);
+   if (ret)
+   goto fail;
 
if ((sem-flags  SEM_NOBUSYDEL) != 0 
xnsynch_pended_p(sem-synchbase)) {
ret = -EBUSY;
-   goto error;
+   goto fail;
}
 
warn = sem-flags  SEM_WARNDEL;
cobalt_mark_deleted(sm);
+
xnlock_put_irqrestore(nklock, s);
 
ret = __cobalt_sem_destroy(sem-resnode.handle);
 
return warn ? ret : 0;
-
-  error:
-
+fail:
xnlock_put_irqrestore(nklock, s);
 
return ret;
 }
 
-static inline int sem_trywait_inner(struct cobalt_sem *sem)
+static inline int do_trywait(struct cobalt_sem *sem)
 {
-   if (sem == NULL || sem-magic != COBALT_SEM_MAGIC)
-   return -EINVAL;
-
-   if (IS_ENABLED(CONFIG_XENO_OPT_DEBUG_POSIX_SYNCHRO) 
-   sem-resnode.scope  sem-resnode.scope != sem_kqueue(sem))
-   return -EPERM;
+   int ret;
+   
+   ret = sem_check(sem);
+   if (ret)
+   return ret;
 
if (atomic_sub_return(1, sem-state-value)  0)
return -EAGAIN;
@@ -222,48 +228,6 @@ static inline int sem_trywait_inner(struct cobalt_sem *sem)
return 0;
 }
 
-static int sem_trywait(xnhandle_t handle)
-{
-   int err;
-   spl_t s;
-
-   xnlock_get_irqsave(nklock, s);
-   err = sem_trywait_inner(xnregistry_lookup(handle, NULL));
-   xnlock_put_irqrestore(nklock, s);
-
-   return err;
-}
-
-static int sem_post_inner(struct cobalt_sem *sem, int bcast)
-{
-   if (sem == NULL || sem-magic != COBALT_SEM_MAGIC)
-   return -EINVAL;
-
-   if (IS_ENABLED(CONFIG_XENO_OPT_DEBUG_POSIX_SYNCHRO) 
-   sem-resnode.scope  sem-resnode.scope != sem_kqueue(sem))
-   return -EPERM;
-
-   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;
@@ -273,7 +237,7 @@ static int sem_wait(xnhandle_t handle)
xnlock_get_irqsave(nklock, s);
 
sem = 

[Xenomai-git] Philippe Gerum : cobalt/posix/sem: fix spurious wakeup on aborted wait

2015-07-29 Thread git repository hosting
Module: xenomai-3
Branch: next
Commit: 081cbb8b150f30a019245dfb0e2f0b92cc7f2dfd
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=081cbb8b150f30a019245dfb0e2f0b92cc7f2dfd

Author: Philippe Gerum r...@xenomai.org
Date:   Wed Jul 29 10:13:08 2015 +0200

cobalt/posix/sem: fix spurious wakeup on aborted wait

sem_wait() must not pull any waiter from the sleep queue when undoing
do_trywait() upon XNBREAK.

At this chance, fold a few routines to avoid unnecessary hops,
improving readability too.

---

 kernel/cobalt/posix/sem.c |  148 +
 1 file changed, 69 insertions(+), 79 deletions(-)

diff --git a/kernel/cobalt/posix/sem.c b/kernel/cobalt/posix/sem.c
index 1c47f2a..dc7ff0d 100644
--- a/kernel/cobalt/posix/sem.c
+++ b/kernel/cobalt/posix/sem.c
@@ -1,5 +1,6 @@
 /*
  * Written by Gilles Chanteperdrix gilles.chanteperd...@xenomai.org.
+ * Copyright (C) 2014,2015 Philippe Gerum r...@xenomai.org
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -30,6 +31,18 @@ static inline struct cobalt_resources *sem_kqueue(struct 
cobalt_sem *sem)
return cobalt_current_resources(pshared);
 }
 
+static inline int sem_check(struct cobalt_sem *sem)
+{
+   if (sem == NULL || sem-magic != COBALT_SEM_MAGIC)
+   return -EINVAL;
+
+   if (IS_ENABLED(CONFIG_XENO_OPT_DEBUG_POSIX_SYNCHRO) 
+   sem-resnode.scope  sem-resnode.scope != sem_kqueue(sem))
+   return -EPERM;
+
+   return 0;
+}
+
 int __cobalt_sem_destroy(xnhandle_t handle)
 {
struct cobalt_sem *sem;
@@ -170,51 +183,44 @@ static int sem_destroy(struct cobalt_sem_shadow *sm)
spl_t s;
 
xnlock_get_irqsave(nklock, s);
+
if (sm-magic != COBALT_SEM_MAGIC) {
ret = -EINVAL;
-   goto error;
+   goto fail;
}
 
sem = xnregistry_lookup(sm-handle, NULL);
-   if (!cobalt_obj_active(sem, COBALT_SEM_MAGIC, typeof(*sem))) {
-   ret = -EINVAL;
-   goto error;
-   }
-
-   if (sem-resnode.scope  sem_kqueue(sem) != sem-resnode.scope) {
-   ret = -EPERM;
-   goto error;
-   }
+   ret = sem_check(sem);
+   if (ret)
+   goto fail;
 
if ((sem-flags  SEM_NOBUSYDEL) != 0 
xnsynch_pended_p(sem-synchbase)) {
ret = -EBUSY;
-   goto error;
+   goto fail;
}
 
warn = sem-flags  SEM_WARNDEL;
cobalt_mark_deleted(sm);
+
xnlock_put_irqrestore(nklock, s);
 
ret = __cobalt_sem_destroy(sem-resnode.handle);
 
return warn ? ret : 0;
-
-  error:
-
+fail:
xnlock_put_irqrestore(nklock, s);
 
return ret;
 }
 
-static inline int sem_trywait_inner(struct cobalt_sem *sem)
+static inline int do_trywait(struct cobalt_sem *sem)
 {
-   if (sem == NULL || sem-magic != COBALT_SEM_MAGIC)
-   return -EINVAL;
-
-   if (IS_ENABLED(CONFIG_XENO_OPT_DEBUG_POSIX_SYNCHRO) 
-   sem-resnode.scope  sem-resnode.scope != sem_kqueue(sem))
-   return -EPERM;
+   int ret;
+   
+   ret = sem_check(sem);
+   if (ret)
+   return ret;
 
if (atomic_sub_return(1, sem-state-value)  0)
return -EAGAIN;
@@ -222,48 +228,6 @@ static inline int sem_trywait_inner(struct cobalt_sem *sem)
return 0;
 }
 
-static int sem_trywait(xnhandle_t handle)
-{
-   int err;
-   spl_t s;
-
-   xnlock_get_irqsave(nklock, s);
-   err = sem_trywait_inner(xnregistry_lookup(handle, NULL));
-   xnlock_put_irqrestore(nklock, s);
-
-   return err;
-}
-
-static int sem_post_inner(struct cobalt_sem *sem, int bcast)
-{
-   if (sem == NULL || sem-magic != COBALT_SEM_MAGIC)
-   return -EINVAL;
-
-   if (IS_ENABLED(CONFIG_XENO_OPT_DEBUG_POSIX_SYNCHRO) 
-   sem-resnode.scope  sem-resnode.scope != sem_kqueue(sem))
-   return -EPERM;
-
-   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;
@@ -273,7 +237,7 @@ static int sem_wait(xnhandle_t handle)
xnlock_get_irqsave(nklock, s);
 
sem =