aboutsummaryrefslogtreecommitdiffstats
path: root/src/vppinfra
diff options
context:
space:
mode:
authorGabriel Ganne <gabriel.ganne@enea.com>2017-02-15 16:55:30 +0100
committerDamjan Marion <dmarion.lists@gmail.com>2017-02-16 19:33:28 +0000
commit83ed1f4f1bc3f09de0e7ca1e163bf1d7dd4b8be2 (patch)
tree2e04d0efe50b6fbd41708a631fddc2c51d6eb5d5 /src/vppinfra
parentb69111e167f5be70b3721ed5c2e5e02b971c3f67 (diff)
tw_timer_expire_timers() - add a maximum to the number of expiration per call
The idea is to prevent a huge processing burst if, say, the network goes down 10' for some reason, and so that we don't need to expire 1M timer sessions on the first call. The maximum is not an exact value, but a value after which the expiration process is postponed until the next call. That way, we don't have to process the same tick twice, nor to unlink timers once at a time when processing a tick. The fact that a timer slot could contain many entries should be dealt with by changing the number of ticks per second. Change-Id: I892d07f965094102a3d53e7dbf4e6f5ad22d4967 Signed-off-by: Gabriel Ganne <gabriel.ganne@enea.com>
Diffstat (limited to 'src/vppinfra')
-rw-r--r--src/vppinfra/tw_timer_template.c8
-rw-r--r--src/vppinfra/tw_timer_template.h5
2 files changed, 10 insertions, 3 deletions
diff --git a/src/vppinfra/tw_timer_template.c b/src/vppinfra/tw_timer_template.c
index 139d27ca09f..436dd4e1f66 100644
--- a/src/vppinfra/tw_timer_template.c
+++ b/src/vppinfra/tw_timer_template.c
@@ -170,13 +170,14 @@ void TW (tw_timer_stop) (TWT (tw_timer_wheel) * tw, u32 handle)
void
TW (tw_timer_wheel_init) (TWT (tw_timer_wheel) * tw,
void *expired_timer_callback,
- f64 timer_interval_in_seconds)
+ f64 timer_interval_in_seconds, u32 max_expirations)
{
int ring, slot;
tw_timer_wheel_slot_t *ts;
TWT (tw_timer) * t;
memset (tw, 0, sizeof (*tw));
tw->expired_timer_callback = expired_timer_callback;
+ tw->max_expirations = max_expirations;
if (timer_interval_in_seconds == 0.0)
{
clib_warning ("timer interval is zero");
@@ -258,7 +259,6 @@ u32 TW (tw_timer_expire_timers) (TWT (tw_timer_wheel) * tw, f64 now)
/* Remember when we ran, compute next runtime */
tw->next_run_time = (now + tw->timer_interval);
- tw->last_run_time = now;
total_nexpirations = 0;
for (i = 0; i < nticks; i++)
@@ -332,8 +332,12 @@ u32 TW (tw_timer_expire_timers) (TWT (tw_timer_wheel) * tw, f64 now)
}
tw->current_index[TW_TIMER_RING_FAST]++;
tw->current_tick++;
+
+ if (total_nexpirations >= tw->max_expirations)
+ break;
}
+ tw->last_run_time += i * tw->ticks_per_second;
return total_nexpirations;
}
diff --git a/src/vppinfra/tw_timer_template.h b/src/vppinfra/tw_timer_template.h
index 2e41bcac5f8..6b61e424f69 100644
--- a/src/vppinfra/tw_timer_template.h
+++ b/src/vppinfra/tw_timer_template.h
@@ -175,6 +175,9 @@ typedef struct
/** vector of expired timers */
u32 *expired_timer_handles;
+
+ /** maximum expirations */
+ u32 max_expirations;
} TWT (tw_timer_wheel);
u32 TW (tw_timer_start) (TWT (tw_timer_wheel) * tw,
@@ -184,7 +187,7 @@ void TW (tw_timer_stop) (TWT (tw_timer_wheel) * tw, u32 handle);
void TW (tw_timer_wheel_init) (TWT (tw_timer_wheel) * tw,
void *expired_timer_callback,
- f64 timer_interval);
+ f64 timer_interval, u32 max_expirations);
void TW (tw_timer_wheel_free) (TWT (tw_timer_wheel) * tw);