Module: xenomai-forge
Branch: next
Commit: c29cf77d9a1c94d26ea145346a8cd58d5e2a2186
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=c29cf77d9a1c94d26ea145346a8cd58d5e2a2186

Author: Philippe Gerum <r...@xenomai.org>
Date:   Sun Aug  3 11:30:59 2014 +0200

cobalt/timer: make timers affine to scheduler slots

Change the affinity target from a thread to a scheduler slot for
initializing timers, since this is the information we need in the
end.

In addition, we might race with a target thread vanishing on a remote
CPU in some cases, which can't happen with scheduler slots.

---

 include/cobalt/kernel/timer.h  |    6 +++---
 kernel/cobalt/posix/timer.c    |    6 +++---
 kernel/cobalt/posix/timerfd.c  |    6 ++++--
 kernel/cobalt/sched-quota.c    |    4 ++--
 kernel/cobalt/sched-sporadic.c |    4 ++--
 kernel/cobalt/sched-tp.c       |    2 +-
 kernel/cobalt/sched.c          |    6 +++---
 kernel/cobalt/thread.c         |   14 +++++++-------
 kernel/cobalt/timer.c          |   28 ++++++++++++++--------------
 9 files changed, 39 insertions(+), 37 deletions(-)

diff --git a/include/cobalt/kernel/timer.h b/include/cobalt/kernel/timer.h
index 83fd16a..dcb6927 100644
--- a/include/cobalt/kernel/timer.h
+++ b/include/cobalt/kernel/timer.h
@@ -312,7 +312,7 @@ static inline int xntimer_periodic_p(struct xntimer *timer)
 void __xntimer_init(struct xntimer *timer,
                    struct xnclock *clock,
                    void (*handler)(struct xntimer *timer),
-                   struct xnthread *thread,
+                   struct xnsched *sched,
                    int flags);
 
 void xntimer_set_gravity(struct xntimer *timer,
@@ -320,9 +320,9 @@ void xntimer_set_gravity(struct xntimer *timer,
 
 #ifdef CONFIG_XENO_OPT_STATS
 
-#define xntimer_init(__timer, __clock, __handler, __thread, __flags)   \
+#define xntimer_init(__timer, __clock, __handler, __sched, __flags)    \
 do {                                                                   \
-       __xntimer_init(__timer, __clock, __handler, __thread, __flags); \
+       __xntimer_init(__timer, __clock, __handler, __sched, __flags);  \
        xntimer_set_name(__timer, #__handler);                          \
 } while (0)
 
diff --git a/kernel/cobalt/posix/timer.c b/kernel/cobalt/posix/timer.c
index 56e0c50..688e280 100644
--- a/kernel/cobalt/posix/timer.c
+++ b/kernel/cobalt/posix/timer.c
@@ -43,7 +43,7 @@ EXPORT_SYMBOL_GPL(cobalt_timer_handler);
 
 static inline struct cobalt_thread *
 timer_init(struct cobalt_timer *timer,
-          const struct sigevent *__restrict__ evp)
+          const struct sigevent *__restrict__ evp) /* nklocked, IRQs off. */
 {
        struct cobalt_thread *owner = cobalt_current_thread(), *target = NULL;
 
@@ -85,7 +85,7 @@ timer_init(struct cobalt_timer *timer,
         * want to deliver a signal when a timer elapses.
         */
        xntimer_init(&timer->timerbase, &nkclock, cobalt_timer_handler,
-                    &target->threadbase, XNTIMER_UGRAVITY);
+                    xnthread_sched(&target->threadbase), XNTIMER_UGRAVITY);
 
        return target;
 }
@@ -346,7 +346,7 @@ static inline int timer_set(struct cobalt_timer *timer, int 
flags,
         * Make the timer affine to the CPU running the thread to be
         * signaled.
         */
-       xntimer_set_sched(&timer->timerbase, thread->threadbase.sched);
+       xntimer_set_sched(&timer->timerbase, 
xnthread_sched(&thread->threadbase));
 
        return cobalt_xntimer_settime(&timer->timerbase,
                                clock_flag(flags, timer->clockid), value);
diff --git a/kernel/cobalt/posix/timerfd.c b/kernel/cobalt/posix/timerfd.c
index 33a10ed..36bd60c 100644
--- a/kernel/cobalt/posix/timerfd.c
+++ b/kernel/cobalt/posix/timerfd.c
@@ -103,7 +103,7 @@ static ssize_t timerfd_read(struct rtdm_fd *fd, void __user 
*buf, size_t size)
 
 static int
 timerfd_select_bind(struct rtdm_fd *fd, struct xnselector *selector,
-               unsigned type, unsigned index)
+                   unsigned type, unsigned index)
 {
        struct cobalt_tfd *tfd = container_of(fd, struct cobalt_tfd, fd);
        struct xnselect_binding *binding;
@@ -164,6 +164,7 @@ static void timerfd_handler(struct xntimer *xntimer)
 int cobalt_timerfd_create(int ufd, int clockid, int flags)
 {
        struct cobalt_tfd *tfd;
+       struct xnthread *curr;
        struct xnsys_ppd *p;
 
        p = xnsys_ppd_get(0);
@@ -182,8 +183,9 @@ int cobalt_timerfd_create(int ufd, int clockid, int flags)
 
        tfd->flags = flags;
        tfd->clockid = clockid;
+       curr = xnshadow_current();
        xntimer_init(&tfd->timer, &nkclock, timerfd_handler,
-                    xnshadow_current(), XNTIMER_UGRAVITY);
+                    curr ? xnthread_sched(curr) : NULL, XNTIMER_UGRAVITY);
        xnsynch_init(&tfd->readers, XNSYNCH_PRIO | XNSYNCH_NOPIP, NULL);
        xnselect_init(&tfd->read_select);
        tfd->target = NULL;
diff --git a/kernel/cobalt/sched-quota.c b/kernel/cobalt/sched-quota.c
index c43244a..a5d98f4 100644
--- a/kernel/cobalt/sched-quota.c
+++ b/kernel/cobalt/sched-quota.c
@@ -224,13 +224,13 @@ static void xnsched_quota_init(struct xnsched *sched)
        strcpy(limiter_name, "[quota-limit]");
 #endif
        xntimer_init(&qs->refill_timer,
-                    &nkclock, quota_refill_handler, NULL,
+                    &nkclock, quota_refill_handler, sched,
                     XNTIMER_NOBLCK|XNTIMER_IGRAVITY);
        xntimer_set_sched(&qs->refill_timer, sched);
        xntimer_set_name(&qs->refill_timer, refiller_name);
 
        xntimer_init(&qs->limit_timer,
-                    &nkclock, quota_limit_handler, NULL,
+                    &nkclock, quota_limit_handler, sched,
                     XNTIMER_NOBLCK|XNTIMER_IGRAVITY);
        xntimer_set_sched(&qs->limit_timer, sched);
        xntimer_set_name(&qs->limit_timer, limiter_name);
diff --git a/kernel/cobalt/sched-sporadic.c b/kernel/cobalt/sched-sporadic.c
index e869dc6..18356cf 100644
--- a/kernel/cobalt/sched-sporadic.c
+++ b/kernel/cobalt/sched-sporadic.c
@@ -315,10 +315,10 @@ static int xnsched_sporadic_declare(struct xnthread 
*thread,
                return -ENOMEM;
 
        xntimer_init(&pss->repl_timer, &nkclock, sporadic_replenish_handler,
-                    thread, XNTIMER_IGRAVITY);
+                    xnthread_sched(thread), XNTIMER_IGRAVITY);
        xntimer_set_name(&pss->repl_timer, "pss-replenish");
        xntimer_init(&pss->drop_timer, &nkclock, sporadic_drop_handler,
-                    thread, XNTIMER_IGRAVITY);
+                    xnthread_sched(thread), XNTIMER_IGRAVITY);
        xntimer_set_name(&pss->drop_timer, "pss-drop");
 
        thread->pss = pss;
diff --git a/kernel/cobalt/sched-tp.c b/kernel/cobalt/sched-tp.c
index 7f48fe0..4efed95 100644
--- a/kernel/cobalt/sched-tp.c
+++ b/kernel/cobalt/sched-tp.c
@@ -101,7 +101,7 @@ static void xnsched_tp_init(struct xnsched *sched)
        tp->gps = NULL;
        INIT_LIST_HEAD(&tp->threads);
        xntimer_init(&tp->tf_timer, &nkclock, tp_tick_handler,
-                    NULL, XNTIMER_NOBLCK|XNTIMER_IGRAVITY);
+                    sched, XNTIMER_NOBLCK|XNTIMER_IGRAVITY);
        xntimer_set_sched(&tp->tf_timer, sched);
        xntimer_set_name(&tp->tf_timer, timer_name);
 }
