[Freeswitch-svn] [commit] r2713 - in freeswitch/trunk/src/mod: endpoints/mod_exosip timers/mod_softtimer timers/mod_threadtimer

Freeswitch SVN anthm at freeswitch.org
Sat Sep 16 16:18:25 EDT 2006


Author: anthm
Date: Sat Sep 16 16:18:24 2006
New Revision: 2713

Removed:
   freeswitch/trunk/src/mod/timers/mod_threadtimer/
Modified:
   freeswitch/trunk/src/mod/endpoints/mod_exosip/mod_exosip.c
   freeswitch/trunk/src/mod/timers/mod_softtimer/mod_softtimer.c

Log:
marry mod_threadsoft with mod_softtimer

Modified: freeswitch/trunk/src/mod/endpoints/mod_exosip/mod_exosip.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_exosip/mod_exosip.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_exosip/mod_exosip.c	Sat Sep 16 16:18:24 2006
@@ -585,7 +585,7 @@
 										   ms,
 										   flags,
 										   key,
-										   "thread_soft",
+										   "soft",
 										   &err, switch_core_session_get_pool(tech_pvt->session));
 
 	if (switch_rtp_ready(tech_pvt->rtp_session)) {

Modified: freeswitch/trunk/src/mod/timers/mod_softtimer/mod_softtimer.c
==============================================================================
--- freeswitch/trunk/src/mod/timers/mod_softtimer/mod_softtimer.c	(original)
+++ freeswitch/trunk/src/mod/timers/mod_softtimer/mod_softtimer.c	Sat Sep 16 16:18:24 2006
@@ -32,121 +32,131 @@
 #include <switch.h>
 #include <stdio.h>
 
-static const char modname[] = "mod_softtimer";
+static switch_memory_pool_t *module_pool = NULL;
 
-#ifdef WIN32
-//#define WINTIMER
-#endif
+static struct {
+	int32_t RUNNING;
+	switch_mutex_t *mutex;
+	uint32_t timer_milliseconds;
+	uint32_t timer_microseconds;
+} globals;
 
+static const char modname[] = "mod_softtimer";
+#define MAX_ELEMENTS 1000
+
 struct timer_private {
-#ifdef WINTIMER
-	LARGE_INTEGER freq;
-	LARGE_INTEGER base;
-	LARGE_INTEGER now;
-#else
-	switch_time_t reference;
-#endif
+    uint32_t reference;
 };
+typedef struct timer_private timer_private_t;
 
-static inline switch_status_t soft_timer_init(switch_timer_t *timer)
-{
-	struct timer_private *private;
+struct timer_matrix {
+	uint64_t tick;
+	uint32_t count;
+};
+typedef struct timer_matrix timer_matrix_t;
 
-	private = switch_core_alloc(timer->memory_pool, sizeof(*private));
-	timer->private_info = private;
+static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS+1];
 
-#ifdef WINTIMER
-	QueryPerformanceFrequency(&private->freq);
-	QueryPerformanceCounter(&private->base);
-#else
-	private->reference = switch_time_now();
-#endif
+#define IDLE_SPEED 100
 
-	return SWITCH_STATUS_SUCCESS;
-}
 
