Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,216 +0,0 @@
1
-/*
2
- * timer related functions (internal)
3
- *
4
- * Copyright (C) 2005 iptelorg GmbH
5
- *
6
- * This file is part of Kamailio, a free SIP server.
7
- *
8
- * Kamailio is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License as published by
10
- * the Free Software Foundation; either version 2 of the License, or
11
- * (at your option) any later version
12
- *
13
- * Kamailio is distributed in the hope that it will be useful,
14
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
- * GNU General Public License for more details.
17
- *
18
- * You should have received a copy of the GNU General Public License
19
- * along with this program; if not, write to the Free Software
20
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21
- */
22
-
23
-/**
24
- * @file
25
- * @brief Kamailio core :: Timer related functions (internal)
26
- * @ingroup core
27
- * Module: @ref core
28
- */
29
-
30
-
31
-#ifndef timer_funcs_h
32
-#define timer_funcs_h
33
-
34
-#include "timer.h"
35
-
36
-
37
-struct timer_head{
38
-	struct timer_ln* volatile next;
39
-	struct timer_ln* volatile prev;
40
-};
41
-
42
-
43
-
44
-/** @name hierarchical timing wheel with 3 levels
45
- *
46
- * Most timeouts should go in the first "wheel" (h0)
47
- * h0 will contain timers expiring from crt. time up to
48
- * crt. time + (1<<H0_BITS)/TICKS_HZ s and will use
49
- * (1<<H0_BITS)*sizeof(struct timer_head) bytes of memory, so arrange it
50
- * accordingly
51
- *
52
- * Uses ~280K on a 64 bits system and ~140K on a 32 bit system; for TICKS_HZ=10
53
- * holds ~ 30 min in the first hash/wheel and ~233h in the first two.
54
- * More perfomant arrangement: 16, 8, 8 (but eats 1 MB on a 64 bit system, and
55
- *  512K on a 32 bit one). For TICKS_HZ=10 it holds almost 2h in the
56
- *  first hash/wheel and ~460h in the first two.
57
- */
58
-/*@{ */
59
-
60
-#define H0_BITS 14
61
-#define H1_BITS  9
62
-#define H2_BITS  (32-H1_BITS-H0_BITS)
63
-
64
-
65
-#define H0_ENTRIES (1<<H0_BITS)
66
-#define H1_ENTRIES (1<<H1_BITS)
67
-#define H2_ENTRIES (1<<H2_BITS)
68
-
69
-#define H0_MASK (H0_ENTRIES-1)
70
-#define H1_MASK (H1_ENTRIES-1)
71
-#define H1_H0_MASK ((1<<(H0_BITS+H1_BITS))-1)
72
-
73
-/*@} */
74
-
75
-struct timer_lists{
76
-	struct timer_head  h0[H0_ENTRIES];
77
-	struct timer_head  h1[H1_ENTRIES];
78
-	struct timer_head  h2[H2_ENTRIES];
79
-	struct timer_head  expired; /* list of expired entries */
80
-};
81
-
82
-extern struct timer_lists* timer_lst;
83
-
84
-
85
-#define _timer_init_list(head)	clist_init((head), next, prev)
86
-
87
-
88
-#define _timer_add_list(head, tl) \
89
-	clist_append((head), (tl), next, prev)
90
-
91
-#define _timer_rm_list(tl) \
92
-	clist_rm((tl), next, prev)
93
-
94
-#define timer_foreach(tl, head)	clist_foreach((head), (tl), next)
95
-#define timer_foreach_safe(tl, tmp, head)	\
96
-	clist_foreach_safe((head), (tl), (tmp), next)
97
-
98
-
99
-
100
-
101
-/** @brief generic add timer entry to the timer lists function (see _timer_add)
102
- *
103
- * tl->expire must be set previously, delta is the difference in ticks
104
- * from current time to the timer desired expire (should be tl->expire-*tick)
105
- * If you don't know delta, you probably want to call _timer_add instead.
106
- */
107
-static inline int _timer_dist_tl(struct timer_ln* tl, ticks_t delta)
108
-{
109
-	if (delta<H0_ENTRIES){
110
-		if (delta==0){
111
-			LM_WARN("0 expire timer added\n");
112
-			_timer_add_list(&timer_lst->expired, tl);
113
-		}else{
114
-			_timer_add_list( &timer_lst->h0[tl->expire & H0_MASK], tl);
115
-		}
116
-	}else if (delta<(H0_ENTRIES*H1_ENTRIES)){
117
-		_timer_add_list(&timer_lst->h1[(tl->expire & H1_H0_MASK)>>H0_BITS],tl);
118
-	}else{
119
-		_timer_add_list(&timer_lst->h2[tl->expire>>(H1_BITS+H0_BITS)], tl);
120
-	}
121
-	return 0;
122
-}
123
-
124
-
125
-
126
-#define _timer_mv_expire(h) \
127
-	do{ \
128
-		if ((h)->next!=(struct timer_ln*)(h)){ \
129
-			clist_append_sublist(&timer_lst->expired, (h)->next, \
130
-									(h)->prev, next, prev); \
131
-			_timer_init_list(h); \
132
-		} \
133
-	}while(0)
134
-
135
-
136
-#if 1
137
-
138
-static inline void timer_redist(ticks_t t, struct timer_head *h)
139
-{
140
-	struct timer_ln* tl;
141
-	struct timer_ln* tmp;
142
-
143
-	timer_foreach_safe(tl, tmp, h){
144
-		_timer_dist_tl(tl, tl->expire-t);
145
-	}
146
-	/* clear the current list */
147
-	_timer_init_list(h);
148
-}
149
-
150
-static inline void timer_run(ticks_t t)
151
-{
152
-	struct timer_head *thp;
153
-
154
-	/* trust the compiler for optimizing */
155
-	if ((t & H0_MASK)==0){              /*r1*/
156
-		if ((t & H1_H0_MASK)==0){        /*r2*/
157
-			timer_redist(t, &timer_lst->h2[t>>(H0_BITS+H1_BITS)]);
158
-		}
159
-
160
-		timer_redist(t, &timer_lst->h1[(t & H1_H0_MASK)>>H0_BITS]);/*r2 >> H0*/
161
-	}
162
-	/*
163
-	DBG("timer_run: ticks %u, expire h0[%u]\n",
164
-						(unsigned ) t, (unsigned)(t & H0_MASK));*/
165
-	thp = &timer_lst->h0[t & H0_MASK];
166
-	_timer_mv_expire(thp);  /*r1*/
167
-}
168
-#else
169
-
170
-static inline void timer_lst_mv0(ticks_t t, struct timer_head* h)
171
-{
172
-	struct timer_ln* tl;
173
-	struct timer_ln* tmp;
174
-
175
-	timer_foreach_safe(tl, tmp, h){
176
-			_timer_dist_tl(tl, &timer_lst->h0[tl->expire & H0_MASK]);
177
-	}
178
-	/* clear the current list */
179
-	_timer_init_list(h);
180
-}
181
-
182
-static inline void timer_lst_mv1(ticks_t t, struct timer_head* h)
183
-{
184
-	struct timer_ln* tl;
185
-	struct timer_ln* tmp;
186
-
187
-	timer_foreach_safe(tl, tmp, h){
188
-		if ((tl->expire & H0_MASK)==0) /* directly to h0 */
189
-			_timer_add_list(tl, &timer_lst->h0[tl->expire & H0_MASK]);
190
-		else  /* to h1 */
191
-			_timer_add_list(tl,
192
-						&timer_lst->h1[(tl->expire & H1_H0_MASK)>>H0_BITS]);
193
-	}
194
-	/* clear the current list */
195
-	_timer_init_list(h);
196
-}
197
-
198
-
199
-/** @brief possible faster version */
200
-static inline void timer_run(ticks_t t)
201
-{
202
-	/* trust the compiler for optimizing */
203
-	if ((t & H0_MASK)==0){              /*r1*/
204
-		if ((t & H1_H0_MASK)==0)        /*r2*/
205
-			/* just move the list "down" to hash1 */
206
-			timer_lst_mv1(&timer_lst->h2[t>>(H0_BITS+H1_BITS)]);
207
-		/* move "down" to hash0 */
208
-		timer_lst_mv0(&timer_lst->h1[(t & H1_H0_MASK)>>H0_BITS]);
209
-	}
210
-	_timer_mv_expire(t, &timer_lst->h0[t & H0_MASK]);  /*r1*/
211
-}
212
-#endif
213
-
214
-
215
-
216
-#endif
Browse code

