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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Wed Mar  4 14:35:53 2015 +0100

cobalt/timer: fix heap-based timer management

---

 include/cobalt/kernel/bheap.h |   20 ++++++++++++++++++++
 include/cobalt/kernel/timer.h |   15 ++++++++++++++-
 kernel/cobalt/clock.c         |    5 ++---
 kernel/cobalt/timer.c         |    5 ++---
 4 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/include/cobalt/kernel/bheap.h b/include/cobalt/kernel/bheap.h
index 4506c2a..4c05bb4 100644
--- a/include/cobalt/kernel/bheap.h
+++ b/include/cobalt/kernel/bheap.h
@@ -80,6 +80,13 @@ static inline bheaph_t *__internal_bheap_gethead(bheap_t 
*heap)
        return heap->elems[1];
 }
 
+#define bheap_second(heap)                             \
+       ({                                              \
+               bheap_t *_bheap = &(heap)->bheap;       \
+               BHEAP_CHECK(_bheap);                    \
+               __internal_bheap_second(_bheap);        \
+       })
+
 #define bheap_next(heap, holder)                       \
        ({                                              \
                bheap_t *_bheap = &(heap)->bheap;       \
@@ -114,6 +121,19 @@ static inline bheaph_t *bheaph_child(bheap_t *heap, 
bheaph_t *holder, int side)
        return likely(pos < heap->last) ? heap->elems[pos] : NULL;
 }
 
+static inline bheaph_t *__internal_bheap_second(bheap_t *heap)
+{
+       bheaph_t *left, *right, *first = __internal_bheap_gethead(heap);
+ 
+       left = bheaph_child(heap, first, 0);
+       right = bheaph_child(heap, first, 1);
+ 
+       if (!left || !right)
+               return left ?: right;
+ 
+       return bheaph_lt(left, right) ? left : right;
+}
+ 
 #define bheap_init(heap, sz) __internal_bheap_init(&(heap)->bheap, sz)
 
 static inline void __internal_bheap_init(bheap_t *heap, unsigned sz)
diff --git a/include/cobalt/kernel/timer.h b/include/cobalt/kernel/timer.h
index 60f900b..7fc4f73 100644
--- a/include/cobalt/kernel/timer.h
+++ b/include/cobalt/kernel/timer.h
@@ -86,6 +86,12 @@ struct xntlholder {
                h;                                                      \
        })
 
+#define xntlist_second(q)                                              \
+       ({                                                              \
+               struct xntlholder *_h = xntlist_head(q);                \
+               _h == NULL ? NULL : xntlist_next(q, _h);                \
+       })
+
 #define xntlist_next(q, h)                                             \
        ({                                                              \
                struct xntlholder *_h = list_is_last(&h->link, q) ? NULL : \
@@ -138,11 +144,17 @@ typedef DECLARE_BHEAP_CONTAINER(xntimerq_t, 
CONFIG_XENO_OPT_TIMER_HEAP_CAPACITY)
 #define xntimerq_destroy(q)       bheap_destroy(q)
 #define xntimerq_empty(q)         bheap_empty(q)
 #define xntimerq_head(q)          bheap_gethead(q)
+#define xntimerq_second(q)        bheap_second(q)
 #define xntimerq_insert(q, h)     bheap_insert((q),(h))
 #define xntimerq_remove(q, h)     bheap_delete((q),(h))
 
 typedef struct {} xntimerq_it_t;
 
+/*
+ * BIG FAT WARNING: the iterator does NOT guarantee any particular
+ * order when returning elements (typically, items may be returned in
+ * random timestamp order).
+ */
 #define xntimerq_it_begin(q, i)   ((void) (i), bheap_gethead(q))
 #define xntimerq_it_next(q, i, h) ((void) (i), bheap_next((q),(h)))
 
@@ -160,7 +172,8 @@ typedef struct list_head xntimerq_t;
 #define xntimerq_destroy(q)     do { } while (0)
 #define xntimerq_empty(q)       xntlist_empty(q)
 #define xntimerq_head(q)        xntlist_head(q)
-#define xntimerq_insert(q,h)    xntlist_insert((q),(h))
+#define xntimerq_second(q)      xntlist_second(q)
+#define xntimerq_insert(q, h)   xntlist_insert((q),(h))
 #define xntimerq_remove(q, h)   xntlist_remove((q),(h))
 
 typedef struct { } xntimerq_it_t;
diff --git a/kernel/cobalt/clock.c b/kernel/cobalt/clock.c
index 9338e67..35f20f2 100644
--- a/kernel/cobalt/clock.c
+++ b/kernel/cobalt/clock.c
@@ -126,7 +126,6 @@ void xnclock_core_local_shot(struct xnsched *sched)
        struct xntimerdata *tmd;
        struct xntimer *timer;
        xnsticks_t delay;
-       xntimerq_it_t it;
        xntimerh_t *h;
 
        /*
@@ -138,7 +137,7 @@ void xnclock_core_local_shot(struct xnsched *sched)
                return;
 
        tmd = xnclock_this_timerdata(&nkclock);
-       h = xntimerq_it_begin(&tmd->q, &it);
+       h = xntimerq_head(&tmd->q);
        if (h == NULL)
                return;
 
@@ -167,7 +166,7 @@ void xnclock_core_local_shot(struct xnsched *sched)
        if (unlikely(timer == &sched->htimer)) {
                if (xnsched_resched_p(sched) ||
                    !xnthread_test_state(sched->curr, XNROOT)) {
-                       h = xntimerq_it_next(&tmd->q, &it, h);
+                       h = xntimerq_second(&tmd->q);
                        if (h) {
                                sched->lflags |= XNHDEFER;
                                timer = container_of(h, struct xntimer, aplink);
diff --git a/kernel/cobalt/timer.c b/kernel/cobalt/timer.c
index 6165fab..9149730 100644
--- a/kernel/cobalt/timer.c
+++ b/kernel/cobalt/timer.c
@@ -46,17 +46,16 @@
 int xntimer_heading_p(struct xntimer *timer)
 {
        struct xnsched *sched = timer->sched;
-       xntimerq_it_t it;
        xntimerq_t *q;
        xntimerh_t *h;
 
        q = xntimer_percpu_queue(timer);
-       h = xntimerq_it_begin(q, &it);
+       h = xntimerq_head(q);
        if (h == &timer->aplink)
                return 1;
 
        if (sched->lflags & XNHDEFER) {
-               h = xntimerq_it_next(q, &it, h);
+               h = xntimerq_second(q);
                if (h == &timer->aplink)
                        return 1;
        }


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

Reply via email to