-static inline switch_status_t soft_timer_next(switch_timer_t *timer)
+static inline void set_timer(void)
 {
-	struct timer_private *private = timer->private_info;
+	uint32_t index = 0, min = IDLE_SPEED;
 
-#ifdef WINTIMER
-	private->base.QuadPart += timer->interval * (private->freq.QuadPart / 1000);
-	for (;;) {
-		QueryPerformanceCounter(&private->now);
-		if (private->now.QuadPart >= private->base.QuadPart) {
-			break;
+	for(index = 0; index < MAX_ELEMENTS; index++) {
+		if (TIMER_MATRIX[index].count) {
+			if (min > index) {
+				min = index;
+			}
 		}
-		switch_yield(100);
 	}
-#else
-	private->reference += timer->interval * 1000;
 
-	while (switch_time_now() < private->reference) {
-		switch_yield(1000);
+	globals.timer_milliseconds = min;
+	globals.timer_microseconds = min * 1000;
+}
+
+static inline switch_status_t timer_init(switch_timer_t *timer)
+{
+	timer_private_t *private_info;
+
+	if ((private_info = switch_core_alloc(timer->memory_pool, sizeof(*private_info)))) {
+		switch_mutex_lock(globals.mutex);
+		TIMER_MATRIX[timer->interval].count++;
+		switch_mutex_unlock(globals.mutex);
+		timer->private_info = private_info;
+		private_info->reference = TIMER_MATRIX[timer->interval].tick;
+		set_timer();
+
+		return SWITCH_STATUS_SUCCESS;
 	}
-#endif
 
-	timer->samplecount += timer->samples;
+	return SWITCH_STATUS_MEMERR;
+}
 
+static inline switch_status_t timer_step(switch_timer_t *timer)
+{
+	timer_private_t *private_info = timer->private_info;
+
+	private_info->reference += timer->interval;
+
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static inline switch_status_t soft_timer_step(switch_timer_t *timer)
+
+static inline switch_status_t timer_next(switch_timer_t *timer)
 {
-	struct timer_private *private = timer->private_info;
-#ifdef WINTIMER
-	private->base.QuadPart += timer->interval * (private->freq.QuadPart / 1000);
-#else
-	private->reference += timer->interval * 1000;
-#endif
+	timer_private_t *private_info = timer->private_info;
 
+	timer_step(timer);
+	while (TIMER_MATRIX[timer->interval].tick < private_info->reference) {
+		switch_yield(1000);
+	}
+	timer->samplecount += timer->samples;
+
 	return SWITCH_STATUS_SUCCESS;
 }
 
+static inline switch_status_t timer_check(switch_timer_t *timer)
 
-static inline switch_status_t soft_timer_check(switch_timer_t *timer)
-
 {
-	struct timer_private *private = timer->private_info;
-#ifdef WINTIMER
-	QueryPerformanceCounter(&private->now);
-	if (private->now.QuadPart >= private->base.QuadPart) {
-		private->base.QuadPart += timer->interval * (private->freq.QuadPart / 1000);
-		return SWITCH_STATUS_SUCCESS;
+	timer_private_t *private_info = timer->private_info;
+	switch_status_t status;
+
+	if (TIMER_MATRIX[timer->interval].tick < private_info->reference) {
+		status = SWITCH_STATUS_FALSE;
 	} else {
-		return SWITCH_STATUS_FALSE;
+		private_info->reference += timer->interval;
+		status = SWITCH_STATUS_SUCCESS;
 	}
-#else
-	if (switch_time_now() < private->reference) {
-		return SWITCH_STATUS_FALSE;
-	} else {
-		private->reference += timer->interval * 1000;
-		return SWITCH_STATUS_SUCCESS;
-	}
-#endif
-	
+
+	return status;
 }
 
 
-static inline switch_status_t soft_timer_destroy(switch_timer_t *timer)
+static inline switch_status_t timer_destroy(switch_timer_t *timer)
 {
+	switch_mutex_lock(globals.mutex);
+	TIMER_MATRIX[timer->interval].count--;
+	switch_mutex_unlock(globals.mutex);
+	set_timer();
 	timer->private_info = NULL;
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static const switch_timer_interface_t soft_timer_interface = {
-	/*.interface_name */ "soft",
-	/*.timer_init */ soft_timer_init,
-	/*.timer_next */ soft_timer_next,
-	/*.timer_step */ soft_timer_step,
-	/*.timer_check */ soft_timer_check,
-	/*.timer_destroy */ soft_timer_destroy
+static const switch_timer_interface_t timer_interface = {
+	/*.interface_name */ "thread_soft",
+	/*.timer_init */ timer_init,
+	/*.timer_next */ timer_next,
+	/*.timer_step */ timer_step,
+	/*.timer_check */ timer_check,
+	/*.timer_destroy */ timer_destroy
 };
 
-static const switch_loadable_module_interface_t mod_timers_module_interface = {
+static const switch_loadable_module_interface_t mod_softtimer_module_interface = {
 	/*.module_name */ modname,
 	/*.endpoint_interface */ NULL,
-	/*.timer_interface */ &soft_timer_interface,
+	/*.timer_interface */ &timer_interface,
 	/*.switch_dialplan_interface */ NULL,
 	/*.switch_codec_interface */ NULL,
 	/*.switch_application_interface */ NULL
@@ -155,9 +165,81 @@
 SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename)
 {
 
+	if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
+		return SWITCH_STATUS_MEMERR;
+	}
+
 	/* connect my internal structure to the blank pointer passed to me */
-	*module_interface = &mod_timers_module_interface;
+	*module_interface = &mod_softtimer_module_interface;
 
 	/* indicate that the module should continue to be loaded */
+	return SWITCH_STATUS_SUCCESS;
+}
+
+
+
+SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void)
+{
+	switch_time_t reference = switch_time_now();
+	uint32_t current_ms = 0;
+	uint32_t x;
+	
+	memset(&globals, 0, sizeof(globals));
+	switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, module_pool);
+	globals.timer_microseconds = IDLE_SPEED  * 1000;
+	globals.timer_milliseconds = IDLE_SPEED;
+
+	globals.RUNNING = 1;
+
+	while(globals.RUNNING == 1) {
+		reference += globals.timer_microseconds;
+
+		while (switch_time_now() < reference) {
+			//switch_yield((reference - now) - 1000);
+			switch_yield(globals.timer_microseconds >> 1);
+		}
+
+		current_ms += globals.timer_milliseconds;
+
+		for (x = 0; x < MAX_ELEMENTS; x++) {
+			int i = x, index;
+			if (i == 0) {
+				i = 1;
+			}
+			
+			index = (current_ms % i == 0) ? i : 0; 
+
+			if (TIMER_MATRIX[index].count) {
+				TIMER_MATRIX[index].tick += index;
+			}
+		}
+
+		if (current_ms == MAX_ELEMENTS) {
+			current_ms = 0;
+		}
+	}
+
+	switch_mutex_lock(globals.mutex);
+	globals.RUNNING = 0;
+	switch_mutex_unlock(globals.mutex);
+
+	return SWITCH_STATUS_TERM;
+}
+
+
+SWITCH_MOD_DECLARE(switch_status_t) switch_module_shutdown(void)
+{
+	
+	if (globals.RUNNING) {
+		switch_mutex_lock(globals.mutex);
+		globals.RUNNING = -1;
+		switch_mutex_unlock(globals.mutex);
+		
+		while (globals.RUNNING) {
+			switch_yield(10000);
+		}
+	}
+
 	return SWITCH_STATUS_SUCCESS;
 }



More information about the Freeswitch-svn mailing list