Module: xenomai-jki Branch: for-forge Commit: 31fd197967442eca07b68d22aaad297d57c441c9 URL: http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=31fd197967442eca07b68d22aaad297d57c441c9
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