* luci/contrib/olsrd-luci: add timer fix from (http://gredler.at/hg/olsrd/rev/ace7c09...
authorJo-Philipp Wich <jow@openwrt.org>
Wed, 3 Sep 2008 09:43:07 +0000 (09:43 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Wed, 3 Sep 2008 09:43:07 +0000 (09:43 +0000)
contrib/package/olsrd-luci/Makefile
contrib/package/olsrd-luci/patches/100-olsrd-timer-fix.patch [new file with mode: 0644]

index 5468814..c492f8f 100644 (file)
@@ -12,7 +12,7 @@ include $(TOPDIR)/rules.mk
 PKG_BASENAME:=olsrd
 PKG_NAME:=$(PKG_BASENAME)-luci
 PKG_VERSION:=0.5.6
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_BASENAME)-$(PKG_VERSION)
 PKG_SOURCE:=$(PKG_BASENAME)-$(PKG_VERSION).tar.bz2
diff --git a/contrib/package/olsrd-luci/patches/100-olsrd-timer-fix.patch b/contrib/package/olsrd-luci/patches/100-olsrd-timer-fix.patch
new file mode 100644 (file)
index 0000000..ea0bddc
--- /dev/null
@@ -0,0 +1,132 @@
+
+--- a/src/scheduler.c  Mon Aug 25 20:23:24 2008 +0200
++++ b/src/scheduler.c  Mon Aug 25 23:02:29 2008 +0200
+@@ -63,7 +63,6 @@ clock_t now_times;                  /* current id
+ /* Hashed root of all timers */
+ struct list_node timer_wheel[TIMER_WHEEL_SLOTS];
+ clock_t timer_last_run;                      /* remember the last timeslot walk */
+-struct list_node *timer_walk_list_node = NULL;        /* used for timeslot walk */
+ /* Pool of timers to avoid malloc() churn */
+ struct list_node free_timer_list;
+@@ -317,6 +316,35 @@ olsr_init_timers(void)
+   timers_running = 0;
+ }
++/*
++ * olsr_get_next_list_entry
++ *
++ * Get the next list node in a hash bucket.
++ * The listnode of the timer in may be subject to getting removed from
++ * this timer bucket in olsr_change_timer() and olsr_stop_timer(), which
++ * means that we can miss our walking context.
++ * By caching the previous node we can figure out if the current node
++ * has been removed from the hash bucket and compute the next node.
++ */
++static struct list_node *
++olsr_get_next_list_entry (struct list_node **prev_node,
++                          struct list_node *current_node)
++{
++  if ((*prev_node)->next == current_node) {
++
++    /*
++     * No change in the list, normal traversal, update the previous node.
++     */
++    *prev_node = current_node;
++    return (current_node->next);
++  } else {
++
++    /*
++     * List change. Recompute the walking context.
++     */
++    return ((*prev_node)->next);
++  }
++}
+ /**
+  * Walk through the timer list and check if any timer is ready to fire.
+@@ -326,7 +354,7 @@ olsr_walk_timers(clock_t * last_run)
+ olsr_walk_timers(clock_t * last_run)
+ {
+   static struct timer_entry *timer;
+-  struct list_node *timer_head_node;
++  struct list_node *timer_head_node, *timer_walk_node, *timer_walk_prev_node;
+   unsigned int timers_walked, timers_fired;
+   unsigned int total_timers_walked, total_timers_fired;
+   unsigned int wheel_slot_walks = 0;
+@@ -347,12 +375,15 @@ olsr_walk_timers(clock_t * last_run)
+     /* Get the hash slot for this clocktick */
+     timer_head_node = &timer_wheel[*last_run & TIMER_WHEEL_MASK];
++    timer_walk_prev_node = timer_head_node;
+     /* Walk all entries hanging off this hash bucket */
+-    for (timer_walk_list_node = timer_head_node->next; timer_walk_list_node != timer_head_node;       /* circular list */
+-       timer_walk_list_node = timer_walk_list_node->next) {
+-
+-      timer = list2timer(timer_walk_list_node);
++    for (timer_walk_node = timer_head_node->next;
++         timer_walk_node != timer_head_node; /* circular list */
++       timer_walk_node = olsr_get_next_list_entry(&timer_walk_prev_node,
++                                                    timer_walk_node)) {
++
++      timer = list2timer(timer_walk_node);
+       timers_walked++;
+@@ -403,11 +434,6 @@ olsr_walk_timers(clock_t * last_run)
+     /* Increment the time slot and wheel slot walk iteration */
+     (*last_run)++;
+     wheel_slot_walks++;
+-
+-    /*
+-     * Mark the timer walk context unused.
+-     */
+-    timer_walk_list_node = NULL;
+   }
+ #ifdef DEBUG
+@@ -581,21 +607,6 @@ olsr_start_timer(unsigned int rel_time, 
+   return timer;
+ }
+-/*
+- * Check if there is a timer walk in progress and advance the
+- * walking context if so. Keep in mind we are about to delete
+- * the timer from a list and this will destroy the walking context.
+- */
+-
+-static inline void
+-olsr_update_timer_walk_ctx(struct timer_entry *timer)
+-{
+-  if (timer_walk_list_node == &timer->timer_list) {
+-    timer_walk_list_node = timer_walk_list_node->next;
+-  }
+-}
+-
+-
+ /**
+  * Delete a timer.
+  *
+@@ -615,8 +626,6 @@ olsr_stop_timer(struct timer_entry *time
+             olsr_cookie_name(timer->timer_cookie),
+             timer, timer->timer_cb_context);
+ #endif
+-
+-  olsr_update_timer_walk_ctx(timer);
+   /*
+    * Carve out of the existing wheel_slot and return to the pool
+@@ -658,8 +667,6 @@ olsr_change_timer(struct timer_entry *ti
+   timer->timer_clock = olsr_jitter(rel_time, jitter_pct, timer->timer_random);
+   timer->timer_jitter_pct = jitter_pct;
+-  olsr_update_timer_walk_ctx(timer);
+-
+   /*
+    * Changes are easy: Remove timer from the exisiting timer_wheel slot
+    * and reinsert into the new slot.
+
+
+
+