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
00031
00032
00033
00034
00035
00036 #ifndef timer_funcs_h
00037 #define timer_funcs_h
00038
00039 #include "timer.h"
00040
00041
00042 struct timer_head{
00043 struct timer_ln* volatile next;
00044 struct timer_ln* volatile prev;
00045 };
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #define H0_BITS 14
00058 #define H1_BITS 9
00059 #define H2_BITS (32-H1_BITS-H0_BITS)
00060
00061
00062
00063
00064
00065
00066
00067 #define H0_ENTRIES (1<<H0_BITS)
00068 #define H1_ENTRIES (1<<H1_BITS)
00069 #define H2_ENTRIES (1<<H2_BITS)
00070
00071 #define H0_MASK (H0_ENTRIES-1)
00072 #define H1_MASK (H1_ENTRIES-1)
00073 #define H1_H0_MASK ((1<<(H0_BITS+H1_BITS))-1)
00074
00075
00076 struct timer_lists{
00077 struct timer_head h0[H0_ENTRIES];
00078 struct timer_head h1[H1_ENTRIES];
00079 struct timer_head h2[H2_ENTRIES];
00080 struct timer_head expired;
00081 };
00082
00083 extern struct timer_lists* timer_lst;
00084
00085
00086 #define _timer_init_list(head) clist_init((head), next, prev)
00087
00088
00089 #define _timer_add_list(head, tl) \
00090 clist_append((head), (tl), next, prev)
00091
00092 #define _timer_rm_list(tl) \
00093 clist_rm((tl), next, prev)
00094
00095 #define timer_foreach(tl, head) clist_foreach((head), (tl), next)
00096 #define timer_foreach_safe(tl, tmp, head) \
00097 clist_foreach_safe((head), (tl), (tmp), next)
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 static inline int _timer_dist_tl(struct timer_ln* tl, ticks_t delta)
00108 {
00109 if (delta<H0_ENTRIES){
00110 if (delta==0){
00111 LOG(L_WARN, "WARNING: timer: add_timeout: 0 expire timer added\n");
00112 _timer_add_list(&timer_lst->expired, tl);
00113 }else{
00114 _timer_add_list( &timer_lst->h0[tl->expire & H0_MASK], tl);
00115 }
00116 }else if (delta<(H0_ENTRIES*H1_ENTRIES)){
00117 _timer_add_list(&timer_lst->h1[(tl->expire & H1_H0_MASK)>>H0_BITS],tl);
00118 }else{
00119 _timer_add_list(&timer_lst->h2[tl->expire>>(H1_BITS+H0_BITS)], tl);
00120 }
00121 return 0;
00122 }
00123
00124
00125
00126 #define _timer_mv_expire(h) \
00127 do{ \
00128 if ((h)->next!=(struct timer_ln*)(h)){ \
00129 clist_append_sublist(&timer_lst->expired, (h)->next, \
00130 (h)->prev, next, prev); \
00131 _timer_init_list(h); \
00132 } \
00133 }while(0)
00134
00135
00136 #if 1
00137
00138 static inline void timer_redist(ticks_t t, struct timer_head *h)
00139 {
00140 struct timer_ln* tl;
00141 struct timer_ln* tmp;
00142
00143 timer_foreach_safe(tl, tmp, h){
00144 _timer_dist_tl(tl, tl->expire-t);
00145 }
00146
00147 _timer_init_list(h);
00148 }
00149
00150 static inline void timer_run(ticks_t t)
00151 {
00152
00153 if ((t & H0_MASK)==0){
00154 if ((t & H1_H0_MASK)==0){
00155 timer_redist(t, &timer_lst->h2[t>>(H0_BITS+H1_BITS)]);
00156 }
00157
00158 timer_redist(t, &timer_lst->h1[(t & H1_H0_MASK)>>H0_BITS]);
00159 }
00160
00161
00162
00163 _timer_mv_expire(&timer_lst->h0[t & H0_MASK]);
00164 }
00165 #else
00166
00167 static inline void timer_lst_mv0(ticks_t t, struct timer_head* h)
00168 {
00169 struct timer_ln* tl;
00170 struct timer_ln* tmp;
00171
00172 timer_foreach_safe(tl, tmp, h){
00173 _timer_dist_tl(tl, &timer_lst->h0[tl->expire & H0_MASK]);
00174 }
00175
00176 _timer_init_list(h);
00177 }
00178
00179 static inline void timer_lst_mv1(ticks_t t, struct timer_head* h)
00180 {
00181 struct timer_ln* tl;
00182 struct timer_ln* tmp;
00183
00184 timer_foreach_safe(tl, tmp, h){
00185 if ((tl->expire & H0_MASK)==0)
00186 _timer_add_list(tl, &timer_lst->h0[tl->expire & H0_MASK]);
00187 else
00188 _timer_add_list(tl,
00189 &timer_lst->h1[(tl->expire & H1_H0_MASK)>>H0_BITS]);
00190 }
00191
00192 _timer_init_list(h);
00193 }
00194
00195
00196
00197 static inline void timer_run(ticks_t t)
00198 {
00199
00200 if ((t & H0_MASK)==0){
00201 if ((t & H1_H0_MASK)==0)
00202
00203 timer_lst_mv1(&timer_lst->h2[t>>(H0_BITS+H1_BITS)]);
00204
00205 timer_lst_mv0(&timer_lst->h1[(t & H1_H0_MASK)>>H0_BITS]);
00206 }
00207 _timer_mv_expire(t, &timer_lst->h0[t & H0_MASK]);
00208 }
00209 #endif
00210
00211
00212
00213 #endif