• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • Directories
  • File List
  • Globals

timer_funcs.h

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  *
00005  * timer related functions (internal)
00006  *
00007  * Copyright (C) 2005 iptelorg GmbH
00008  *
00009  * This file is part of SIP-router, a free SIP server.
00010  *
00011  * SIP-router is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License as published by
00013  * the Free Software Foundation; either version 2 of the License, or
00014  * (at your option) any later version
00015  *
00016  * SIP-router is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License 
00022  * along with this program; if not, write to the Free Software 
00023  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024  */
00025 
00026 /* History:
00027  * --------
00028  *  2005-07-27  complete re-design/re-implemnetation (andrei)
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; /* list of expired entries */
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         /* clear the current list */
00155         _timer_init_list(h);
00156 }
00157 
00158 static inline void timer_run(ticks_t t)
00159 {
00160         /* trust the compiler for optimizing */
00161         if ((t & H0_MASK)==0){              /*r1*/
00162                 if ((t & H1_H0_MASK)==0){        /*r2*/
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]);/*r2 >> H0*/
00167         }
00168         /*
00169         DBG("timer_run: ticks %u, expire h0[%u]\n",
00170                                                 (unsigned ) t, (unsigned)(t & H0_MASK));*/
00171         _timer_mv_expire(&timer_lst->h0[t & H0_MASK]);  /*r1*/
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         /* clear the current list */
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) /* directly to h0 */
00194                         _timer_add_list(tl, &timer_lst->h0[tl->expire & H0_MASK]);
00195                 else  /* to h1 */
00196                         _timer_add_list(tl, 
00197                                                 &timer_lst->h1[(tl->expire & H1_H0_MASK)>>H0_BITS]);
00198         }
00199         /* clear the current list */
00200         _timer_init_list(h);
00201 }
00202 
00203 
00205 static inline void timer_run(ticks_t t)
00206 {
00207         /* trust the compiler for optimizing */
00208         if ((t & H0_MASK)==0){              /*r1*/
00209                 if ((t & H1_H0_MASK)==0)        /*r2*/
00210                         /* just move the list "down" to hash1 */
00211                         timer_lst_mv1(&timer_lst->h2[t>>(H0_BITS+H1_BITS)]); 
00212                 /* move "down" to hash0 */
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]);  /*r1*/
00216 }
00217 #endif
00218 
00219 
00220 
00221 #endif

Generated on Tue May 22 2012 13:10:17 for SIP Router by  doxygen 1.7.1