Initial commit of vpp code.
[vpp.git] / vnet / vnet / vcgn / spp_timers.h
1 /* 
2  *------------------------------------------------------------------
3  * spp_timers.h
4  *
5  * Copyright (c) 2008-2009 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19 #ifndef __SPP_TIMERS_H__
20 #define __SPP_TIMERS_H__
21
22
23 typedef struct d_list_el_ {
24     struct d_list_el_ *next;
25     struct d_list_el_ *prev;
26 } d_list_el_t;
27
28 /*
29  * d_list_init
30  */
31
32 static inline void d_list_init (d_list_el_t *headp)
33 {
34     headp->prev = headp->next = headp;
35 }
36
37 /*
38  * d_list_init - add at head of list
39  */
40
41 static inline void d_list_add_head (d_list_el_t *headp, 
42                                                   d_list_el_t *elp)
43 {
44     ASSERT(elp->prev == elp);     /* multiple enqueue, BAD! */
45     ASSERT(elp->next == elp);
46
47     elp->next = headp->next;
48     headp->next = elp;
49     elp->prev = elp->next->prev;
50     elp->next->prev = elp;
51 }
52
53 /*
54  * d_list_add_tail - add element at tail of list
55  */
56 static inline void d_list_add_tail (d_list_el_t *headp, 
57                                                   d_list_el_t *elp)
58 {
59     ASSERT(elp->prev == elp);     /* multiple enqueue, BAD! */
60     ASSERT(elp->next == elp);
61
62     headp = headp->prev;
63
64     elp->next = headp->next;
65     headp->next = elp;
66     elp->prev = elp->next->prev;
67     elp->next->prev = elp;
68 }
69
70 /*
71  * d_list_rem_head - removes first element from list
72  */
73 static inline d_list_el_t *d_list_rem_head (d_list_el_t *headp)
74 {
75     d_list_el_t *elp;
76
77     elp = headp->next;
78     if (elp == headp)
79         return (NULL);
80     headp->next = elp->next;
81     elp->next->prev = elp->prev;
82
83     elp->next = elp->prev = elp;
84     return (elp);
85 }
86
87 /*
88  * d_list_rem_elem - removes specific element from list.
89  */
90 static inline void d_list_rem_elem (d_list_el_t *elp)
91 {
92     d_list_el_t *headp;
93
94     headp = elp->prev;
95
96     headp->next = elp->next;
97     elp->next->prev = elp->prev;
98     elp->next = elp->prev = elp;
99 }
100
101 #define TIMER_BKTS_PER_WHEEL    128 /* power of 2, please */
102 #define TIMER_NWHEELS           4
103
104 typedef struct {
105     i32 curindex;               /* current index for this wheel */
106     d_list_el_t *bkts;          /* vector of bucket listheads */
107 } spp_timer_wheel_t;
108
109
110 typedef struct {
111     u64 next_run_ticks;         /* Next time we expire timers */
112     spp_timer_wheel_t **wheels; /* pointers to wheels */
113 } spp_timer_axle_t;
114
115
116 typedef struct {
117     d_list_el_t el;
118     u16 cb_index;
119     u16 flags;
120     u64 expires;
121 } spp_timer_t;
122
123 #define SPP_TIMER_RUNNING       0x0001
124
125
126 /*
127  * prototypes
128  */
129 void spp_timer_set_ticks_per_ms(u64);
130 void spp_timer_axle_init (spp_timer_axle_t *ta);
131 void spp_timer_expire(spp_timer_axle_t *ta, u64 now);
132 void spp_timer_final_init(void);
133
134 void spp_timer_start(spp_timer_t *tp);
135 void spp_timer_start_axle(spp_timer_axle_t *ta, spp_timer_t *tp);
136 void spp_timer_stop(spp_timer_t *tp);
137 u16 spp_timer_register_callback (void (*fp)(spp_timer_t *));
138
139 #endif /* __SPP_TIMERS_H__ */