core: timer - coherent indentation and whitespacing

Daniel-Constantin Mierla authored on 05/05/2016 06:28:19
Showing 1 changed files
... ...
@@ -15,8 +15,8 @@
15 15
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 16
  * GNU General Public License for more details.
17 17
  *
18
- * You should have received a copy of the GNU General Public License 
19
- * along with this program; if not, write to the Free Software 
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program; if not, write to the Free Software
20 20
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21 21
  */
22 22
 
... ...
@@ -58,7 +58,7 @@ struct timer_head{
58 58
 /*@{ */
59 59
 
60 60
 #define H0_BITS 14
61
-#define H1_BITS  9 
61
+#define H1_BITS  9
62 62
 #define H2_BITS  (32-H1_BITS-H0_BITS)
63 63
 
64 64
 
... ...
@@ -139,7 +139,7 @@ static inline void timer_redist(ticks_t t, struct timer_head *h)
139 139
 {
140 140
 	struct timer_ln* tl;
141 141
 	struct timer_ln* tmp;
142
-	
142
+
143 143
 	timer_foreach_safe(tl, tmp, h){
144 144
 		_timer_dist_tl(tl, tl->expire-t);
145 145
 	}
... ...
@@ -156,7 +156,7 @@ static inline void timer_run(ticks_t t)
156 156
 		if ((t & H1_H0_MASK)==0){        /*r2*/
157 157
 			timer_redist(t, &timer_lst->h2[t>>(H0_BITS+H1_BITS)]);
158 158
 		}
159
-		
159
+
160 160
 		timer_redist(t, &timer_lst->h1[(t & H1_H0_MASK)>>H0_BITS]);/*r2 >> H0*/
161 161
 	}
162 162
 	/*
... ...
@@ -171,7 +171,7 @@ static inline void timer_lst_mv0(ticks_t t, struct timer_head* h)
171 171
 {
172 172
 	struct timer_ln* tl;
173 173
 	struct timer_ln* tmp;
174
-	
174
+
175 175
 	timer_foreach_safe(tl, tmp, h){
176 176
 			_timer_dist_tl(tl, &timer_lst->h0[tl->expire & H0_MASK]);
177 177
 	}
... ...
@@ -183,12 +183,12 @@ static inline void timer_lst_mv1(ticks_t t, struct timer_head* h)
183 183
 {
184 184
 	struct timer_ln* tl;
185 185
 	struct timer_ln* tmp;
186
-	
186
+
187 187
 	timer_foreach_safe(tl, tmp, h){
188 188
 		if ((tl->expire & H0_MASK)==0) /* directly to h0 */
189 189
 			_timer_add_list(tl, &timer_lst->h0[tl->expire & H0_MASK]);
190 190
 		else  /* to h1 */
191
-			_timer_add_list(tl, 
191
+			_timer_add_list(tl,
192 192
 						&timer_lst->h1[(tl->expire & H1_H0_MASK)>>H0_BITS]);
193 193
 	}
194 194
 	/* clear the current list */
... ...
@@ -203,7 +203,7 @@ static inline void timer_run(ticks_t t)
203 203
 	if ((t & H0_MASK)==0){              /*r1*/
204 204
 		if ((t & H1_H0_MASK)==0)        /*r2*/
205 205
 			/* just move the list "down" to hash1 */
206
-			timer_lst_mv1(&timer_lst->h2[t>>(H0_BITS+H1_BITS)]); 
206
+			timer_lst_mv1(&timer_lst->h2[t>>(H0_BITS+H1_BITS)]);
207 207
 		/* move "down" to hash0 */
208 208
 		timer_lst_mv0(&timer_lst->h1[(t & H1_H0_MASK)>>H0_BITS]);
209 209
 	}
Browse code

core: Modify doxygen, remove history, remove SVN IDs, change "ser" and "sip-router" to "KAMAILIO"

Olle E. Johansson authored on 16/01/2015 16:38:46
Showing 1 changed files
... ...
@@ -1,19 +1,16 @@
1 1
 /*
2
- * $Id$
3
- *
4
- *
5 2
  * timer related functions (internal)
6 3
  *
7 4
  * Copyright (C) 2005 iptelorg GmbH
8 5
  *
9
- * This file is part of SIP-router, a free SIP server.
6
+ * This file is part of Kamailio, a free SIP server.
10 7
  *
11
- * SIP-router is free software; you can redistribute it and/or modify
8
+ * Kamailio is free software; you can redistribute it and/or modify
12 9
  * it under the terms of the GNU General Public License as published by
13 10
  * the Free Software Foundation; either version 2 of the License, or
14 11
  * (at your option) any later version
15 12
  *
16
- * SIP-router is distributed in the hope that it will be useful,
13
+ * Kamailio is distributed in the hope that it will be useful,
17 14
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 15
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 16
  * GNU General Public License for more details.
... ...
@@ -23,14 +20,9 @@
23 20
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
24 21
  */
25 22
 
26
-/* History:
27
- * --------
28
- *  2005-07-27  complete re-design/re-implemnetation (andrei)
29
- */
30
-
31 23
 /**
32 24
  * @file
33
- * @brief SIP-router core :: Timer related functions (internal)
25
+ * @brief Kamailio core :: Timer related functions (internal)
34 26
  * @ingroup core
35 27
  * Module: @ref core
36 28
  */
Browse code

timer_funcs.h: logging: convert LOG to LM_*

Ovidiu Sas authored on 03/10/2014 18:45:42
Showing 1 changed files
... ...
@@ -116,7 +116,7 @@ static inline int _timer_dist_tl(struct timer_ln* tl, ticks_t delta)
116 116
 {
117 117
 	if (delta<H0_ENTRIES){
118 118
 		if (delta==0){
119
-			LOG(L_WARN, "WARNING: timer: add_timeout: 0 expire timer added\n");
119
+			LM_WARN("0 expire timer added\n");
120 120
 			_timer_add_list(&timer_lst->expired, tl);
121 121
 		}else{
122 122
 			_timer_add_list( &timer_lst->h0[tl->expire & H0_MASK], tl);
Browse code

all: updated FSF address in GPL text

Anthony Messina authored on 04/07/2014 09:36:37 • Daniel-Constantin Mierla committed on 04/07/2014 09:37:36
Showing 1 changed files
... ...
@@ -20,7 +20,7 @@
20 20
  *
21 21
  * You should have received a copy of the GNU General Public License 
22 22
  * along with this program; if not, write to the Free Software 
23
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
24 24
  */
25 25
 
26 26
 /* History:
Browse code

core: fix for warning dereferencing type-punned pointer will break strict-aliasing rules

- related to timer list operation

Daniel-Constantin Mierla authored on 19/09/2013 13:17:38
Showing 1 changed files
... ...
@@ -157,6 +157,8 @@ static inline void timer_redist(ticks_t t, struct timer_head *h)
157 157
 
158 158
 static inline void timer_run(ticks_t t)
159 159
 {
160
+	struct timer_head *thp;
161
+
160 162
 	/* trust the compiler for optimizing */
161 163
 	if ((t & H0_MASK)==0){              /*r1*/
162 164
 		if ((t & H1_H0_MASK)==0){        /*r2*/
... ...
@@ -168,7 +170,8 @@ static inline void timer_run(ticks_t t)
168 170
 	/*
169 171
 	DBG("timer_run: ticks %u, expire h0[%u]\n",
170 172
 						(unsigned ) t, (unsigned)(t & H0_MASK));*/
171
-	_timer_mv_expire(&timer_lst->h0[t & H0_MASK]);  /*r1*/
173
+	thp = &timer_lst->h0[t & H0_MASK];
174
+	_timer_mv_expire(thp);  /*r1*/
172 175
 }
173 176
 #else
174 177
 
Browse code

core: Correct an error in doxygen comments.

One of previous commits added an extra comment-closing sequence
which caused a compilation error. This patch fixes that.

Jan Janak authored on 23/10/2009 15:31:50
Showing 1 changed files
... ...
@@ -57,13 +57,12 @@ struct timer_head{
57 57
  * (1<<H0_BITS)*sizeof(struct timer_head) bytes of memory, so arrange it
58 58
  * accordingly
59 59
  *
60
-x* Uses ~280K on a 64 bits system and ~140K on a 32 bit system; for TICKS_HZ=10
60
+ * Uses ~280K on a 64 bits system and ~140K on a 32 bit system; for TICKS_HZ=10
61 61
  * holds ~ 30 min in the first hash/wheel and ~233h in the first two.
62 62
  * More perfomant arrangement: 16, 8, 8 (but eats 1 MB on a 64 bit system, and
63 63
  *  512K on a 32 bit one). For TICKS_HZ=10 it holds almost 2h in the
64 64
  *  first hash/wheel and ~460h in the first two.
65 65
  */
66
- */
67 66
 /*@{ */
68 67
 
69 68
 #define H0_BITS 14
Browse code

Doxygen updates on timer modules

- changing from \ and ! to javadoc format
- adding new doxygen file headers

oej authored on 22/10/2009 17:56:48
Showing 1 changed files
... ...
@@ -6,19 +6,14 @@
6 6
  *
7 7
  * Copyright (C) 2005 iptelorg GmbH
8 8
  *
9
- * This file is part of ser, a free SIP server.
9
+ * This file is part of SIP-router, a free SIP server.
10 10
  *
11
- * ser is free software; you can redistribute it and/or modify
11
+ * SIP-router is free software; you can redistribute it and/or modify
12 12
  * it under the terms of the GNU General Public License as published by
13 13
  * the Free Software Foundation; either version 2 of the License, or
14 14
  * (at your option) any later version
15 15
  *
16
- * For a license to use the ser software under conditions
17
- * other than those described here, or to purchase support for this
18
- * software, please contact iptel.org by e-mail at the following addresses:
19
- *    info@iptel.org
20
- *
21
- * ser is distributed in the hope that it will be useful,
16
+ * SIP-router is distributed in the hope that it will be useful,
22 17
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 18
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 19
  * GNU General Public License for more details.
... ...
@@ -27,11 +22,19 @@
27 22
  * along with this program; if not, write to the Free Software 
28 23
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29 24
  */
25
+
30 26
 /* History:
31 27
  * --------
32 28
  *  2005-07-27  complete re-design/re-implemnetation (andrei)
33 29
  */
34 30
 
31
+/**
32
+ * @file
33
+ * @brief SIP-router core :: Timer related functions (internal)
34
+ * @ingroup core
35
+ * Module: @ref core
36
+ */
37
+
35 38
 
36 39
 #ifndef timer_funcs_h
37 40
 #define timer_funcs_h
... ...
@@ -46,23 +49,27 @@ struct timer_head{
46 49
 
47 50
 
48 51
 
49
-/* hierarchical timing wheel with 3 levels
52
+/** @name hierarchical timing wheel with 3 levels
53
+ *
50 54
  * Most timeouts should go in the first "wheel" (h0)
51 55
  * h0 will contain timers expiring from crt. time up to
52 56
  * crt. time + (1<<H0_BITS)/TICKS_HZ s and will use
53 57
  * (1<<H0_BITS)*sizeof(struct timer_head) bytes of memory, so arrange it
54 58
  * accordingly
55
- */
56
-
57
-#define H0_BITS 14
58
-#define H1_BITS  9 
59
-#define H2_BITS  (32-H1_BITS-H0_BITS)
60
-/* Uses ~280K on a 64 bits system and ~140K on a 32 bit system; for TICKS_HZ=10
59
+ *
60
+x* Uses ~280K on a 64 bits system and ~140K on a 32 bit system; for TICKS_HZ=10
61 61
  * holds ~ 30 min in the first hash/wheel and ~233h in the first two.
62 62
  * More perfomant arrangement: 16, 8, 8 (but eats 1 MB on a 64 bit system, and
63 63
  *  512K on a 32 bit one). For TICKS_HZ=10 it holds almost 2h in the
64 64
  *  first hash/wheel and ~460h in the first two.
65 65
  */
66
+ */
67
+/*@{ */
68
+
69
+#define H0_BITS 14
70
+#define H1_BITS  9 
71
+#define H2_BITS  (32-H1_BITS-H0_BITS)
72
+
66 73
 
67 74
 #define H0_ENTRIES (1<<H0_BITS)
68 75
 #define H1_ENTRIES (1<<H1_BITS)
... ...
@@ -72,6 +79,7 @@ struct timer_head{
72 79
 #define H1_MASK (H1_ENTRIES-1)
73 80
 #define H1_H0_MASK ((1<<(H0_BITS+H1_BITS))-1)
74 81
 
82
+/*@} */
75 83
 
76 84
 struct timer_lists{
77 85
 	struct timer_head  h0[H0_ENTRIES];
... ...
@@ -99,7 +107,8 @@ extern struct timer_lists* timer_lst;
99 107
 
100 108
 
101 109
 
102
-/* generic add timer entry to the timer lists function (see _timer_add)
110
+/** @brief generic add timer entry to the timer lists function (see _timer_add)
111
+ *
103 112
  * tl->expire must be set previously, delta is the difference in ticks
104 113
  * from current time to the timer desired expire (should be tl->expire-*tick)
105 114
  * If you don't know delta, you probably want to call _timer_add instead.
... ...
@@ -193,7 +202,7 @@ static inline void timer_lst_mv1(ticks_t t, struct timer_head* h)
193 202
 }
194 203
 
195 204
 
196
-/* possible faster version */
205
+/** @brief possible faster version */
197 206
 static inline void timer_run(ticks_t t)
198 207
 {
199 208
 	/* trust the compiler for optimizing */
Browse code

- more timer DBG cleanups

Andrei Pelinescu-Onciul authored on 14/02/2006 18:04:17
Showing 1 changed files
... ...
@@ -111,21 +111,11 @@ static inline int _timer_dist_tl(struct timer_ln* tl, ticks_t delta)
111 111
 			LOG(L_WARN, "WARNING: timer: add_timeout: 0 expire timer added\n");
112 112
 			_timer_add_list(&timer_lst->expired, tl);
113 113
 		}else{
114
-			DBG("_timer_dist_tl: adding timer %p, delta %u,"
115
-					" expire %u @h0[%u]\n",
116
-				tl, (unsigned) delta, (unsigned) tl->expire,
117
-				(unsigned)(tl->expire & H0_MASK));
118 114
 			_timer_add_list( &timer_lst->h0[tl->expire & H0_MASK], tl);
119 115
 		}
120 116
 	}else if (delta<(H0_ENTRIES*H1_ENTRIES)){
121
-		DBG("_timer_dist_tl: adding timer %p, delta %u, expire %u @h1[%u]\n",
122
-				tl, (unsigned) delta, (unsigned) tl->expire,
123
-				(unsigned)((tl->expire & H1_H0_MASK)>>H0_BITS));
124 117
 		_timer_add_list(&timer_lst->h1[(tl->expire & H1_H0_MASK)>>H0_BITS],tl);
125 118
 	}else{
126
-		DBG("_timer_dist_tl: adding timer %p, delta %u, expire %u @h2[%u]\n",
127
-				tl, (unsigned) delta, (unsigned) tl->expire,
128
-				(unsigned)(tl->expire>>(H1_BITS+H0_BITS)));
129 119
 		_timer_add_list(&timer_lst->h2[tl->expire>>(H1_BITS+H0_BITS)], tl);
130 120
 	}
131 121
 	return 0;
... ...
@@ -150,8 +140,6 @@ static inline void timer_redist(ticks_t t, struct timer_head *h)
150 140
 	struct timer_ln* tl;
151 141
 	struct timer_ln* tmp;
152 142
 	
153
-	DBG("timer_redist: list %p, ticks %lu\n", h, (unsigned long) t);
154
-	
155 143
 	timer_foreach_safe(tl, tmp, h){
156 144
 		_timer_dist_tl(tl, tl->expire-t);
157 145
 	}
... ...
@@ -164,12 +152,8 @@ static inline void timer_run(ticks_t t)
164 152
 	/* trust the compiler for optimizing */
165 153
 	if ((t & H0_MASK)==0){              /*r1*/
166 154
 		if ((t & H1_H0_MASK)==0){        /*r2*/
167
-			DBG("timer_run: ticks %u, redist h2[%u]\n",
168
-							(unsigned ) t, (unsigned)( t>>(H0_BITS+H1_BITS)));
169 155
 			timer_redist(t, &timer_lst->h2[t>>(H0_BITS+H1_BITS)]);
170 156
 		}
171
-		DBG("timer_run: ticks %u, redist h1[%u]\n",
172
-						(unsigned ) t, (unsigned)((t & H1_H0_MASK)>>H0_BITS));
173 157
 		
174 158
 		timer_redist(t, &timer_lst->h1[(t & H1_H0_MASK)>>H0_BITS]);/*r2 >> H0*/
175 159
 	}
Browse code

New timer interface: - allows adding timers dynamically - supports one shot and periodic timers - precise - allows timeouts < 0.5 s (depends on the config., by default min. timeout = 62.5 ms) - based on a 3 level hierarchical timing wheel - very fast - low overhead for timer functions (most of the time, the excetion is timer_del which take can take quite a long time in special situations) - supports "slow" timers (compile option, by default on), "slow" timer = a timer handler which is declared as possible taking a long timer to execute. - backward compatible: old timer functions are preserverd => no changes needed for the existing code (although migration to the new interface is recommended) For more information read doc/timers.txt. tm timer update will follow shortly (this week).

Andrei Pelinescu-Onciul authored on 05/12/2005 18:29:30
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,229 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ *
5
+ * timer related functions (internal)
6
+ *
7
+ * Copyright (C) 2005 iptelorg GmbH
8
+ *
9
+ * This file is part of ser, a free SIP server.
10
+ *
11
+ * ser is free software; you can redistribute it and/or modify
12
+ * it under the terms of the GNU General Public License as published by
13
+ * the Free Software Foundation; either version 2 of the License, or
14
+ * (at your option) any later version
15
+ *
16
+ * For a license to use the ser software under conditions
17
+ * other than those described here, or to purchase support for this
18
+ * software, please contact iptel.org by e-mail at the following addresses:
19
+ *    info@iptel.org
20
+ *
21
+ * ser is distributed in the hope that it will be useful,
22
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
+ * GNU General Public License for more details.
25
+ *
26
+ * You should have received a copy of the GNU General Public License 
27
+ * along with this program; if not, write to the Free Software 
28
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29
+ */
30
+/* History:
31
+ * --------
32
+ *  2005-07-27  complete re-design/re-implemnetation (andrei)
33
+ */
34
+
35
+
36
+#ifndef timer_funcs_h
37
+#define timer_funcs_h
38
+
39
+#include "timer.h"
40
+
41
+
42
+struct timer_head{
43
+	struct timer_ln* volatile next;
44
+	struct timer_ln* volatile prev;
45
+};
46
+
47
+
48
+
49
+/* hierarchical timing wheel with 3 levels
50
+ * Most timeouts should go in the first "wheel" (h0)
51
+ * h0 will contain timers expiring from crt. time up to
52
+ * crt. time + (1<<H0_BITS)/TICKS_HZ s and will use
53
+ * (1<<H0_BITS)*sizeof(struct timer_head) bytes of memory, so arrange it
54
+ * accordingly
55
+ */
56
+
57
+#define H0_BITS 14
58
+#define H1_BITS  9 
59
+#define H2_BITS  (32-H1_BITS-H0_BITS)
60
+/* Uses ~280K on a 64 bits system and ~140K on a 32 bit system; for TICKS_HZ=10
61
+ * holds ~ 30 min in the first hash/wheel and ~233h in the first two.
62
+ * More perfomant arrangement: 16, 8, 8 (but eats 1 MB on a 64 bit system, and
63
+ *  512K on a 32 bit one). For TICKS_HZ=10 it holds almost 2h in the
64
+ *  first hash/wheel and ~460h in the first two.
65
+ */
66
+
67
+#define H0_ENTRIES (1<<H0_BITS)
68
+#define H1_ENTRIES (1<<H1_BITS)
69
+#define H2_ENTRIES (1<<H2_BITS)
70
+
71
+#define H0_MASK (H0_ENTRIES-1)
72
+#define H1_MASK (H1_ENTRIES-1)
73
+#define H1_H0_MASK ((1<<(H0_BITS+H1_BITS))-1)
74
+
75
+
76
+struct timer_lists{
77
+	struct timer_head  h0[H0_ENTRIES];
78
+	struct timer_head  h1[H1_ENTRIES];
79
+	struct timer_head  h2[H2_ENTRIES];
80
+	struct timer_head  expired; /* list of expired entries */
81
+};
82
+
83
+extern struct timer_lists* timer_lst;
84
+
85
+
86
+#define _timer_init_list(head)	clist_init((head), next, prev)
87
+
88
+
89
+#define _timer_add_list(head, tl) \
90
+	clist_append((head), (tl), next, prev)
91
+
92
+#define _timer_rm_list(tl) \
93
+	clist_rm((tl), next, prev)
94
+
95
+#define timer_foreach(tl, head)	clist_foreach((head), (tl), next)
96
+#define timer_foreach_safe(tl, tmp, head)	\
97
+	clist_foreach_safe((head), (tl), (tmp), next)
98
+
99
+
100
+
101
+
102
+/* generic add timer entry to the timer lists function (see _timer_add)
103
+ * tl->expire must be set previously, delta is the difference in ticks
104
+ * from current time to the timer desired expire (should be tl->expire-*tick)
105
+ * If you don't know delta, you probably want to call _timer_add instead.
106
+ */
107
+static inline int _timer_dist_tl(struct timer_ln* tl, ticks_t delta)
108
+{
109
+	if (delta<H0_ENTRIES){
110
+		if (delta==0){
111
+			LOG(L_WARN, "WARNING: timer: add_timeout: 0 expire timer added\n");
112
+			_timer_add_list(&timer_lst->expired, tl);
113
+		}else{
114
+			DBG("_timer_dist_tl: adding timer %p, delta %u,"
115
+					" expire %u @h0[%u]\n",
116
+				tl, (unsigned) delta, (unsigned) tl->expire,
117
+				(unsigned)(tl->expire & H0_MASK));
118
+			_timer_add_list( &timer_lst->h0[tl->expire & H0_MASK], tl);
119
+		}
120
+	}else if (delta<(H0_ENTRIES*H1_ENTRIES)){
121
+		DBG("_timer_dist_tl: adding timer %p, delta %u, expire %u @h1[%u]\n",
122
+				tl, (unsigned) delta, (unsigned) tl->expire,
123
+				(unsigned)((tl->expire & H1_H0_MASK)>>H0_BITS));
124
+		_timer_add_list(&timer_lst->h1[(tl->expire & H1_H0_MASK)>>H0_BITS],tl);
125
+	}else{
126
+		DBG("_timer_dist_tl: adding timer %p, delta %u, expire %u @h2[%u]\n",
127
+				tl, (unsigned) delta, (unsigned) tl->expire,
128
+				(unsigned)(tl->expire>>(H1_BITS+H0_BITS)));
129
+		_timer_add_list(&timer_lst->h2[tl->expire>>(H1_BITS+H0_BITS)], tl);
130
+	}
131
+	return 0;
132
+}
133
+
134
+
135
+
136
+#define _timer_mv_expire(h) \
137
+	do{ \
138
+		if ((h)->next!=(struct timer_ln*)(h)){ \
139
+			clist_append_sublist(&timer_lst->expired, (h)->next, \
140
+									(h)->prev, next, prev); \
141
+			_timer_init_list(h); \
142
+		} \
143
+	}while(0)
144
+
145
+
146
+#if 1
147
+
148
+static inline void timer_redist(ticks_t t, struct timer_head *h)
149
+{
150
+	struct timer_ln* tl;
151
+	struct timer_ln* tmp;
152
+	
153
+	DBG("timer_redist: list %p, ticks %lu\n", h, (unsigned long) t);
154
+	
155
+	timer_foreach_safe(tl, tmp, h){
156
+		_timer_dist_tl(tl, tl->expire-t);
157
+	}
158
+	/* clear the current list */
159
+	_timer_init_list(h);
160
+}
161
+
162
+static inline void timer_run(ticks_t t)
163
+{
164
+	/* trust the compiler for optimizing */
165
+	if ((t & H0_MASK)==0){              /*r1*/
166
+		if ((t & H1_H0_MASK)==0){        /*r2*/
167
+			DBG("timer_run: ticks %u, redist h2[%u]\n",
168
+							(unsigned ) t, (unsigned)( t>>(H0_BITS+H1_BITS)));
169
+			timer_redist(t, &timer_lst->h2[t>>(H0_BITS+H1_BITS)]);
170
+		}
171
+		DBG("timer_run: ticks %u, redist h1[%u]\n",
172
+						(unsigned ) t, (unsigned)((t & H1_H0_MASK)>>H0_BITS));
173
+		
174
+		timer_redist(t, &timer_lst->h1[(t & H1_H0_MASK)>>H0_BITS]);/*r2 >> H0*/
175
+	}
176
+	/*
177
+	DBG("timer_run: ticks %u, expire h0[%u]\n",
178
+						(unsigned ) t, (unsigned)(t & H0_MASK));*/
179
+	_timer_mv_expire(&timer_lst->h0[t & H0_MASK]);  /*r1*/
180
+}
181
+#else
182
+
183
+static inline void timer_lst_mv0(ticks_t t, struct timer_head* h)
184
+{
185
+	struct timer_ln* tl;
186
+	struct timer_ln* tmp;
187
+	
188
+	timer_foreach_safe(tl, tmp, h){
189
+			_timer_dist_tl(tl, &timer_lst->h0[tl->expire & H0_MASK]);
190
+	}
191
+	/* clear the current list */
192
+	_timer_init_list(h);
193
+}
194
+
195
+static inline void timer_lst_mv1(ticks_t t, struct timer_head* h)
196
+{
197
+	struct timer_ln* tl;
198
+	struct timer_ln* tmp;
199
+	
200
+	timer_foreach_safe(tl, tmp, h){
201
+		if ((tl->expire & H0_MASK)==0) /* directly to h0 */
202
+			_timer_add_list(tl, &timer_lst->h0[tl->expire & H0_MASK]);
203
+		else  /* to h1 */
204
+			_timer_add_list(tl, 
205
+						&timer_lst->h1[(tl->expire & H1_H0_MASK)>>H0_BITS]);
206
+	}
207
+	/* clear the current list */
208
+	_timer_init_list(h);
209
+}
210
+
211
+
212
+/* possible faster version */
213
+static inline void timer_run(ticks_t t)
214
+{
215
+	/* trust the compiler for optimizing */
216
+	if ((t & H0_MASK)==0){              /*r1*/
217
+		if ((t & H1_H0_MASK)==0)        /*r2*/
218
+			/* just move the list "down" to hash1 */
219
+			timer_lst_mv1(&timer_lst->h2[t>>(H0_BITS+H1_BITS)]); 
220
+		/* move "down" to hash0 */
221
+		timer_lst_mv0(&timer_lst->h1[(t & H1_H0_MASK)>>H0_BITS]);
222
+	}
223
+	_timer_mv_expire(t, &timer_lst->h0[t & H0_MASK]);  /*r1*/
224
+}
225
+#endif
226
+
227
+
228
+
229
+#endif