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,257 +0,0 @@
1
-/*
2
- * Copyright (C) 2007 iptelorg GmbH
3
- *
4
- * This file is part of Kamailio, a free SIP server.
5
- *
6
- * Kamailio is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version
10
- *
11
- * Kamailio is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License 
17
- * along with this program; if not, write to the Free Software 
18
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19
- */
20
-
21
-/*!
22
- * \file
23
- * \brief Kamailio core :: local, per process timer routines
24
- * WARNING: this should be used only within the same process, the timers
25
- *  are not multi-process safe or multi-thread safe
26
- *  (there are no locks)
27
- * \ingroup core
28
- * Module: \ref core
29
- */
30
-
31
-
32
-#include "timer.h"
33
-#include "timer_funcs.h"
34
-#include "dprint.h"
35
-#include "tcp_conn.h"
36
-#include "mem/mem.h"
37
-#include "compiler_opt.h"
38
-
39
-#include "local_timer.h"
40
-
41
-
42
-
43
-/** init a local_timer handle
44
- * returns 0 on success, -1 on error */
45
-int init_local_timer(struct local_timer *t, ticks_t crt_ticks)
46
-{
47
-	int r;
48
-	
49
-	/* initial values */
50
-	memset(t, 0, sizeof(*t));
51
-	t->prev_ticks=crt_ticks;
52
-	/* init timer structures */
53
-	for (r=0; r<H0_ENTRIES; r++)
54
-		_timer_init_list(&t->timer_lst.h0[r]);
55
-	for (r=0; r<H1_ENTRIES; r++)
56
-		_timer_init_list(&t->timer_lst.h1[r]);
57
-	for (r=0; r<H2_ENTRIES; r++)
58
-		_timer_init_list(&t->timer_lst.h2[r]);
59
-	_timer_init_list(&t->timer_lst.expired);
60
-	LM_DBG("timer_list between %p and %p\n",
61
-			&t->timer_lst.h0[0], &t->timer_lst.h2[H2_ENTRIES]);
62
-	return 0;
63
-}
64
-
65
-
66
-
67
-void destroy_local_timer(struct local_timer* lt)
68
-{
69
-}
70
-
71
-
72
-
73
-/** generic add timer entry to the timer lists function (see _timer_add)
74
- * tl->expire must be set previously, delta is the difference in ticks
75
- * from current time to the timer desired expire (should be tl->expire-*tick)
76
- * If you don't know delta, you probably want to call _timer_add instead.
77
- */
78
-static inline int _local_timer_dist_tl(struct local_timer* h, 
79
-										struct timer_ln* tl, ticks_t delta)
80
-{
81
-	if (likely(delta<H0_ENTRIES)){
82
-		if (unlikely(delta==0)){
83
-			LM_WARN("0 expire timer added\n");
84
-			_timer_add_list(&h->timer_lst.expired, tl);
85
-		}else{
86
-			_timer_add_list( &h->timer_lst.h0[tl->expire & H0_MASK], tl);
87
-		}
88
-	}else if (likely(delta<(H0_ENTRIES*H1_ENTRIES))){
89
-		_timer_add_list(&h->timer_lst.h1[(tl->expire & H1_H0_MASK)>>H0_BITS],
90
-							tl);
91
-	}else{
92
-		_timer_add_list(&h->timer_lst.h2[tl->expire>>(H1_BITS+H0_BITS)], tl);
93
-	}
94
-	return 0;
95
-}
96
-
97
-
98
-
99
-static inline void local_timer_redist(struct local_timer* l,
100
-										ticks_t t, struct timer_head *h)
101
-{
102
-	struct timer_ln* tl;
103
-	struct timer_ln* tmp;
104
-	
105
-	timer_foreach_safe(tl, tmp, h){
106
-		_local_timer_dist_tl(l, tl, tl->expire-t);
107
-	}
108
-	/* clear the current list */
109
-	_timer_init_list(h);
110
-}
111
-
112
-
113
-
114
-/** local timer add function (no lock, not multithread or multiprocess safe,
115
- * designed for local process use only)
116
- * t = current ticks
117
- * tl must be filled (the intial_timeout and flags must be set)
118
- * returns -1 on error, 0 on success */
119
-static inline int _local_timer_add(struct local_timer *h, ticks_t t,
120
-									struct timer_ln* tl)
121
-{
122
-	ticks_t delta;
123
-	
124
-	delta=tl->initial_timeout;
125
-	tl->expire=t+delta;
126
-	return _local_timer_dist_tl(h, tl, delta);
127
-}
128
-
129
-
130
-
131
-/** "public", safe timer add functions (local process use only)
132
- * adds a timer at delta ticks from the current time
133
- * returns -1 on error, 0 on success
134
- * WARNING: to re-add a deleted or expired timer you must call
135
- *          timer_reinit(tl) prior to timer_add
136
- *          The default behaviour allows timer_add to add a timer only if it
137
- *          has never been added before.*/
138
-int local_timer_add(struct local_timer* h, struct timer_ln* tl, ticks_t delta,
139
-						ticks_t crt_ticks)
140
-{
141
-	int ret;
142
-	
143
-	if (unlikely(tl->flags & F_TIMER_ACTIVE)){
144
-		LM_DBG("called on an active timer %p (%p, %p), flags %x\n",
145
-				tl, tl->next, tl->prev, tl->flags);
146
-		ret=-1; /* refusing to add active or non-reinit. timer */
147
-		goto error;
148
-	}
149
-	tl->initial_timeout=delta;
150
-	if (unlikely((tl->next!=0) || (tl->prev!=0))){
151
-		LM_CRIT("called with linked timer: %p (%p, %p)\n", tl, tl->next, tl->prev);
152
-		ret=-1;
153
-		goto error;
154
-	}
155
-	tl->flags|=F_TIMER_ACTIVE;
156
-	ret=_local_timer_add(h, crt_ticks, tl);
157
-error:
158
-	return ret;
159
-}
160
-
161
-
162
-
163
-/** safe timer delete
164
- * deletes tl and inits the list pointer to 0
165
- * WARNING: to be able to reuse a deleted timer you must call
166
- *          timer_reinit(tl) on it
167
- * 
168
- */
169
-void local_timer_del(struct local_timer* h, struct timer_ln* tl)
170
-{
171
-	/* quick exit if timer inactive */
172
-	if (unlikely(!(tl->flags & F_TIMER_ACTIVE))){
173
-		LM_DBG("called on an inactive timer %p (%p, %p), flags %x\n",
174
-				tl, tl->next, tl->prev, tl->flags);
175
-		return;
176
-	}
177
-	if (likely((tl->next!=0)&&(tl->prev!=0))){
178
-		_timer_rm_list(tl); /* detach */
179
-		tl->next=tl->prev=0;
180
-	}else{
181
-		LM_DBG("(f) timer %p (%p, %p) flags %x already detached\n",
182
-			tl, tl->next, tl->prev, tl->flags);
183
-	}
184
-}
185
-
186
-
187
-
188
-/** called from timer_handle*/
189
-inline static void local_timer_list_expire(struct local_timer* l, 
190
-											ticks_t t, struct timer_head* h)
191
-{
192
-	struct timer_ln * tl;
193
-	ticks_t ret;
194
-	
195
-	/*LM_DBG("@ ticks = %lu, list =%p\n", (unsigned long) *ticks, h); */
196
-	while(h->next!=(struct timer_ln*)h){
197
-		tl=h->next;
198
-		_timer_rm_list(tl); /* detach */
199
-			tl->next=tl->prev=0; /* debugging */
200
-				/*FIXME: process tcpconn */
201
-				ret=tl->f(t, tl, tl->data);
202
-				if (ret!=0){
203
-					/* not one-shot, re-add it */
204
-					if (ret!=(ticks_t)-1) /* ! periodic */
205
-						tl->initial_timeout=ret;
206
-					_local_timer_add(l, t, tl);
207
-				}
208
-	}
209
-}
210
-
211
-
212
-
213
-/** run all the handler that expire at t ticks */
214
-static inline void local_timer_expire(struct local_timer* h, ticks_t t)
215
-{
216
-	/* trust the compiler for optimizing */
217
-	if (unlikely((t & H0_MASK)==0)){              /*r1*/
218
-		if (unlikely((t & H1_H0_MASK)==0)){        /*r2*/
219
-			local_timer_redist(h, t, &h->timer_lst.h2[t>>(H0_BITS+H1_BITS)]);
220
-		}
221
-		
222
-		local_timer_redist(h, t, &h->timer_lst.h1[(t & H1_H0_MASK)>>H0_BITS]);
223
-															/*r2 >> H0*/
224
-	}
225
-	/* run handler immediately, no need to move it to the expired list
226
-	 * (since no locks are used) */
227
-	local_timer_list_expire(h, t, &h->timer_lst.h0[t & H0_MASK]);
228
-}
229
-
230
-
231
-
232
-/** "main" local timer routine, should be called with a proper ticks value
233
- * WARNING: it should never be called twice for the same ticks value
234
- * (it could cause too fast expires for long timers), ticks must be also
235
- *  always increasing */
236
-void local_timer_run(struct local_timer* lt, ticks_t saved_ticks)
237
-{
238
-	
239
-		/* protect against time running backwards */
240
-		if (unlikely(lt->prev_ticks>=saved_ticks)){
241
-			LM_CRIT("backwards or still time\n");
242
-			/* try to continue */
243
-			lt->prev_ticks=saved_ticks-1;
244
-			return;
245
-		}
246
-		/* go through all the "missed" ticks, taking a possible overflow
247
-		 * into account */
248
-		for (lt->prev_ticks=lt->prev_ticks+1; lt->prev_ticks!=saved_ticks; 
249
-															lt->prev_ticks++)
250
-			local_timer_expire(lt, lt->prev_ticks);
251
-		local_timer_expire(lt, lt->prev_ticks); /* do it for saved_ticks too */
252
-	local_timer_list_expire(lt, saved_ticks, &lt->timer_lst.expired);
253
-	/* WARNING: add_timer(...,0) must go directly to expired list, since
254
-	 * otherwise there is a race between timer running and adding it
255
-	 * (it could expire it H0_ENTRIES ticks later instead of 'now')*/
256
-}
257
-
Browse code

