#include <vppinfra/clib.h>
#include <vppinfra/pool.h>
+#include <vppinfra/bitmap.h>
#ifndef _twt
#define _twt(a,b) a##b##_t
}
*/
+#if (TW_TIMER_WHEELS != 1 && TW_TIMER_WHEELS != 2 && TW_TIMER_WHEELS != 3)
+#error TW_TIMER_WHEELS must be 1, 2 or 3
+#endif
+
typedef struct
{
/** next, previous pool indices */
u32 next;
u32 prev;
-#if TW_TIMER_WHEELS > 0
- /** fast ring offset, only valid in the slow ring */
- u16 fast_ring_offset;
- u16 pad;
+
+ union
+ {
+ struct
+ {
+#if (TW_TIMER_WHEELS == 3)
+ /** fast ring offset, only valid in the slow ring */
+ u16 fast_ring_offset;
+ /** slow ring offset, only valid in the glacier ring */
+ u16 slow_ring_offset;
+#endif
+#if (TW_TIMER_WHEELS == 2)
+ /** fast ring offset, only valid in the slow ring */
+ u16 fast_ring_offset;
+ /** slow ring offset, only valid in the glacier ring */
+ u16 pad;
#endif
+ };
+
+#if (TW_OVERFLOW_VECTOR > 0)
+ u64 expiration_time;
+#endif
+ };
+
/** user timer handle */
u32 user_handle;
} TWT (tw_timer);
TW_TIMER_RING_FAST,
/** Slow timer ring ID */
TW_TIMER_RING_SLOW,
+ /** Glacier ring ID */
+ TW_TIMER_RING_GLACIER,
} tw_ring_index_t;
#endif /* __defined_tw_timer_wheel_slot__ */
+typedef CLIB_PACKED (struct
+ {
+ u8 timer_id;
+ u32 pool_index;
+ u32 handle;
+ }) TWT (trace);
+
typedef struct
{
/** Timer pool */
f64 timer_interval;
/** current tick */
- u32 current_tick;
+ u64 current_tick;
/** current wheel indices */
u32 current_index[TW_TIMER_WHEELS];
/** wheel arrays */
tw_timer_wheel_slot_t w[TW_TIMER_WHEELS][TW_SLOTS_PER_RING];
+#if TW_OVERFLOW_VECTOR > 0
+ 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);
- /** vector of expired timers */
+ /** vectors of expired timers */
u32 *expired_timer_handles;
/** maximum expirations */
u32 max_expirations;
+
+ /** current trace index */
+#if TW_START_STOP_TRACE_SIZE > 0
+ /* Start/stop/expire tracing */
+ u32 trace_index;
+ u32 trace_wrapped;
+ TWT (trace) traces[TW_START_STOP_TRACE_SIZE];
+#endif
+
} TWT (tw_timer_wheel);
u32 TW (tw_timer_start) (TWT (tw_timer_wheel) * tw,
- u32 pool_index, u32 timer_id, u32 interval);
+ u32 pool_index, u32 timer_id, u64 interval);
void TW (tw_timer_stop) (TWT (tw_timer_wheel) * tw, u32 handle);
+int TW (tw_timer_handle_is_free) (TWT (tw_timer_wheel) * tw, u32 handle);
+void TW (tw_timer_update) (TWT (tw_timer_wheel) * tw, u32 handle,
+ u64 interval);
void TW (tw_timer_wheel_init) (TWT (tw_timer_wheel) * tw,
void *expired_timer_callback,
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) (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
+
+#if TW_START_STOP_TRACE_SIZE > 0
+void TW (tw_search_trace) (TWT (tw_timer_wheel) * tw, u32 handle);
+void TW (tw_timer_trace) (TWT (tw_timer_wheel) * tw, u32 timer_id,
+ u32 pool_index, u32 handle);
+#endif
/*
* fd.io coding-style-patch-verification: ON