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

Reply via email to