diff options
author | Jo-Philipp Wich <jow@openwrt.org> | 2008-09-03 09:43:07 +0000 |
---|---|---|
committer | Jo-Philipp Wich <jow@openwrt.org> | 2008-09-03 09:43:07 +0000 |
commit | e97527fa0617d76dbe2e9513bce264f3486c089a (patch) | |
tree | 245c9a016f4f8495f173203b505b41aefaabf2e3 /contrib/package/olsrd-luci/patches | |
parent | eedb43da9b5193380faeeb39754298335a0f0bb9 (diff) |
* luci/contrib/olsrd-luci: add timer fix from (http://gredler.at/hg/olsrd/rev/ace7c0970ec)
Diffstat (limited to 'contrib/package/olsrd-luci/patches')
-rw-r--r-- | contrib/package/olsrd-luci/patches/100-olsrd-timer-fix.patch | 132 |
1 files changed, 132 insertions, 0 deletions
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 index 0000000000..ea0bddc959 --- /dev/null +++ b/contrib/package/olsrd-luci/patches/100-olsrd-timer-fix.patch @@ -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. + + + + |