diff --git a/kernel/cobalt/sched.c b/kernel/cobalt/sched.c
index 4e4ca0d..db87e4c 100644
--- a/kernel/cobalt/sched.c
+++ b/kernel/cobalt/sched.c
@@ -192,11 +192,11 @@ void xnsched_init(struct xnsched *sched, int cpu)
         * exit code.
         */
        xntimer_init(&sched->htimer, &nkclock, NULL,
-                    &sched->rootcb, XNTIMER_IGRAVITY);
+                    sched, XNTIMER_IGRAVITY);
        xntimer_set_priority(&sched->htimer, XNTIMER_LOPRIO);
        xntimer_set_name(&sched->htimer, htimer_name);
        xntimer_init(&sched->rrbtimer, &nkclock, roundrobin_handler,
-                    &sched->rootcb, XNTIMER_IGRAVITY);
+                    sched, XNTIMER_IGRAVITY);
        xntimer_set_name(&sched->rrbtimer, rrbtimer_name);
        xntimer_set_priority(&sched->rrbtimer, XNTIMER_LOPRIO);
 
@@ -211,7 +211,7 @@ void xnsched_init(struct xnsched *sched, int cpu)
 
 #ifdef CONFIG_XENO_OPT_WATCHDOG
        xntimer_init(&sched->wdtimer, &nkclock, watchdog_handler,
-                    &sched->rootcb, XNTIMER_NOBLCK|XNTIMER_IGRAVITY);
+                    sched, XNTIMER_NOBLCK|XNTIMER_IGRAVITY);
        xntimer_set_name(&sched->wdtimer, "[watchdog]");
        xntimer_set_priority(&sched->wdtimer, XNTIMER_LOPRIO);
 #endif /* CONFIG_XENO_OPT_WATCHDOG */
