21 #if TW_START_STOP_TRACE_SIZE > 0
23 void TW (tw_timer_trace) (
TWT (tw_timer_wheel) * tw,
u32 timer_id,
24 u32 pool_index,
u32 handle)
26 TWT (
trace) * t = &tw->traces[tw->trace_index];
28 t->timer_id = timer_id;
29 t->pool_index = pool_index;
33 if (tw->trace_index == TW_START_STOP_TRACE_SIZE)
40 void TW (tw_search_trace) (
TWT (tw_timer_wheel) * tw,
u32 handle)
48 start_pos = tw->trace_index;
50 start_pos = TW_START_STOP_TRACE_SIZE - 1;
54 for (
i = start_pos;
i > 0;
i--)
57 if (t->handle == handle)
71 fformat (stderr,
"handle 0x%x (%d) %s at trace %d\n",
72 handle, handle, s,
i);
75 if (tw->trace_wrapped > 0)
77 for (
i = TW_START_STOP_TRACE_SIZE;
i >= tw->trace_index;
i--)
80 if (t->handle == handle)
94 fformat (stderr,
"handle 0x%x (%d) %s at trace %d\n",
95 handle, handle, s,
i);
108 #if LOG2_TW_TIMERS_PER_OBJECT > 0
122 TWT (tw_timer) * old_first;
124 TWT (tw_timer) *
new;
130 head->next = head->prev = new_index;
131 new->next =
new->prev = head_index;
135 old_first_index = head->next;
138 new->next = old_first_index;
139 new->prev = old_first->prev;
140 old_first->prev = new_index;
141 head->next = new_index;
147 TWT (tw_timer) * next_elt, *prev_elt;
163 #if TW_TIMER_WHEELS > 1
164 u16 slow_ring_offset;
167 #if TW_TIMER_WHEELS > 2
168 u16 glacier_ring_offset;
170 #if TW_OVERFLOW_VECTOR > 0
171 u64 interval_plus_time_to_wrap, triple_wrap_mask;
173 u16 fast_ring_offset;
177 #if TW_TIMER_WHEELS > 2
178 #if TW_OVERFLOW_VECTOR > 0
186 interval_plus_time_to_wrap =
187 interval + (tw->current_tick & triple_wrap_mask);
188 if ((interval_plus_time_to_wrap >= 1 << (3 *
TW_RING_SHIFT)))
190 t->expiration_time = tw->current_tick +
interval;
193 #if TW_START_STOP_TRACE_SIZE > 0
194 TW (tw_timer_trace) (tw, timer_id, user_id, t - tw->timers);
204 #if TW_TIMER_WHEELS > 1
220 #if TW_TIMER_WHEELS > 1
229 #if TW_TIMER_WHEELS > 2
230 glacier_ring_offset +=
235 #if TW_TIMER_WHEELS > 2
236 if (glacier_ring_offset !=
240 t->slow_ring_offset = slow_ring_offset;
241 t->fast_ring_offset = fast_ring_offset;
246 #if TW_START_STOP_TRACE_SIZE > 0
247 TW (tw_timer_trace) (tw, timer_id, user_id, t - tw->timers);
253 #if TW_TIMER_WHEELS > 1
255 if (slow_ring_offset !=
259 t->fast_ring_offset = fast_ring_offset;
264 #if TW_START_STOP_TRACE_SIZE > 0
265 TW (tw_timer_trace) (tw, timer_id, user_id, t - tw->timers);
278 #if TW_FAST_WHEEL_BITMAP
280 fast_ring_offset, 1);
282 #if TW_START_STOP_TRACE_SIZE > 0
283 TW (tw_timer_trace) (tw, timer_id, user_id, t - tw->timers);
309 return t - tw->timers;
312 #if TW_TIMER_SCAN_FOR_HANDLE > 0
313 int TW (scan_for_handle) (
TWT (tw_timer_wheel) * tw,
u32 handle)
317 TWT (tw_timer) * t, *head;
356 #if TW_TIMER_ALLOW_DUPLICATE_STOP
365 #if TW_START_STOP_TRACE_SIZE > 0
366 TW (tw_timer_trace) (tw, ~0, ~0, handle);
372 ASSERT (t->user_handle != ~0);
410 f64 timer_interval_in_seconds,
u32 max_expirations)
417 tw->max_expirations = max_expirations;
418 if (timer_interval_in_seconds == 0.0)
423 tw->timer_interval = timer_interval_in_seconds;
424 tw->ticks_per_second = 1.0 / timer_interval_in_seconds;
427 _vec_len (tw->expired_timer_handles) = 0;
433 ts = &tw->w[ring][
slot];
436 t->next = t->prev = t - tw->timers;
441 #if TW_OVERFLOW_VECTOR > 0
445 t->next = t->prev = t - tw->timers;
458 TWT (tw_timer) * head, *t;
479 #if TW_OVERFLOW_VECTOR > 0
506 u32 * callback_vector_arg)
510 TWT (tw_timer) * t, *head;
511 u32 *callback_vector;
512 u32 fast_wheel_index;
514 u32 slow_wheel_index __attribute__ ((unused));
515 u32 glacier_wheel_index __attribute__ ((unused));
519 return callback_vector_arg;
522 nticks = tw->ticks_per_second * (
now - tw->last_run_time);
524 return callback_vector_arg;
527 tw->next_run_time = (
now + tw->timer_interval);
531 ((tw->last_run_time == 0.0) || (
now <= tw->last_run_time)))
533 tw->last_run_time =
now;
534 return callback_vector_arg;
537 if (callback_vector_arg == 0)
539 _vec_len (tw->expired_timer_handles) = 0;
540 callback_vector = tw->expired_timer_handles;
543 callback_vector = callback_vector_arg;
545 for (
i = 0;
i < nticks;
i++)
553 #if TW_OVERFLOW_VECTOR > 0
560 u32 new_glacier_ring_offset, new_slow_ring_offset;
561 u32 new_fast_ring_offset;
577 t->next = t->prev = ~0;
579 ASSERT (t->expiration_time >= tw->current_tick);
581 interval = t->expiration_time - tw->current_tick;
599 t->slow_ring_offset = new_slow_ring_offset;
600 t->fast_ring_offset = new_fast_ring_offset;
604 t->fast_ring_offset == 0 &&
605 new_glacier_ring_offset == 0))
607 vec_add1 (callback_vector, t->user_handle);
608 #if TW_START_STOP_TRACE_SIZE > 0
609 TW (tw_timer_trace) (tw, 0xfe, t->user_handle,
615 else if (new_glacier_ring_offset)
621 else if (t->slow_ring_offset)
632 #if TW_FAST_WHEEL_BITMAP
633 tw->fast_slot_bitmap =
635 t->fast_ring_offset, 1);
642 #if TW_TIMER_WHEELS > 2
665 t->next = t->prev = ~0;
669 t->fast_ring_offset == 0))
671 vec_add1 (callback_vector, t->user_handle);
672 #if TW_START_STOP_TRACE_SIZE > 0
673 TW (tw_timer_trace) (tw, 0xfe, t->user_handle,
683 #if TW_FAST_WHEEL_BITMAP
684 tw->fast_slot_bitmap =
686 t->fast_ring_offset, 1);
699 #if TW_TIMER_WHEELS > 1
721 t->next = t->prev = ~0;
726 vec_add1 (callback_vector, t->user_handle);
727 #if TW_START_STOP_TRACE_SIZE > 0
728 TW (tw_timer_trace) (tw, 0xfe, t->user_handle,
738 #if TW_FAST_WHEEL_BITMAP
739 tw->fast_slot_bitmap =
741 t->fast_ring_offset, 1);
763 vec_add1 (callback_vector, t->user_handle);
764 #if TW_START_STOP_TRACE_SIZE > 0
765 TW (tw_timer_trace) (tw, 0xfe, t->user_handle, t - tw->timers);
771 if (callback_vector_arg == 0 &&
vec_len (callback_vector))
774 if (tw->expired_timer_callback)
776 tw->expired_timer_callback (callback_vector);
779 tw->expired_timer_handles = callback_vector;
782 #if TW_FAST_WHEEL_BITMAP
784 fast_wheel_index, 0);
791 #if TW_TIMER_WHEELS > 1
797 #if TW_TIMER_WHEELS > 2
799 glacier_wheel_index++;
803 if (
vec_len (callback_vector) >= tw->max_expirations)
807 if (callback_vector_arg == 0)
808 tw->expired_timer_handles = callback_vector;
810 tw->last_run_time +=
i * tw->timer_interval;
811 return callback_vector;
826 #if TW_FAST_WHEEL_BITMAP
835 TW (tw_timer_first_expires_in_ticks) (
TWT (tw_timer_wheel) * tw)
837 u32 first_expiring_index, fast_ring_index;
840 #if TW_TIMER_WHEELS > 1
845 first_expiring_index = clib_bitmap_next_set (tw->fast_slot_bitmap,
847 if (first_expiring_index == ~0)
859 first_expiring_index = clib_bitmap_next_set (tw->fast_slot_bitmap,
861 if (first_expiring_index == ~0 && fast_ring_index != 0)
865 ASSERT (first_expiring_index != ~0);
867 delta = (
i32) first_expiring_index - (
i32) fast_ring_index;