38 TWT (tw_timer) * old_first;
46 head->next = head->prev = new_index;
47 new->next =
new->prev = head_index;
51 old_first_index = head->next;
54 new->next = old_first_index;
55 new->prev = old_first->prev;
56 old_first->prev = new_index;
57 head->next = new_index;
64 TWT (tw_timer) * next_elt, *prev_elt;
66 ASSERT (elt->user_handle != ~0);
71 next_elt->prev = elt->prev;
72 prev_elt->next = elt->next;
74 elt->prev = elt->next = ~0;
89 #if TW_TIMER_WHEELS > 1 100 t->next = t->prev = ~0;
101 #if TW_TIMER_WHEELS > 1 102 t->fast_ring_offset = ~0;
108 #if TW_TIMER_WHEELS > 1 117 if (slow_ring_offset)
123 t->fast_ring_offset = fast_ring_offset;
130 return t - tw->timers;
141 return t - tw->timers;
156 ASSERT (t->user_handle != ~0);
172 void *expired_timer_callback,
173 f64 timer_interval_in_seconds,
u32 max_expirations)
178 memset (tw, 0,
sizeof (*tw));
179 tw->expired_timer_callback = expired_timer_callback;
180 tw->max_expirations = max_expirations;
181 if (timer_interval_in_seconds == 0.0)
186 tw->timer_interval = timer_interval_in_seconds;
187 tw->ticks_per_second = 1.0 / timer_interval_in_seconds;
193 ts = &tw->w[ring][slot];
195 memset (t, 0xff,
sizeof (*t));
196 t->next = t->prev = t - tw->timers;
210 TWT (tw_timer) * head, *t;
219 next_index = head->next;
224 next_index = t->next;
230 memset (tw, 0,
sizeof (*tw));
243 TWT (tw_timer) * t, *head;
244 u32 fast_wheel_index;
246 u32 nexpirations, total_nexpirations;
247 #if TW_TIMER_WHEELS > 1 248 u32 slow_wheel_index;
256 nticks = tw->ticks_per_second * (now - tw->last_run_time);
261 tw->next_run_time = (now + tw->timer_interval);
263 total_nexpirations = 0;
264 for (i = 0; i < nticks; i++)
277 #if TW_TIMER_WHEELS > 1 285 next_index = head->next;
291 while (next_index != head - tw->timers)
294 next_index = t->next;
297 t->next = t->prev = ~0;
312 next_index = head->next;
321 next_index = t->next;
322 vec_add1 (tw->expired_timer_handles, t->user_handle);
327 nexpirations =
vec_len (tw->expired_timer_handles);
330 tw->expired_timer_callback (tw->expired_timer_handles);
331 total_nexpirations += nexpirations;
336 if (total_nexpirations >= tw->max_expirations)
340 tw->last_run_time += i * tw->timer_interval;
341 return total_nexpirations;
void TW() tw_timer_wheel_init(TWT(tw_timer_wheel)*tw, void *expired_timer_callback, f64 timer_interval_in_seconds, u32 max_expirations)
Initialize a tw timer wheel template instance.
sll srl srl sll sra u16x4 i
#define TW_TIMERS_PER_OBJECT
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
#define LOG2_TW_TIMERS_PER_OBJECT
static void timer_addhead(TWT(tw_timer)*pool, u32 head_index, u32 new_index)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
#define TW_SLOTS_PER_RING
#define pool_put(P, E)
Free an object E in pool P.
u32 TW() tw_timer_start(TWT(tw_timer_wheel)*tw, u32 pool_index, u32 timer_id, u32 interval)
Start a Tw Timer.
u32 TW() tw_timer_expire_timers(TWT(tw_timer_wheel)*tw, f64 now)
Advance a tw timer wheel.
#define clib_warning(format, args...)
void TW() tw_timer_stop(TWT(tw_timer_wheel)*tw, u32 handle)
Stop a tw timer.
static void timer_remove(TWT(tw_timer)*pool, u32 index)
#define pool_put_index(p, i)
Free pool element with given index.
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static u32 TW() make_internal_timer_handle(u32 pool_index, u32 timer_id)
void TW() tw_timer_wheel_free(TWT(tw_timer_wheel)*tw)
Free a tw timer wheel template instance.
u32 head_index
Listhead of timers which expire in this interval.