Module: xenomai-gch
Branch: for-forge
Commit: 0e584746f02f8c4e832d6a58d93e385e79e95060
URL:    
http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=0e584746f02f8c4e832d6a58d93e385e79e95060

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Fri Dec 27 10:47:17 2013 +0100

cobalt/timer: factor settime/gettime, common to timer and timerfd

---

 kernel/cobalt/posix/timer.c   |   72 +++++++++++++++++++++++++----------------
 kernel/cobalt/posix/timer.h   |    7 ++++
 kernel/cobalt/posix/timerfd.c |   37 +++++----------------
 3 files changed, 60 insertions(+), 56 deletions(-)

diff --git a/kernel/cobalt/posix/timer.c b/kernel/cobalt/posix/timer.c
index 17d7063..18dcb29 100644
--- a/kernel/cobalt/posix/timer.c
+++ b/kernel/cobalt/posix/timer.c
@@ -26,7 +26,6 @@
 #include <linux/err.h>
 #include "internal.h"
 #include "thread.h"
-#include "signal.h"
 #include "timer.h"
 #include "clock.h"
 
@@ -266,6 +265,21 @@ out:
        return ret;
 }
 
+void cobalt_xntimer_gettime(struct xntimer *__restrict__ timer, 
+                       struct itimerspec *__restrict__ value)
+{
+       if (!xntimer_running_p(timer)) {
+               value->it_value.tv_sec = 0;
+               value->it_value.tv_nsec = 0;
+               value->it_interval.tv_sec = 0;
+               value->it_interval.tv_nsec = 0;
+               return;
+       }
+
+       ns2ts(&value->it_value, xntimer_get_timeout(timer));
+       ns2ts(&value->it_interval, xntimer_interval(timer));
+}
+
 static inline void
 timer_gettimeout(struct cobalt_timer *__restrict__ timer,
                 struct itimerspec *__restrict__ value)
@@ -281,19 +295,39 @@ timer_gettimeout(struct cobalt_timer *__restrict__ timer,
        }
 
        if (!cobalt_call_extension(timer_gettime, &timer->extref,
-                                  ret, value) || ret == 0) {
-               ns2ts(&value->it_value,
-                     xntimer_get_timeout(&timer->timerbase));
-               ns2ts(&value->it_interval,
-                     xntimer_interval(&timer->timerbase));
-       }
+                                  ret, value) || ret == 0)
+               cobalt_xntimer_gettime(&timer->timerbase, value);
 }
 
+int cobalt_xntimer_settime(struct xntimer *__restrict__ timer, int clock_flag, 
+                       const struct itimerspec *__restrict__ value)
+{
+       xnticks_t start, period;
+
+       if (value->it_value.tv_nsec == 0 && value->it_value.tv_sec == 0) {
+               xntimer_stop(timer);
+               return 0;
+       }
+
+       if ((unsigned long)value->it_value.tv_nsec >= ONE_BILLION ||
+           ((unsigned long)value->it_interval.tv_nsec >= ONE_BILLION &&
+            (value->it_value.tv_sec != 0 || value->it_value.tv_nsec != 0)))
+               return -EINVAL;
+
+       start = ts2ns(&value->it_value) + 1;
+       period = ts2ns(&value->it_interval);
+
+       /*
+        * Now start the timer. If the timeout data has already
+        * passed, the caller will handle the case.
+        */
+       return xntimer_start(timer, start, period, clock_flag);
+}                      
+
 static inline int timer_set(struct cobalt_timer *timer, int flags,
                            const struct itimerspec *__restrict__ value)
 {                              /* nklocked, IRQs off. */
        struct cobalt_thread *thread;
-       xnticks_t start, period;
        int ret;
 
        /* First, try offloading the work to an extension. */
@@ -307,19 +341,6 @@ static inline int timer_set(struct cobalt_timer *timer, 
int flags,
         * POSIX behavior.
         */
 
-       if (value->it_value.tv_nsec == 0 && value->it_value.tv_sec == 0) {
-               xntimer_stop(&timer->timerbase);
-               return 0;
-       }
-
-       if ((unsigned long)value->it_value.tv_nsec >= ONE_BILLION ||
-           ((unsigned long)value->it_interval.tv_nsec >= ONE_BILLION &&
-            (value->it_value.tv_sec != 0 || value->it_value.tv_nsec != 0)))
-               return -EINVAL;
-
-       start = ts2ns(&value->it_value) + 1;
-       period = ts2ns(&value->it_interval);
-
        /*
         * If the target thread vanished, simply don't start the
         * timer.
@@ -333,12 +354,9 @@ static inline int timer_set(struct cobalt_timer *timer, 
int flags,
         * signaled.
         */
        xntimer_set_sched(&timer->timerbase, thread->threadbase.sched);
-       /*
-        * Now start the timer. If the timeout data has already
-        * passed, the caller will handle the case.
-        */
-       return xntimer_start(&timer->timerbase, start, period,
-                            clock_flag(flags, timer->clockid));
+
+       return cobalt_xntimer_settime(&timer->timerbase, 
+                               clock_flag(flags, timer->clockid), value);
 }
 
 static inline void
diff --git a/kernel/cobalt/posix/timer.h b/kernel/cobalt/posix/timer.h
index 5b361c9..b9ff95a 100644
--- a/kernel/cobalt/posix/timer.h
+++ b/kernel/cobalt/posix/timer.h
@@ -22,6 +22,7 @@
 #include <linux/time.h>
 #include <linux/list.h>
 #include <cobalt/kernel/timer.h>
+#include "signal.h"
 
 struct cobalt_thread;
 struct cobalt_kqueues;
@@ -72,6 +73,12 @@ static inline struct cobalt_timer 
*cobalt_timer_by_id(timer_t timer_id)
        return &cobalt_timer_pool[(unsigned int)timer_id];
 }
 
