bugfix: do a proper list merging of the temporary timer list
authorHannes Gredler <hannes@gredler.at>
Tue, 25 Nov 2008 12:45:10 +0000 (13:45 +0100)
committerHannes Gredler <hannes@gredler.at>
Tue, 25 Nov 2008 12:45:10 +0000 (13:45 +0100)
src/common/list.h
src/scheduler.c

index 726d25b..7eb6ef5 100644 (file)
@@ -60,6 +60,21 @@ void list_add_after(struct list_node *, struct list_node *);
 
 void list_remove(struct list_node *);
 
+/*
+ * Merge elements of list_head2 at the end of list_head1.
+ * list_head2 will be left empty.
+ */
+static inline void list_merge(struct list_node *list_head1, struct list_node *list_head2) \
+{ \
+  if (!list_is_empty(list_head2)) {  \
+     list_head1->next->prev = list_head2->prev; \
+     list_head2->prev->next = list_head1->next; \
+     list_head1->next = list_head2->next; \
+     list_head2->next->prev = list_head1; \
+     list_head2->next = list_head2->prev = list_head2; \
+  } \
+}
+
 /*
  * Macro to define an inline function to map from a list_node offset back to the
  * base of the datastructure. That way you save an extra data pointer.
index bf26030..d1e6ebb 100644 (file)
@@ -339,7 +339,7 @@ olsr_walk_timers(clock_t * last_run)
     /* Walk all entries hanging off this hash bucket */
     list_head_init(&tmp_head_node);
     for (timer_node = timer_head_node->next;
-         timer_node != timer_head_node;   /* circular list */
+         !list_is_empty(timer_head_node);
          timer_node = timer_head_node->next) {
 
       /*
@@ -392,10 +392,9 @@ olsr_walk_timers(clock_t * last_run)
     }
 
     /*
-     * Now mount the temporary list back to the old bucket.
+     * Now merge the temporary list back to the old bucket.
      */
-    list_add_after(timer_head_node, &tmp_head_node);
-    list_remove(&tmp_head_node);
+    list_merge(timer_head_node, &tmp_head_node);
 
     /* Increment the time slot and wheel slot walk iteration */
     (*last_run)++;