Browse code

core: wheel timer implementation

- to be shared by modules needing to execute timer tasks, don't want to
interfere with main core timers, but don't do lots of operations to
create own timer

Daniel-Constantin Mierla authored on 21/01/2016 13:17:37
Showing 2 changed files
... ...
@@ -278,4 +278,116 @@ int fork_sync_utimer(int child_id, char* desc, int make_sock,
278 278
 }
279 279
 
280 280
 
281
+#define SR_WTIMER_SIZE	16
282
+
283
+typedef struct sr_wtimer_node {
284
+	struct sr_wtimer_node *next;
285
+	uint32_t interval;
286
+	uint32_t steps;
287
+	uint32_t cycles;
288
+	timer_function* f;
289
+	void* param;
290
+} sr_wtimer_node_t;
291
+
292
+typedef struct sr_wtimer {
293
+	uint32_t itimer;
294
+	sr_wtimer_node_t *wlist[SR_WTIMER_SIZE];
295
+} sr_wtimer_t;
296
+
297
+static sr_wtimer_t *_sr_wtimer = NULL;;
298
+
299
+/**
300
+ *
301
+ */
302
+int sr_wtimer_init(void)
303
+{
304
+	if(_sr_wtimer!=NULL)
305
+		return 0;
306
+	_sr_wtimer = (sr_wtimer_t *)pkg_malloc(sizeof(sr_wtimer_t));
307
+	if(_sr_wtimer!=NULL) {
308
+		LM_ERR("no more pkg memory\n");
309
+		return -1;
310
+	}
311
+
312
+	memset(_sr_wtimer, 0, sizeof(sr_wtimer_t));
313
+	register_sync_timers(1);
314
+	return 0;
315
+}
316
+
317
+/**
318
+ *
319
+ */
320
+int sr_wtimer_add(timer_function* f, void* param, int interval)
321
+{
322
+	sr_wtimer_node_t *wt;
323
+	if(_sr_wtimer!=NULL) {
324
+		LM_ERR("wtimer not intialized\n");
325
+		return -1;
326
+	}
327
+
328
+	wt = (sr_wtimer_node_t*)pkg_malloc(sizeof(sr_wtimer_node_t));
329
+	if(wt==NULL) {
330
+		LM_ERR("no more pkg memory\n");
331
+		return -1;
332
+	}
333
+	memset(wt, 0, sizeof(sr_wtimer_node_t));
334
+	wt->f = f;
335
+	wt->param = param;
336
+	wt->interval = interval;
337
+	wt->steps = interval % SR_WTIMER_SIZE;
338
+	wt->cycles = interval / SR_WTIMER_SIZE;
339
+	wt->next = _sr_wtimer->wlist[wt->steps];
340
+	_sr_wtimer->wlist[wt->steps] = wt;
341
+
342
+	return 0;
343
+}
344
+
345
+/**
346
+ *
347
+ */
348
+void sr_wtimer_exec(unsigned int ticks, void *param)
349
+{
350
+	sr_wtimer_node_t *wt;
351
+	uint32_t i;
352
+	uint32_t c;
353
+
354
+	if(_sr_wtimer!=NULL) {
355
+		LM_ERR("wtimer not intialized\n");
356
+		return;
357
+	}
358
+
359
+	_sr_wtimer->itimer++;
360
+	c = _sr_wtimer->itimer / SR_WTIMER_SIZE;
361
+
362
+	for(i=1; i<=SR_WTIMER_SIZE; i++) {
363
+		if(_sr_wtimer->itimer % i == 0) {
364
+			for(wt=_sr_wtimer->wlist[i % SR_WTIMER_SIZE];
365
+					wt!=NULL; wt = wt->next) {
366
+				if(wt->cycles==0 || (c % wt->cycles==0)) {
367
+					wt->f(ticks, wt->param);
368
+				}
369
+			}
370
+		}
371
+	}
372
+}
373
+
374
+/**
375
+ *
376
+ */
377
+int sr_wtimer_start(void)
378
+{
379
+	if(_sr_wtimer!=NULL) {
380
+		LM_ERR("wtimer not intialized\n");
381
+		return -1;
382
+	}
383
+
384
+	if(fork_sync_timer(-1 /*PROC_TIMER*/, "WTIMER", 1,
385
+				sr_wtimer_exec, NULL, 1)<0) {
386
+		LM_ERR("wtimer starting failed\n");
387
+		return -1;
388
+	}
389
+
390
+	return 0;
391
+}
392
+
281 393
 /* vi: set ts=4 sw=4 tw=79:ai:cindent: */
... ...
@@ -122,6 +122,10 @@ int fork_sync_timer(int child_id, char* desc, int make_sock,
122 122
 int fork_sync_utimer(int child_id, char* desc, int make_sock,
123 123
 						utimer_function* f, void* param, int uinterval);
124 124
 
125
+int sr_wtimer_init(void);
126
+int sr_wtimer_add(timer_function* f, void* param, int interval);
127
+int sr_wtimer_start(void);
128
+
125 129
 #endif /*__timer_proc_h*/
126 130
 
127 131
 /* vi: set ts=4 sw=4 tw=79:ai:cindent: */