Browse code

core: secondary timer implemented as classic wheel timer (wtimer)

Daniel-Constantin Mierla authored on 25/01/2016 23:35:57
Showing 1 changed files
... ...
@@ -284,8 +284,9 @@ int fork_sync_utimer(int child_id, char* desc, int make_sock,
284 284
 typedef struct sr_wtimer_node {
285 285
 	struct sr_wtimer_node *next;
286 286
 	uint32_t interval;  /* frequency of execution (secs) */
287
-	uint32_t steps;     /* interval = loops * SR_WTIMER_SIZE + steps */
287
+	uint32_t steps;     /* init: interval = loops * SR_WTIMER_SIZE + steps */
288 288
 	uint32_t loops;
289
+	uint32_t eloop;
289 290
 	timer_function* f;
290 291
 	void* param;
291 292
 } sr_wtimer_node_t;
... ...
@@ -337,20 +338,38 @@ int sr_wtimer_add(timer_function* f, void* param, int interval)
337 338
 	wt->interval = interval;
338 339
 	wt->steps = interval % SR_WTIMER_SIZE;
339 340
 	wt->loops = interval / SR_WTIMER_SIZE;
341
+	wt->eloop = wt->loops;
340 342
 	wt->next = _sr_wtimer->wlist[wt->steps];
341 343
 	_sr_wtimer->wlist[wt->steps] = wt;
342 344
 
343 345
 	return 0;
344 346
 }
345 347
 
348
+/**
349
+ *
350
+ */
351
+int sr_wtimer_reinsert(uint32_t cs, sr_wtimer_node_t *wt)
352
+{
353
+	uint32_t ts;
354
+
355
+	ts = (cs + wt->interval) % SR_WTIMER_SIZE;
356
+	wt->eloop = wt->interval / SR_WTIMER_SIZE;
357
+	wt->next = _sr_wtimer->wlist[ts];
358
+	_sr_wtimer->wlist[ts] = wt;
359
+
360
+	return 0;
361
+}
362
+
346 363
 /**
347 364
  *
348 365
  */
349 366
 void sr_wtimer_exec(unsigned int ticks, void *param)
350 367
 {
351 368
 	sr_wtimer_node_t *wt;
352
-	uint32_t i;
353
-	uint32_t c;
369
+	sr_wtimer_node_t *wn;
370
+	sr_wtimer_node_t *wp;
371
+	uint32_t cs;
372
+	uint32_t cl;
354 373
 
355 374
 	if(_sr_wtimer==NULL) {
356 375
 		LM_ERR("wtimer not intialized\n");
... ...
@@ -358,17 +377,29 @@ void sr_wtimer_exec(unsigned int ticks, void *param)
358 377
 	}
359 378
 
360 379
 	_sr_wtimer->itimer++;
361
-	c = _sr_wtimer->itimer / SR_WTIMER_SIZE;
362
-
363
-	for(i=1; i<=SR_WTIMER_SIZE; i++) {
364
-		if(_sr_wtimer->itimer % i == 0) {
365
-			for(wt=_sr_wtimer->wlist[i % SR_WTIMER_SIZE];
366
-					wt!=NULL; wt = wt->next) {
367
-				if(wt->loops==0 || (c % wt->loops==0)) {
368
-					wt->f(ticks, wt->param);
369
-				}
380
+	cs = _sr_wtimer->itimer % SR_WTIMER_SIZE;
381
+	cl = _sr_wtimer->itimer / SR_WTIMER_SIZE;
382
+	LM_DBG("wtimer - loop: %u - slot: %u\n", cl, cs);
383
+
384
+	wp = NULL;
385
+	wt=_sr_wtimer->wlist[cs];
386
+	while(wt) {
387
+		wn = wt->next;
388
+		if(wt->eloop==0) {
389
+			/* execute timer callback function */
390
+			wt->f(ticks, wt->param);
391
+			/* extract and reinsert timer item */
392
+			if(wp==NULL) {
393
+				_sr_wtimer->wlist[cs] = wn;
394
+			} else {
395
+				wp->next = wn;
370 396
 			}
397
+			sr_wtimer_reinsert(cs, wt);
398
+		} else {
399
+			wt->eloop--;
400
+			wp = wt;
371 401
 		}
402
+		wt = wn;
372 403
 	}
373 404
 }
374 405