diff --git a/kernel/cobalt/thread.c b/kernel/cobalt/thread.c
index 47ede97..c801dd9 100644
--- a/kernel/cobalt/thread.c
+++ b/kernel/cobalt/thread.c
@@ -141,7 +141,7 @@ int __xnthread_init(struct xnthread *thread,
                    struct xnsched_class *sched_class,
                    const union xnsched_policy_param *sched_param)
 {
-       int flags = attr->flags, ret;
+       int flags = attr->flags, ret, gravity;
        spl_t s;
 
        flags &= ~XNSUSP;
@@ -187,14 +187,14 @@ int __xnthread_init(struct xnthread *thread,
        thread->entry = NULL;
        thread->cookie = NULL;
 
-       xntimer_init(&thread->rtimer, &nkclock, timeout_handler, thread,
-                    xnthread_test_state(thread, XNUSER) ?
-                    XNTIMER_UGRAVITY : XNTIMER_KGRAVITY);
+       gravity = xnthread_test_state(thread, XNUSER) ?
+               XNTIMER_UGRAVITY : XNTIMER_KGRAVITY;
+       xntimer_init(&thread->rtimer, &nkclock, timeout_handler,
+                    sched, gravity);
        xntimer_set_name(&thread->rtimer, thread->name);
        xntimer_set_priority(&thread->rtimer, XNTIMER_HIPRIO);
-       xntimer_init(&thread->ptimer, &nkclock, periodic_handler, thread,
-                    xnthread_test_state(thread, XNUSER) ?
-                    XNTIMER_UGRAVITY : XNTIMER_KGRAVITY);
+       xntimer_init(&thread->ptimer, &nkclock, periodic_handler,
+                    sched, gravity);
        xntimer_set_name(&thread->ptimer, thread->name);
        xntimer_set_priority(&thread->ptimer, XNTIMER_HIPRIO);
 
diff --git a/kernel/cobalt/timer.c b/kernel/cobalt/timer.c
index 6f91053..360ce86 100644
--- a/kernel/cobalt/timer.c
+++ b/kernel/cobalt/timer.c
@@ -272,7 +272,7 @@ xnticks_t xntimer_get_timeout(struct xntimer *timer)
 EXPORT_SYMBOL_GPL(xntimer_get_timeout);
 
 /**
- * @fn void xntimer_init(struct xntimer *timer,struct xnclock *clock,void 
(*handler)(struct xntimer *timer), struct xnthread *thread, int flags)
+ * @fn void xntimer_init(struct xntimer *timer,struct xnclock *clock,void 
(*handler)(struct xntimer *timer), struct xnsched *sched, int flags)
  * @brief Initialize a timer object.
  *
  * Creates a timer. When created, a timer is left disarmed; it must be
@@ -290,10 +290,10 @@ EXPORT_SYMBOL_GPL(xntimer_get_timeout);
  *
  * @param handler The routine to call upon expiration of the timer.
  *
- * @param thread The optional thread object the new timer is affine
- * to. If non-NULL, the timer will fire on the same CPU @a thread
- * currently runs on by default, otherwise it will fire on the CPU
- * which initialized it.
+ * @param sched An optional pointer to the per-CPU scheduler slot the
+ * new timer is affine to. If non-NULL, the timer will fire on the CPU
+ * @a sched is bound to, otherwise it will fire either on the current
+ * CPU if real-time, or on the first real-time CPU.
  *
  * @param flags A set of flags describing the timer. The valid flags are:
  *
@@ -316,14 +316,14 @@ EXPORT_SYMBOL_GPL(xntimer_get_timeout);
 #ifdef DOXYGEN_CPP
 void xntimer_init(struct xntimer *timer, struct xnclock *clock,
                  void (*handler)(struct xntimer *timer),
-                 struct xnthread *thread,
+                 struct xnsched *sched,
                  int flags);
 #endif
 
 void __xntimer_init(struct xntimer *timer,
                    struct xnclock *clock,
                    void (*handler)(struct xntimer *timer),
-                   struct xnthread *thread,
+                   struct xnsched *sched,
                    int flags)
 {
        spl_t s __maybe_unused;
@@ -339,14 +339,14 @@ void __xntimer_init(struct xntimer *timer,
        timer->handler = handler;
        timer->interval_ns = 0;
        /*
-        * Timers have to run on a real-time CPU, i.e. a member of the
-        * xnsched_realtime_cpus mask. If the new timer is affine to a
-        * thread, we assign it the same CPU (which has to be
-        * correct), otherwise pick the current CPU if valid, or the
-        * first valid real-time CPU otherwise.
+        * Timers are affine to a scheduler slot, which is in turn
+        * bound to a real-time CPU. If no scheduler affinity was
+        * given, assign the timer to the scheduler slot of the
+        * current CPU if real-time, otherwise default to the
+        * scheduler slot of the first real-time CPU.
         */
-       if (thread)
-               timer->sched = thread->sched;
+       if (sched)
+               timer->sched = sched;
        else {
                cpu = ipipe_processor_id();
                if (!xnsched_supported_cpu(cpu))


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

Reply via email to