local_timer.c: logging: DBG -> LM_DBG

Ovidiu Sas authored on 13/01/2015 17:47:03
Showing 1 changed files
... ...
@@ -57,7 +57,7 @@ int init_local_timer(struct local_timer *t, ticks_t crt_ticks)
57 57
 	for (r=0; r<H2_ENTRIES; r++)
58 58
 		_timer_init_list(&t->timer_lst.h2[r]);
59 59
 	_timer_init_list(&t->timer_lst.expired);
60
-	DBG("init_local_timer: timer_list between %p and %p\n",
60
+	LM_DBG("timer_list between %p and %p\n",
61 61
 			&t->timer_lst.h0[0], &t->timer_lst.h2[H2_ENTRIES]);
62 62
 	return 0;
63 63
 }
... ...
@@ -141,8 +141,8 @@ int local_timer_add(struct local_timer* h, struct timer_ln* tl, ticks_t delta,
141 141
 	int ret;
142 142
 	
143 143
 	if (unlikely(tl->flags & F_TIMER_ACTIVE)){
144
-		DBG("timer_add called on an active timer %p (%p, %p),"
145
-					" flags %x\n", tl, tl->next, tl->prev, tl->flags);
144
+		LM_DBG("called on an active timer %p (%p, %p), flags %x\n",
145
+				tl, tl->next, tl->prev, tl->flags);
146 146
 		ret=-1; /* refusing to add active or non-reinit. timer */
147 147
 		goto error;
148 148
 	}
... ...
@@ -170,16 +170,15 @@ void local_timer_del(struct local_timer* h, struct timer_ln* tl)
170 170
 {
171 171
 	/* quick exit if timer inactive */
172 172
 	if (unlikely(!(tl->flags & F_TIMER_ACTIVE))){
173
-		DBG("timer_del called on an inactive timer %p (%p, %p),"
174
-					" flags %x\n", tl, tl->next, tl->prev, tl->flags);
173
+		LM_DBG("called on an inactive timer %p (%p, %p), flags %x\n",
174
+				tl, tl->next, tl->prev, tl->flags);
175 175
 		return;
176 176
 	}
177 177
 	if (likely((tl->next!=0)&&(tl->prev!=0))){
178 178
 		_timer_rm_list(tl); /* detach */
179 179
 		tl->next=tl->prev=0;
180 180
 	}else{
181
-		DBG("timer_del: (f) timer %p (%p, %p) flags %x "
182
-			"already detached\n",
181
+		LM_DBG("(f) timer %p (%p, %p) flags %x already detached\n",
183 182
 			tl, tl->next, tl->prev, tl->flags);
184 183
 	}
185 184
 }
... ...
@@ -193,9 +192,7 @@ inline static void local_timer_list_expire(struct local_timer* l,
193 192
 	struct timer_ln * tl;
194 193
 	ticks_t ret;
195 194
 	
196
-	/*DBG("timer_list_expire @ ticks = %lu, list =%p\n",
197
-			(unsigned long) *ticks, h);
198
-	*/
195
+	/*LM_DBG("@ ticks = %lu, list =%p\n", (unsigned long) *ticks, h); */
199 196
 	while(h->next!=(struct timer_ln*)h){
200 197
 		tl=h->next;
201 198
 		_timer_rm_list(tl); /* detach */
Browse code

core Update headers, change "SIP-router" to "Kamailio", update doxygen file headers

Olle E. Johansson authored on 03/01/2015 14:15:58
Showing 1 changed files
... ...
@@ -8,11 +8,6 @@
8 8
  * the Free Software Foundation; either version 2 of the License, or
9 9
  * (at your option) any later version
10 10
  *
11
- * For a license to use the ser software under conditions
12
- * other than those described here, or to purchase support for this
13
- * software, please contact iptel.org by e-mail at the following addresses:
14
- *    info@iptel.org
15
- *
16 11
  * Kamailio is distributed in the hope that it will be useful,
17 12
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 13
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Browse code

Core Removed history, svn $id$ and doxygen udpates on the .c files

Olle E. Johansson authored on 03/01/2015 09:53:17
Showing 1 changed files
... ...
@@ -1,11 +1,9 @@
1 1
 /*
2
- * $Id$
3
- *
4 2
  * Copyright (C) 2007 iptelorg GmbH
5 3
  *
6
- * This file is part of ser, a free SIP server.
4
+ * This file is part of Kamailio, a free SIP server.
7 5
  *
8
- * ser is free software; you can redistribute it and/or modify
6
+ * Kamailio is free software; you can redistribute it and/or modify
9 7
  * it under the terms of the GNU General Public License as published by
10 8
  * the Free Software Foundation; either version 2 of the License, or
11 9
  * (at your option) any later version
... ...
@@ -15,7 +13,7 @@
15 13
  * software, please contact iptel.org by e-mail at the following addresses:
16 14
  *    info@iptel.org
17 15
  *
18
- * ser is distributed in the hope that it will be useful,
16
+ * Kamailio is distributed in the hope that it will be useful,
19 17
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 18
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 19
  * GNU General Public License for more details.
... ...
@@ -24,19 +22,13 @@
24 22
  * along with this program; if not, write to the Free Software 
25 23
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
26 24
  */
27
-/* local, per process timer routines
28
- * WARNING: this should be used only within the same process, the timers
29
- *  are not multi-process safe or multi-thread safe
30
- *  (there are no locks)
31
- *
32
- * History:
33
- * --------
34
- *  2006-02-03  created by andrei
35
- */
36 25
 
37 26
 /*!
38 27
  * \file
39
- * \brief SIP-router core :: 
28
+ * \brief Kamailio core :: local, per process timer routines
29
+ * WARNING: this should be used only within the same process, the timers
30
+ *  are not multi-process safe or multi-thread safe
31
+ *  (there are no locks)
40 32
  * \ingroup core
41 33
  * Module: \ref core
42 34
  */
... ...
@@ -53,7 +45,7 @@
53 45
 
54 46
 
55 47
 
56
-/* init a local_timer handle
48
+/** init a local_timer handle
57 49
  * returns 0 on success, -1 on error */
58 50
 int init_local_timer(struct local_timer *t, ticks_t crt_ticks)
59 51
 {
... ...
@@ -83,7 +75,7 @@ void destroy_local_timer(struct local_timer* lt)
83 75
 
84 76
 
85 77
 
86
-/* generic add timer entry to the timer lists function (see _timer_add)
78
+/** generic add timer entry to the timer lists function (see _timer_add)
87 79
  * tl->expire must be set previously, delta is the difference in ticks
88 80
  * from current time to the timer desired expire (should be tl->expire-*tick)
89 81
  * If you don't know delta, you probably want to call _timer_add instead.
... ...
@@ -124,7 +116,7 @@ static inline void local_timer_redist(struct local_timer* l,
124 116
 
125 117
 
126 118
 
127
-/* local timer add function (no lock, not multithread or multiprocess safe,
119
+/** local timer add function (no lock, not multithread or multiprocess safe,
128 120
  * designed for local process use only)
129 121
  * t = current ticks
130 122
  * tl must be filled (the intial_timeout and flags must be set)
... ...
@@ -141,7 +133,7 @@ static inline int _local_timer_add(struct local_timer *h, ticks_t t,
141 133
 
142 134
 
143 135
 
144
-/* "public", safe timer add functions (local process use only)
136
+/** "public", safe timer add functions (local process use only)
145 137
  * adds a timer at delta ticks from the current time
146 138
  * returns -1 on error, 0 on success
147 139
  * WARNING: to re-add a deleted or expired timer you must call
... ...
@@ -173,7 +165,7 @@ error:
173 165
 
174 166
 
175 167
 
176
-/* safe timer delete
168
+/** safe timer delete
177 169
  * deletes tl and inits the list pointer to 0
178 170
  * WARNING: to be able to reuse a deleted timer you must call
179 171
  *          timer_reinit(tl) on it
... ...
@@ -199,7 +191,7 @@ void local_timer_del(struct local_timer* h, struct timer_ln* tl)
199 191
 
200 192
 
201 193
 
202
-/* called from timer_handle*/
194
+/** called from timer_handle*/
203 195
 inline static void local_timer_list_expire(struct local_timer* l, 
204 196
 											ticks_t t, struct timer_head* h)
205 197
 {
... ...
@@ -226,7 +218,7 @@ inline static void local_timer_list_expire(struct local_timer* l,
226 218
 
227 219
 
228 220
 
229
-/* run all the handler that expire at t ticks */
221
+/** run all the handler that expire at t ticks */
230 222
 static inline void local_timer_expire(struct local_timer* h, ticks_t t)
231 223
 {
232 224
 	/* trust the compiler for optimizing */
... ...
@@ -245,7 +237,7 @@ static inline void local_timer_expire(struct local_timer* h, ticks_t t)
245 237
 
246 238
 
247 239
 
248
-/* "main" local timer routine, should be called with a proper ticks value
240
+/** "main" local timer routine, should be called with a proper ticks value
249 241
  * WARNING: it should never be called twice for the same ticks value
250 242
  * (it could cause too fast expires for long timers), ticks must be also
251 243
  *  always increasing */
Browse code

local_timer.c: logging: convert LOG to LM_*

Ovidiu Sas authored on 03/10/2014 20:36:35
Showing 1 changed files
... ...
@@ -93,8 +93,7 @@ static inline int _local_timer_dist_tl(struct local_timer* h,
93 93
 {
94 94
 	if (likely(delta<H0_ENTRIES)){
95 95
 		if (unlikely(delta==0)){
96
-			LOG(L_WARN, "WARNING: local_timer: add_timeout: 0 expire timer"
97
-						" added\n");
96
+			LM_WARN("0 expire timer added\n");
98 97
 			_timer_add_list(&h->timer_lst.expired, tl);
99 98
 		}else{
100 99
 			_timer_add_list( &h->timer_lst.h0[tl->expire & H0_MASK], tl);
... ...
@@ -162,8 +161,7 @@ int local_timer_add(struct local_timer* h, struct timer_ln* tl, ticks_t delta,
162 161
 	}
163 162
 	tl->initial_timeout=delta;
164 163
 	if (unlikely((tl->next!=0) || (tl->prev!=0))){
165
-		LOG(L_CRIT, "BUG: tcp_timer_add: called with linked timer:"
166
-				" %p (%p, %p)\n", tl, tl->next, tl->prev);
164
+		LM_CRIT("called with linked timer: %p (%p, %p)\n", tl, tl->next, tl->prev);
167 165
 		ret=-1;
168 166
 		goto error;
169 167
 	}
... ...
@@ -256,7 +254,7 @@ void local_timer_run(struct local_timer* lt, ticks_t saved_ticks)
256 254
 	
257 255
 		/* protect against time running backwards */
258 256
 		if (unlikely(lt->prev_ticks>=saved_ticks)){
259
-			LOG(L_CRIT, "BUG: local_timer: backwards or still time\n");
257
+			LM_CRIT("backwards or still time\n");
260 258
 			/* try to continue */
261 259
 			lt->prev_ticks=saved_ticks-1;
262 260
 			return;
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
... ...
@@ -22,7 +22,7 @@
22 22
  *
23 23
  * You should have received a copy of the GNU General Public License 
24 24
  * along with this program; if not, write to the Free Software 
25
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
26 26
  */
27 27
 /* local, per process timer routines
28 28
  * WARNING: this should be used only within the same process, the timers
Browse code

Adding doxygen template to all core .c files

Please fill in after the :: to explain the function of this file.

oej authored on 10/10/2009 13:54:13
Showing 1 changed files
... ...
@@ -34,6 +34,13 @@
34 34
  *  2006-02-03  created by andrei
35 35
  */
36 36
 
37
+/*!
38
+ * \file
39
+ * \brief SIP-router core :: 
40
+ * \ingroup core
41
+ * Module: \ref core
42
+ */
43
+
37 44
 
38 45
 #include "timer.h"
39 46
 #include "timer_funcs.h"
Browse code

- local per process timer support (optimized "main" timer version that works only inside one process). Several independent timers can be run in the same time (if intialized with different handles). They'll be used for the tcp connection timeout handling (near future).

Andrei Pelinescu-Onciul authored on 22/11/2007 13:43:09
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,268 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2007 iptelorg GmbH
5
+ *
6
+ * This file is part of ser, a free SIP server.
7
+ *
8
+ * ser 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
+ * For a license to use the ser software under conditions
14
+ * other than those described here, or to purchase support for this
15
+ * software, please contact iptel.org by e-mail at the following addresses:
16
+ *    info@iptel.org
17
+ *
18
+ * ser is distributed in the hope that it will be useful,
19
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
+ * GNU General Public License for more details.
22
+ *
23
+ * You should have received a copy of the GNU General Public License 
24
+ * along with this program; if not, write to the Free Software 
25
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
+ */
27
+/* local, per process timer routines
28
+ * WARNING: this should be used only within the same process, the timers
29
+ *  are not multi-process safe or multi-thread safe
30
+ *  (there are no locks)
31
+ *
32
+ * History:
33
+ * --------
34
+ *  2006-02-03  created by andrei
35
+ */
36
+
37
+
38
+#include "timer.h"
39
+#include "timer_funcs.h"
40
+#include "dprint.h"
41
+#include "tcp_conn.h"
42
+#include "mem/mem.h"
43
+#include "compiler_opt.h"
44
+
45
+#include "local_timer.h"
46
+
47
+
48
+
49
+/* init a local_timer handle
50
+ * returns 0 on success, -1 on error */
51
+int init_local_timer(struct local_timer *t, ticks_t crt_ticks)
52
+{
53
+	int r;
54
+	
55
+	/* initial values */
56
+	memset(t, 0, sizeof(*t));
57
+	t->prev_ticks=crt_ticks;
58
+	/* init timer structures */
59
+	for (r=0; r<H0_ENTRIES; r++)
60
+		_timer_init_list(&t->timer_lst.h0[r]);
61
+	for (r=0; r<H1_ENTRIES; r++)
62
+		_timer_init_list(&t->timer_lst.h1[r]);
63
+	for (r=0; r<H2_ENTRIES; r++)
64
+		_timer_init_list(&t->timer_lst.h2[r]);
65
+	_timer_init_list(&t->timer_lst.expired);
66
+	DBG("init_local_timer: timer_list between %p and %p\n",
67
+			&t->timer_lst.h0[0], &t->timer_lst.h2[H2_ENTRIES]);
68
+	return 0;
69
+}
70
+
71
+
72
+
73
+void destroy_local_timer(struct local_timer* lt)
74
+{
75
+}
76
+
77
+
78
+
79
+/* generic add timer entry to the timer lists function (see _timer_add)
80
+ * tl->expire must be set previously, delta is the difference in ticks
81
+ * from current time to the timer desired expire (should be tl->expire-*tick)
82
+ * If you don't know delta, you probably want to call _timer_add instead.
83
+ */
84
+static inline int _local_timer_dist_tl(struct local_timer* h, 
85
+										struct timer_ln* tl, ticks_t delta)
86
+{
87
+	if (likely(delta<H0_ENTRIES)){
88
+		if (unlikely(delta==0)){
89
+			LOG(L_WARN, "WARNING: local_timer: add_timeout: 0 expire timer"
90
+						" added\n");
91
+			_timer_add_list(&h->timer_lst.expired, tl);
92
+		}else{
93
+			_timer_add_list( &h->timer_lst.h0[tl->expire & H0_MASK], tl);
94
+		}
95
+	}else if (likely(delta<(H0_ENTRIES*H1_ENTRIES))){
96
+		_timer_add_list(&h->timer_lst.h1[(tl->expire & H1_H0_MASK)>>H0_BITS],
97
+							tl);
98
+	}else{
99
+		_timer_add_list(&h->timer_lst.h2[tl->expire>>(H1_BITS+H0_BITS)], tl);
100
+	}
101
+	return 0;
102
+}
103
+
104
+
105
+
106
+static inline void local_timer_redist(struct local_timer* l,
107
+										ticks_t t, struct timer_head *h)
108
+{
109
+	struct timer_ln* tl;
110
+	struct timer_ln* tmp;
111
+	
112
+	timer_foreach_safe(tl, tmp, h){
113
+		_local_timer_dist_tl(l, tl, tl->expire-t);
114
+	}
115
+	/* clear the current list */
116
+	_timer_init_list(h);
117
+}
118
+
119
+
120
+
121
+/* local timer add function (no lock, not multithread or multiprocess safe,
122
+ * designed for local process use only)
123
+ * t = current ticks
124
+ * tl must be filled (the intial_timeout and flags must be set)
125
+ * returns -1 on error, 0 on success */
126
+static inline int _local_timer_add(struct local_timer *h, ticks_t t,
127
+									struct timer_ln* tl)
128
+{
129
+	ticks_t delta;
130
+	
131
+	delta=tl->initial_timeout;
132
+	tl->expire=t+delta;
133
+	return _local_timer_dist_tl(h, tl, delta);
134
+}
135
+
136
+
137
+
138
+/* "public", safe timer add functions (local process use only)
139
+ * adds a timer at delta ticks from the current time
140
+ * returns -1 on error, 0 on success
141
+ * WARNING: to re-add a deleted or expired timer you must call
142
+ *          timer_reinit(tl) prior to timer_add
143
+ *          The default behaviour allows timer_add to add a timer only if it
144
+ *          has never been added before.*/
145
+int local_timer_add(struct local_timer* h, struct timer_ln* tl, ticks_t delta,
146
+						ticks_t crt_ticks)
147
+{
148
+	int ret;
149
+	
150
+	if (unlikely(tl->flags & F_TIMER_ACTIVE)){
151
+		DBG("timer_add called on an active timer %p (%p, %p),"
152
+					" flags %x\n", tl, tl->next, tl->prev, tl->flags);
153
+		ret=-1; /* refusing to add active or non-reinit. timer */
154
+		goto error;
155
+	}
156
+	tl->initial_timeout=delta;
157
+	if (unlikely((tl->next!=0) || (tl->prev!=0))){
158
+		LOG(L_CRIT, "BUG: tcp_timer_add: called with linked timer:"
159
+				" %p (%p, %p)\n", tl, tl->next, tl->prev);
160
+		ret=-1;
161
+		goto error;
162
+	}
163
+	tl->flags|=F_TIMER_ACTIVE;
164
+	ret=_local_timer_add(h, crt_ticks, tl);
165
+error:
166
+	return ret;
167
+}
168
+
169
+
170
+
171
+/* safe timer delete
172
+ * deletes tl and inits the list pointer to 0
173
+ * WARNING: to be able to reuse a deleted timer you must call
174
+ *          timer_reinit(tl) on it
175
+ * 
176
+ */
177
+void local_timer_del(struct local_timer* h, struct timer_ln* tl)
178
+{
179
+	/* quick exit if timer inactive */
180
+	if (unlikely(!(tl->flags & F_TIMER_ACTIVE))){
181
+		DBG("timer_del called on an inactive timer %p (%p, %p),"
182
+					" flags %x\n", tl, tl->next, tl->prev, tl->flags);
183
+		return;
184
+	}
185
+	if (likely((tl->next!=0)&&(tl->prev!=0))){
186
+		_timer_rm_list(tl); /* detach */
187
+		tl->next=tl->prev=0;
188
+	}else{
189
+		DBG("timer_del: (f) timer %p (%p, %p) flags %x "
190
+			"already detached\n",
191
+			tl, tl->next, tl->prev, tl->flags);
192
+	}
193
+}
194
+
195
+
196
+
197
+/* called from timer_handle*/
198
+inline static void local_timer_list_expire(struct local_timer* l, 
199
+											ticks_t t, struct timer_head* h)
200
+{
201
+	struct timer_ln * tl;
202
+	ticks_t ret;
203
+	
204
+	/*DBG("timer_list_expire @ ticks = %lu, list =%p\n",
205
+			(unsigned long) *ticks, h);
206
+	*/
207
+	while(h->next!=(struct timer_ln*)h){
208
+		tl=h->next;
209
+		_timer_rm_list(tl); /* detach */
210
+			tl->next=tl->prev=0; /* debugging */
211
+				/*FIXME: process tcpconn */
212
+				ret=tl->f(t, tl, tl->data);
213
+				if (ret!=0){
214
+					/* not one-shot, re-add it */
215
+					if (ret!=(ticks_t)-1) /* ! periodic */
216
+						tl->initial_timeout=ret;
217
+					_local_timer_add(l, t, tl);
218
+				}
219
+	}
220
+}
221
+
222
+
223
+
224
+/* run all the handler that expire at t ticks */
225
+static inline void local_timer_expire(struct local_timer* h, ticks_t t)
226
+{
227
+	/* trust the compiler for optimizing */
228
+	if (unlikely((t & H0_MASK)==0)){              /*r1*/
229
+		if (unlikely((t & H1_H0_MASK)==0)){        /*r2*/
230
+			local_timer_redist(h, t, &h->timer_lst.h2[t>>(H0_BITS+H1_BITS)]);
231
+		}
232
+		
233
+		local_timer_redist(h, t, &h->timer_lst.h1[(t & H1_H0_MASK)>>H0_BITS]);
234
+															/*r2 >> H0*/
235
+	}
236
+	/* run handler immediately, no need to move it to the expired list
237
+	 * (since no locks are used) */
238
+	local_timer_list_expire(h, t, &h->timer_lst.h0[t & H0_MASK]);
239
+}
240
+
241
+
242
+
243
+/* "main" local timer routine, should be called with a proper ticks value
244
+ * WARNING: it should never be called twice for the same ticks value
245
+ * (it could cause too fast expires for long timers), ticks must be also
246
+ *  always increasing */
247
+void local_timer_run(struct local_timer* lt, ticks_t saved_ticks)
248
+{
249
+	
250
+		/* protect against time running backwards */
251
+		if (unlikely(lt->prev_ticks>=saved_ticks)){
252
+			LOG(L_CRIT, "BUG: local_timer: backwards or still time\n");
253
+			/* try to continue */
254
+			lt->prev_ticks=saved_ticks-1;
255
+			return;
256
+		}
257
+		/* go through all the "missed" ticks, taking a possible overflow
258
+		 * into account */
259
+		for (lt->prev_ticks=lt->prev_ticks+1; lt->prev_ticks!=saved_ticks; 
260
+															lt->prev_ticks++)
261
+			local_timer_expire(lt, lt->prev_ticks);
262
+		local_timer_expire(lt, lt->prev_ticks); /* do it for saved_ticks too */
263
+	local_timer_list_expire(lt, saved_ticks, &lt->timer_lst.expired);
264
+	/* WARNING: add_timer(...,0) must go directly to expired list, since
265
+	 * otherwise there is a race between timer running and adding it
266
+	 * (it could expire it H0_ENTRIES ticks later instead of 'now')*/
267
+}
268
+