Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00039 #ifndef timer_funcs_h
00040 #define timer_funcs_h
00041
00042 #include "timer.h"
00043
00044
00045 struct timer_head{
00046 struct timer_ln* volatile next;
00047 struct timer_ln* volatile prev;
00048 };
00049
00050
00051
00066
00068 #define H0_BITS 14
00069 #define H1_BITS 9
00070 #define H2_BITS (32-H1_BITS-H0_BITS)
00071
00072
00073 #define H0_ENTRIES (1<<H0_BITS)
00074 #define H1_ENTRIES (1<<H1_BITS)
00075 #define H2_ENTRIES (1<<H2_BITS)
00076
00077 #define H0_MASK (H0_ENTRIES-1)
00078 #define H1_MASK (H1_ENTRIES-1)
00079 #define H1_H0_MASK ((1<<(H0_BITS+H1_BITS))-1)
00080
00083 struct timer_lists{
00084 struct timer_head h0[H0_ENTRIES];
00085 struct timer_head h1[H1_ENTRIES];
00086 struct timer_head h2[H2_ENTRIES];
00087 struct timer_head expired;
00088 };
00089
00090 extern struct timer_lists* timer_lst;
00091
00092
00093 #define _timer_init_list(head) clist_init((head), next, prev)
00094
00095
00096 #define _timer_add_list(head, tl) \
00097 clist_append((head), (tl), next, prev)
00098
00099 #define _timer_rm_list(tl) \
00100 clist_rm((tl), next, prev)
00101
00102 #define timer_foreach(tl, head) clist_foreach((head), (tl), next)
00103 #define timer_foreach_safe(tl, tmp, head) \
00104 clist_foreach_safe((head), (tl), (tmp), next)
00105
00106
00107
00108
00115 static inline int _timer_dist_tl(struct timer_ln* tl, ticks_t delta)
00116 {
00117 if (delta<H0_ENTRIES){
00118 if (delta==0){
00119 LOG(L_WARN, "WARNING: timer: add_timeout: 0 expire timer added\n");
00120 _timer_add_list(&timer_lst->expired, tl);
00121 }else{
00122 _timer_add_list( &timer_lst->h0[tl->expire & H0_MASK], tl);
00123 }
00124 }else if (delta<(H0_ENTRIES*H1_ENTRIES)){
00125 _timer_add_list(&timer_lst->h1[(tl->expire & H1_H0_MASK)>>H0_BITS],tl);
00126 }else{
00127 _timer_add_list(&timer_lst->h2[tl->expire>>(H1_BITS+H0_BITS)], tl);
00128 }
00129 return 0;
00130 }
00131
00132
00133
00134 #define _timer_mv_expire(h) \
00135 do{ \
00136 if ((h)->next!=(struct timer_ln*)(h)){ \
00137 clist_append_sublist(&timer_lst->expired, (h)->next, \
00138 (h)->prev, next, prev); \
00139 _timer_init_list(h); \
00140 } \
00141 }while(0)
00142
00143
00144 #if 1
00145
00146 static inline void timer_redist(ticks_t t, struct timer_head *h)
00147 {
00148 struct timer_ln* tl;
00149 struct timer_ln* tmp;
00150
00151 timer_foreach_safe(tl, tmp, h){
00152 _timer_dist_tl(tl, tl->expire-t);
00153 }
00154
00155 _timer_init_list(h);
00156 }
00157
00158 static inline void timer_run(ticks_t t)
00159 {
00160
00161 if ((t & H0_MASK)==0){
00162 if ((t & H1_H0_MASK)==0){
00163 timer_redist(t, &timer_lst->h2[t>>(H0_BITS+H1_BITS)]);
00164 }
00165
00166 timer_redist(t, &timer_lst->h1[(t & H1_H0_MASK)>>H0_BITS]);
00167 }
00168
00169
00170
00171 _timer_mv_expire(&timer_lst->h0[t & H0_MASK]);
00172 }
00173 #else
00174
00175 static inline void timer_lst_mv0(ticks_t t, struct timer_head* h)
00176 {
00177 struct timer_ln* tl;
00178 struct timer_ln* tmp;
00179
00180 timer_foreach_safe(tl, tmp, h){
00181 _timer_dist_tl(tl, &timer_lst->h0[tl->expire & H0_MASK]);
00182 }
00183
00184 _timer_init_list(h);
00185 }
00186
00187 static inline void timer_lst_mv1(ticks_t t, struct timer_head* h)
00188 {
00189 struct timer_ln* tl;
00190 struct timer_ln* tmp;
00191
00192 timer_foreach_safe(tl, tmp, h){
00193 if ((tl->expire & H0_MASK)==0)
00194 _timer_add_list(tl, &timer_lst->h0[tl->expire & H0_MASK]);
00195 else
00196 _timer_add_list(tl,
00197 &timer_lst->h1[(tl->expire & H1_H0_MASK)>>H0_BITS]);
00198 }
00199
00200 _timer_init_list(h);
00201 }
00202
00203
00205 static inline void timer_run(ticks_t t)
00206 {
00207
00208 if ((t & H0_MASK)==0){
00209 if ((t & H1_H0_MASK)==0)
00210
00211 timer_lst_mv1(&timer_lst->h2[t>>(H0_BITS+H1_BITS)]);
00212
00213 timer_lst_mv0(&timer_lst->h1[(t & H1_H0_MASK)>>H0_BITS]);
00214 }
00215 _timer_mv_expire(t, &timer_lst->h0[t & H0_MASK]);
00216 }
00217 #endif
00218
00219
00220
00221 #endif