/* *------------------------------------------------------------------ * spp_timers.h * * Copyright (c) 2008-2009 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *------------------------------------------------------------------ */ #ifndef __SPP_TIMERS_H__ #define __SPP_TIMERS_H__ typedef struct d_list_el_ { struct d_list_el_ *next; struct d_list_el_ *prev; } d_list_el_t; /* * d_list_init */ static inline void d_list_init (d_list_el_t *headp) { headp->prev = headp->next = headp; } /* * d_list_init - add at head of list */ static inline void d_list_add_head (d_list_el_t *headp, d_list_el_t *elp) { ASSERT(elp->prev == elp); /* multiple enqueue, BAD! */ ASSERT(elp->next == elp); elp->next = headp->next; headp->next = elp; elp->prev = elp->next->prev; elp->next->prev = elp; } /* * d_list_add_tail - add element at tail of list */ static inline void d_list_add_tail (d_list_el_t *headp, d_list_el_t *elp) { ASSERT(elp->prev == elp); /* multiple enqueue, BAD! */ ASSERT(elp->next == elp); headp = headp->prev; elp->next = headp->next; headp->next = elp; elp->prev = elp->next->prev; elp->next->prev = elp; } /* * d_list_rem_head - removes first element from list */ static inline d_list_el_t *d_list_rem_head (d_list_el_t *headp) { d_list_el_t *elp; elp = headp->next; if (elp == headp) return (NULL); headp->next = elp->next; elp->next->prev = elp->prev; elp->next = elp->prev = elp; return (elp); } /* * d_list_rem_elem - removes specific element from list. */ static inline void d_list_rem_elem (d_list_el_t *elp) { d_list_el_t *headp; headp = elp->prev; headp->next = elp->next; elp->next->prev = elp->prev; elp->next = elp->prev = elp; } #define TIMER_BKTS_PER_WHEEL 128 /* power of 2, please */ #define TIMER_NWHEELS 4 typedef struct { i32 curindex; /* current index for this wheel */ d_list_el_t *bkts; /* vector of bucket listheads */ } spp_timer_wheel_t; typedef struct { u64 next_run_ticks; /* Next time we expire timers */ spp_timer_wheel_t **wheels; /* pointers to wheels */ } spp_timer_axle_t; typedef struct { d_list_el_t el; u16 cb_index; u16 flags; u64 expires; } spp_timer_t; #define SPP_TIMER_RUNNING 0x0001 /* * prototypes */ void spp_timer_set_ticks_per_ms(u64); void spp_timer_axle_init (spp_timer_axle_t *ta); void spp_timer_expire(spp_timer_axle_t *ta, u64 now); void spp_timer_final_init(void); void spp_timer_start(spp_timer_t *tp); void spp_timer_start_axle(spp_timer_axle_t *ta, spp_timer_t *tp); void spp_timer_stop(spp_timer_t *tp); u16 spp_timer_register_callback (void (*fp)(spp_timer_t *)); #endif /* __SPP_TIMERS_H__ */