[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