+void cobalt_xntimer_gettime(struct xntimer *__restrict__ timer, 
+                       struct itimerspec *__restrict__ value);
+
+int cobalt_xntimer_settime(struct xntimer *__restrict__ timer, int clock_flag, 
+                       const struct itimerspec *__restrict__ value);
+
 void cobalt_timer_handler(struct xntimer *xntimer);
 
 #endif /* !_COBALT_POSIX_TIMER_H */
diff --git a/kernel/cobalt/posix/timerfd.c b/kernel/cobalt/posix/timerfd.c
index cf8156d..292666c 100644
--- a/kernel/cobalt/posix/timerfd.c
+++ b/kernel/cobalt/posix/timerfd.c
@@ -22,6 +22,7 @@
 #include <cobalt/kernel/select.h>
 #include "internal.h"
 #include "clock.h"
+#include "timer.h"
 #include "timerfd.h"
 
 struct cobalt_tfd {
@@ -64,7 +65,9 @@ static ssize_t timerfd_read(struct xnfd *xnfd, void __user 
*buf, size_t size)
        }
        
        xntimer_set_sched(&tfd->timer, xnsched_current());
-       err = xnsynch_sleep_on(&tfd->readers, XN_INFINITE, XN_RELATIVE);
+       do {
+               err = xnsynch_sleep_on(&tfd->readers, XN_INFINITE, XN_RELATIVE);
+       } while (err == 0 && (tfd->flags & COBALT_TFD_TICKED) == 0);
 
   out:
        if (err == 0) {
@@ -199,28 +202,12 @@ static inline void tfd_put(struct cobalt_tfd *tfd)
        xnfd_put(&tfd->xnfd);
 }
 
-static inline void 
-timerfd_gettime(struct cobalt_tfd *tfd, struct itimerspec *value)
-{
-       if (xntimer_running_p(&tfd->timer) == 0) {
-               value->it_value.tv_sec = 0;
-               value->it_value.tv_nsec = 0;
-               value->it_interval.tv_sec = 0;
-               value->it_interval.tv_nsec = 0;
-               return;
-       }
-       
-       ns2ts(&value->it_value, xntimer_get_timeout(&tfd->timer));
-       ns2ts(&value->it_interval, xntimer_interval(&tfd->timer));
-}
-
 int cobalt_timerfd_settime(int fd, int flags,
                        const struct itimerspec __user *new_value,
                        struct itimerspec __user *old_value)
 {
        struct itimerspec ovalue, value;
        struct cobalt_tfd *tfd;
-       xnticks_t start, period;
        int err;
        spl_t s;
 
@@ -234,22 +221,14 @@ int cobalt_timerfd_settime(int fd, int flags,
                goto out;
        }
 
-       start = ts2ns(&value.it_value) + 1;
-       period = ts2ns(&value.it_interval);
        flags = (flags & TFD_TIMER_ABSTIME) ? TIMER_ABSTIME : 0;
        
        xnlock_get_irqsave(&nklock, s);
        if (old_value)
-               timerfd_gettime(tfd, &ovalue);
+               cobalt_xntimer_gettime(&tfd->timer, &ovalue);
 
-       if (start == 0) {
-               xntimer_stop(&tfd->timer);
-               err = 0;
-       } else {
-               xntimer_set_sched(&tfd->timer, xnsched_current());
-               err = xntimer_start(&tfd->timer, start, period, 
-                               clock_flag(flags, tfd->clockid));
-       }
+       err = cobalt_xntimer_settime(&tfd->timer, 
+                               clock_flag(flags, tfd->clockid), &value);
        xnlock_put_irqrestore(&nklock, s);
 
        if (err == 0 && old_value &&
@@ -279,7 +258,7 @@ int cobalt_timerfd_gettime(int fd, struct itimerspec __user 
*curr_value)
                return PTR_ERR(tfd);
 
        xnlock_get_irqsave(&nklock, s);
-       timerfd_gettime(tfd, &value);
+       cobalt_xntimer_gettime(&tfd->timer, &value);
        xnlock_put_irqrestore(&nklock, s);
        
        if (!curr_value || __xn_copy_to_user(curr_value, &value, sizeof(value)))


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

Reply via email to