aboutsummaryrefslogtreecommitdiffstats
path: root/src/vppinfra
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2017-06-13 08:48:31 -0400
committerDave Barach <openvpp@barachs.net>2017-06-28 19:12:10 +0000
commit5c20a0131a6a2516c14d5ccfc6db90fd13ec8a33 (patch)
tree0e175b7e6be5ae87e2a35534b94eec35c5328986 /src/vppinfra
parent31a71ab497616940c105fa1719515fe7ae37f37a (diff)
switch vlib process model to tw_timer_template timer impl
Change-Id: I36bb47faea55a6fea7af7ee58d87d8f6dd28f93d Signed-off-by: Dave Barach <dave@barachs.net>
Diffstat (limited to 'src/vppinfra')
-rw-r--r--src/vppinfra/tw_timer_16t_1w_2048sl.h4
-rw-r--r--src/vppinfra/tw_timer_16t_2w_512sl.h4
-rw-r--r--src/vppinfra/tw_timer_1t_3w_1024sl_ov.h4
-rw-r--r--src/vppinfra/tw_timer_2t_1w_2048sl.h4
-rw-r--r--src/vppinfra/tw_timer_4t_3w_256sl.h4
-rw-r--r--src/vppinfra/tw_timer_4t_3w_4sl_ov.h4
-rw-r--r--src/vppinfra/tw_timer_template.c74
-rw-r--r--src/vppinfra/tw_timer_template.h9
8 files changed, 107 insertions, 0 deletions
diff --git a/src/vppinfra/tw_timer_16t_1w_2048sl.h b/src/vppinfra/tw_timer_16t_1w_2048sl.h
index 6edef17bf60..66cf7d37b68 100644
--- a/src/vppinfra/tw_timer_16t_1w_2048sl.h
+++ b/src/vppinfra/tw_timer_16t_1w_2048sl.h
@@ -25,6 +25,8 @@
#undef LOG2_TW_TIMERS_PER_OBJECT
#undef TW_SUFFIX
#undef TW_OVERFLOW_VECTOR
+#undef TW_FAST_WHEEL_BITMAP
+#undef TW_TIMER_ALLOW_DUPLICATE_STOP
#define TW_TIMER_WHEELS 1
#define TW_SLOTS_PER_RING 2048
@@ -33,6 +35,8 @@
#define TW_TIMERS_PER_OBJECT 16
#define LOG2_TW_TIMERS_PER_OBJECT 4
#define TW_SUFFIX _16t_1w_2048sl
+#define TW_FAST_WHEEL_BITMAP 0
+#define TW_TIMER_ALLOW_DUPLICATE_STOP 0
#include <vppinfra/tw_timer_template.h>
diff --git a/src/vppinfra/tw_timer_16t_2w_512sl.h b/src/vppinfra/tw_timer_16t_2w_512sl.h
index 2497b31c1ad..00587b8eeda 100644
--- a/src/vppinfra/tw_timer_16t_2w_512sl.h
+++ b/src/vppinfra/tw_timer_16t_2w_512sl.h
@@ -25,6 +25,8 @@
#undef LOG2_TW_TIMERS_PER_OBJECT
#undef TW_SUFFIX
#undef TW_OVERFLOW_VECTOR
+#undef TW_FAST_WHEEL_BITMAP
+#undef TW_TIMER_ALLOW_DUPLICATE_STOP
#define TW_TIMER_WHEELS 2
#define TW_SLOTS_PER_RING 512
@@ -33,6 +35,8 @@
#define TW_TIMERS_PER_OBJECT 16
#define LOG2_TW_TIMERS_PER_OBJECT 4
#define TW_SUFFIX _16t_2w_512sl
+#define TW_FAST_WHEEL_BITMAP 0
+#define TW_TIMER_ALLOW_DUPLICATE_STOP 0
#include <vppinfra/tw_timer_template.h>
diff --git a/src/vppinfra/tw_timer_1t_3w_1024sl_ov.h b/src/vppinfra/tw_timer_1t_3w_1024sl_ov.h
index 7327f87b900..e5e4cc19a90 100644
--- a/src/vppinfra/tw_timer_1t_3w_1024sl_ov.h
+++ b/src/vppinfra/tw_timer_1t_3w_1024sl_ov.h
@@ -25,6 +25,8 @@
#undef LOG2_TW_TIMERS_PER_OBJECT
#undef TW_SUFFIX
#undef TW_OVERFLOW_VECTOR
+#undef TW_FAST_WHEEL_BITMAP
+#undef TW_TIMER_ALLOW_DUPLICATE_STOP
#define TW_TIMER_WHEELS 3
#define TW_SLOTS_PER_RING 1024
@@ -34,6 +36,8 @@
#define LOG2_TW_TIMERS_PER_OBJECT 0
#define TW_SUFFIX _1t_3w_1024sl_ov
#define TW_OVERFLOW_VECTOR 1
+#define TW_FAST_WHEEL_BITMAP 1
+#define TW_TIMER_ALLOW_DUPLICATE_STOP 1
#include <vppinfra/tw_timer_template.h>
diff --git a/src/vppinfra/tw_timer_2t_1w_2048sl.h b/src/vppinfra/tw_timer_2t_1w_2048sl.h
index 33b74405fcc..98b548b39d4 100644
--- a/src/vppinfra/tw_timer_2t_1w_2048sl.h
+++ b/src/vppinfra/tw_timer_2t_1w_2048sl.h
@@ -25,6 +25,8 @@
#undef LOG2_TW_TIMERS_PER_OBJECT
#undef TW_SUFFIX
#undef TW_OVERFLOW_VECTOR
+#undef TW_FAST_WHEEL_BITMAP
+#undef TW_TIMER_ALLOW_DUPLICATE_STOP
#define TW_TIMER_WHEELS 1
#define TW_SLOTS_PER_RING 2048
@@ -33,6 +35,8 @@
#define TW_TIMERS_PER_OBJECT 2
#define LOG2_TW_TIMERS_PER_OBJECT 1
#define TW_SUFFIX _2t_1w_2048sl
+#define TW_FAST_WHEEL_BITMAP 0
+#define TW_TIMER_ALLOW_DUPLICATE_STOP 0
#include <vppinfra/tw_timer_template.h>
diff --git a/src/vppinfra/tw_timer_4t_3w_256sl.h b/src/vppinfra/tw_timer_4t_3w_256sl.h
index 89adb7a2464..07203de8742 100644
--- a/src/vppinfra/tw_timer_4t_3w_256sl.h
+++ b/src/vppinfra/tw_timer_4t_3w_256sl.h
@@ -25,6 +25,8 @@
#undef LOG2_TW_TIMERS_PER_OBJECT
#undef TW_SUFFIX
#undef TW_OVERFLOW_VECTOR
+#undef TW_FAST_WHEEL_BITMAP
+#undef TW_TIMER_ALLOW_DUPLICATE_STOP
#define TW_TIMER_WHEELS 3
#define TW_SLOTS_PER_RING 256
@@ -33,6 +35,8 @@
#define TW_TIMERS_PER_OBJECT 4
#define LOG2_TW_TIMERS_PER_OBJECT 2
#define TW_SUFFIX _4t_3w_256sl
+#define TW_FAST_WHEEL_BITMAP 0
+#define TW_TIMER_ALLOW_DUPLICATE_STOP 0
#include <vppinfra/tw_timer_template.h>
diff --git a/src/vppinfra/tw_timer_4t_3w_4sl_ov.h b/src/vppinfra/tw_timer_4t_3w_4sl_ov.h
index 0f76164d069..20a01d05e7d 100644
--- a/src/vppinfra/tw_timer_4t_3w_4sl_ov.h
+++ b/src/vppinfra/tw_timer_4t_3w_4sl_ov.h
@@ -25,6 +25,8 @@
#undef LOG2_TW_TIMERS_PER_OBJECT
#undef TW_SUFFIX
#undef TW_OVERFLOW_VECTOR
+#undef TW_FAST_WHEEL_BITMAP
+#undef TW_TIMER_ALLOW_DUPLICATE_STOP
#define TW_TIMER_WHEELS 3
#define TW_SLOTS_PER_RING 4
@@ -34,6 +36,8 @@
#define LOG2_TW_TIMERS_PER_OBJECT 2
#define TW_SUFFIX _4t_3w_4sl_ov
#define TW_OVERFLOW_VECTOR 1
+#define TW_FAST_WHEEL_BITMAP 0
+#define TW_TIMER_ALLOW_DUPLICATE_STOP 0
#include <vppinfra/tw_timer_template.h>
diff --git a/src/vppinfra/tw_timer_template.c b/src/vppinfra/tw_timer_template.c
index 9253488ceac..c0a9685aa82 100644
--- a/src/vppinfra/tw_timer_template.c
+++ b/src/vppinfra/tw_timer_template.c
@@ -204,6 +204,11 @@ TW (tw_timer_start) (TWT (tw_timer_wheel) * tw, u32 pool_index, u32 timer_id,
ts = &tw->w[TW_TIMER_RING_FAST][fast_ring_offset];
timer_addhead (tw->timers, ts->head_index, t - tw->timers);
+
+#if TW_FAST_WHEEL_BITMAP
+ tw->fast_slot_bitmap = clib_bitmap_set (tw->fast_slot_bitmap,
+ fast_ring_offset, 1);
+#endif
return t - tw->timers;
}
@@ -251,6 +256,16 @@ void TW (tw_timer_stop) (TWT (tw_timer_wheel) * tw, u32 handle)
{
TWT (tw_timer) * t;
+#if TW_TIMER_ALLOW_DUPLICATE_STOP
+ /*
+ * A vlib process may have its timer expire, and receive
+ * an event before the expiration is processed.
+ * That results in a duplicate tw_timer_stop.
+ */
+ if (pool_is_free_index (tw->timers, handle))
+ return;
+#endif
+
t = pool_elt_at_index (tw->timers, handle);
/* in case of idiotic handle (e.g. passing a listhead index) */
@@ -481,6 +496,11 @@ static inline
{
ts = &tw->w[TW_TIMER_RING_FAST][t->fast_ring_offset];
timer_addhead (tw->timers, ts->head_index, t - tw->timers);
+#if TW_FAST_WHEEL_BITMAP
+ tw->fast_slot_bitmap =
+ clib_bitmap_set (tw->fast_slot_bitmap,
+ t->fast_ring_offset, 1);
+#endif
}
}
}
@@ -523,6 +543,11 @@ static inline
{
ts = &tw->w[TW_TIMER_RING_FAST][t->fast_ring_offset];
timer_addhead (tw->timers, ts->head_index, t - tw->timers);
+#if TW_FAST_WHEEL_BITMAP
+ tw->fast_slot_bitmap =
+ clib_bitmap_set (tw->fast_slot_bitmap,
+ t->fast_ring_offset, 1);
+#endif
}
else /* typical case */
{
@@ -569,6 +594,11 @@ static inline
/* Add to fast ring */
ts = &tw->w[TW_TIMER_RING_FAST][t->fast_ring_offset];
timer_addhead (tw->timers, ts->head_index, t - tw->timers);
+#if TW_FAST_WHEEL_BITMAP
+ tw->fast_slot_bitmap =
+ clib_bitmap_set (tw->fast_slot_bitmap,
+ t->fast_ring_offset, 1);
+#endif
}
}
}
@@ -604,6 +634,12 @@ static inline
}
tw->expired_timer_handles = callback_vector;
}
+
+#if TW_FAST_WHEEL_BITMAP
+ tw->fast_slot_bitmap = clib_bitmap_set (tw->fast_slot_bitmap,
+ fast_wheel_index, 0);
+#endif
+
tw->current_tick++;
fast_wheel_index++;
tw->current_index[TW_TIMER_RING_FAST] = fast_wheel_index;
@@ -642,6 +678,44 @@ u32 *TW (tw_timer_expire_timers_vec) (TWT (tw_timer_wheel) * tw, f64 now,
return TW (tw_timer_expire_timers_internal) (tw, now, vec);
}
+#if TW_FAST_WHEEL_BITMAP
+/** Returns an approximation to the first timer expiration in
+ * timer-ticks from "now". To avoid wasting an unjustifiable
+ * amount of time on the problem, we maintain an approximate fast-wheel slot
+ * occupancy bitmap. We don't worry about clearing fast wheel bits
+ * when timers are removed from fast wheel slots.
+ */
+
+u32 TW (tw_timer_first_expires_in_ticks) (TWT (tw_timer_wheel) * tw)
+{
+ u32 first_expiring_index, fast_ring_index;
+ i32 delta;
+
+ if (clib_bitmap_is_zero (tw->fast_slot_bitmap))
+ return TW_SLOTS_PER_RING;
+
+ fast_ring_index = tw->current_index[TW_TIMER_RING_FAST];
+ if (fast_ring_index == TW_SLOTS_PER_RING)
+ fast_ring_index = 0;
+
+ first_expiring_index = clib_bitmap_next_set (tw->fast_slot_bitmap,
+ fast_ring_index);
+ if (first_expiring_index == ~0 && fast_ring_index != 0)
+ first_expiring_index = clib_bitmap_first_set (tw->fast_slot_bitmap);
+
+ ASSERT (first_expiring_index != ~0);
+
+ delta = (i32) first_expiring_index - (i32) fast_ring_index;
+ if (delta < 0)
+ delta += TW_SLOTS_PER_RING;
+
+ ASSERT (delta >= 0);
+
+ return (u32) delta;
+}
+
+#endif
+
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/src/vppinfra/tw_timer_template.h b/src/vppinfra/tw_timer_template.h
index 76755609451..0404e3f4715 100644
--- a/src/vppinfra/tw_timer_template.h
+++ b/src/vppinfra/tw_timer_template.h
@@ -19,6 +19,7 @@
#include <vppinfra/clib.h>
#include <vppinfra/pool.h>
+#include <vppinfra/bitmap.h>
#ifndef _twt
#define _twt(a,b) a##b##_t
@@ -202,6 +203,11 @@ typedef struct
tw_timer_wheel_slot_t overflow;
#endif
+#if TW_FAST_WHEEL_BITMAP > 0
+ /** Fast wheel slot occupancy bitmap */
+ uword *fast_slot_bitmap;
+#endif
+
/** expired timer callback, receives a vector of handles */
void (*expired_timer_callback) (u32 * expired_timer_handles);
@@ -226,6 +232,9 @@ void TW (tw_timer_wheel_free) (TWT (tw_timer_wheel) * tw);
u32 *TW (tw_timer_expire_timers) (TWT (tw_timer_wheel) * tw, f64 now);
u32 *TW (tw_timer_expire_timers_vec) (TWT (tw_timer_wheel) * tw, f64 now,
u32 * vec);
+#if TW_FAST_WHEEL_BITMAP
+u32 TW (tw_timer_first_expires_in_ticks) (TWT (tw_timer_wheel) * tw);
+#endif
/*
* fd.io coding-style-patch-verification: ON