Module: xenomai-forge Branch: master Commit: dad32967e94f5fff4edcffd4a78300442d79f0b9 URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=dad32967e94f5fff4edcffd4a78300442d79f0b9
Author: Philippe Gerum <r...@xenomai.org> Date: Tue Dec 13 15:53:03 2011 +0100 kernel/cobalt: introduce monotonic clock-based sem_timedwait() POSIX mandates that timed waits on semaphores be based on CLOCK_REALTIME. We introduce a non-standard variant allowing CLOCK_MONOTONIC to be used instead, if SEM_RAWCLOCK is mentioned in the creation flags passed to sem_init_np(). --- include/cobalt/semaphore.h | 1 + kernel/cobalt/sem.c | 36 ++++++++++++++++++++---------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/include/cobalt/semaphore.h b/include/cobalt/semaphore.h index c7a29c3..312e73a 100644 --- a/include/cobalt/semaphore.h +++ b/include/cobalt/semaphore.h @@ -110,6 +110,7 @@ COBALT_DECL(int, sem_unlink(const char *name)); #define SEM_PSHARED 0x4 #define SEM_REPORT 0x8 #define SEM_WARNDEL 0x10 +#define SEM_RAWCLOCK 0x20 int sem_init_np(sem_t *sem, int flags, diff --git a/kernel/cobalt/sem.c b/kernel/cobalt/sem.c index 6b1918c..e650fac 100644 --- a/kernel/cobalt/sem.c +++ b/kernel/cobalt/sem.c @@ -521,26 +521,27 @@ static int sem_trywait(cobalt_sem_t *sem) static inline int sem_timedwait_internal(cobalt_sem_t *sem, int timed, xnticks_t to) { - xnthread_t *cur; - int err; - - cur = xnpod_current_thread(); + xntmode_t tmode; + xnflags_t info; + int ret; - if ((err = sem_trywait_internal(sem)) != -EAGAIN) - return err; + ret = sem_trywait_internal(sem); + if (ret != -EAGAIN) + return ret; - if (timed) - xnsynch_sleep_on(&sem->synchbase, to, XN_REALTIME); - else - xnsynch_sleep_on(&sem->synchbase, XN_INFINITE, XN_RELATIVE); + if (timed) { + tmode = sem->flags & SEM_RAWCLOCK ? XN_ABSOLUTE : XN_REALTIME; + info = xnsynch_sleep_on(&sem->synchbase, to, tmode); + } else + info = xnsynch_sleep_on(&sem->synchbase, XN_INFINITE, XN_RELATIVE); - if (xnthread_test_info(cur, XNRMID)) + if (info & XNRMID) return -EINVAL; - if (xnthread_test_info(cur, XNBREAK)) + if (info & XNBREAK) return -EINTR; - if (xnthread_test_info(cur, XNTIMEO)) + if (info & XNTIMEO) return -ETIMEDOUT; return 0; @@ -599,8 +600,10 @@ static int sem_wait(cobalt_sem_t *sem) * * @param sm the semaphore to be decremented; * - * @param abs_timeout the timeout, expressed as an absolute value of the - * CLOCK_REALTIME clock. + * @param abs_timeout the timeout, expressed as an absolute value of + * the relevant clock for the semaphore, either CLOCK_MONOTONIC if + * SEM_RAWCLOCK was mentioned via sem_init_np(), or CLOCK_REALTIME + * otherwise. * * @retval 0 on success; * @retval -1 with @a errno set if: @@ -987,7 +990,8 @@ int cobalt_sem_init_np(struct __shadow_sem __user *u_sem, if (__xn_safe_copy_from_user(&sm, u_sem, sizeof(sm))) return -EFAULT; - if (flags & ~(SEM_FIFO|SEM_PULSE|SEM_PSHARED|SEM_REPORT|SEM_WARNDEL)) + if (flags & ~(SEM_FIFO|SEM_PULSE|SEM_PSHARED|\ + SEM_REPORT|SEM_WARNDEL|SEM_RAWCLOCK)) return -EINVAL; err = do_sem_init(&sm, flags, value); _______________________________________________ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git