ms,
flags,
key,
- "thread_soft",
+ "soft",
&err, switch_core_session_get_pool(tech_pvt->session));
if (switch_rtp_ready(tech_pvt->rtp_session)) {
#include <switch.h>
#include <stdio.h>
-static const char modname[] = "mod_softtimer";
+static switch_memory_pool_t *module_pool = NULL;
+
+static struct {
+ int32_t RUNNING;
+ switch_mutex_t *mutex;
+ uint32_t timer_milliseconds;
+ uint32_t timer_microseconds;
+} globals;
-#ifdef WIN32
-//#define WINTIMER
-#endif
+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;
-
-#ifdef WINTIMER
- private->base.QuadPart += timer->interval * (private->freq.QuadPart / 1000);
- for (;;) {
- QueryPerformanceCounter(&private->now);
- if (private->now.QuadPart >= private->base.QuadPart) {
- break;
+ uint32_t index = 0, min = IDLE_SPEED;
+
+ 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 soft_timer_check(switch_timer_t *timer)
+static inline switch_status_t 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;
- } else {
- return SWITCH_STATUS_FALSE;
- }
-#else
- if (switch_time_now() < private->reference) {
- return SWITCH_STATUS_FALSE;
+ 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 {
- private->reference += timer->interval * 1000;
- return SWITCH_STATUS_SUCCESS;
+ private_info->reference += timer->interval;
+ status = 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
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;
+}
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_threadtimer.c -- Software Timer Module
- *
- */
-#include <switch.h>
-#include <stdio.h>
-
-static switch_memory_pool_t *module_pool = NULL;
-
-static struct {
- int32_t RUNNING;
- switch_mutex_t *mutex;
- uint32_t timer_milliseconds;
- uint32_t timer_microseconds;
-} globals;
-
-static const char modname[] = "mod_threadtimer";
-#define MAX_ELEMENTS 1000
-
-struct timer_private {
- uint32_t reference;
-};
-typedef struct timer_private timer_private_t;
-
-struct timer_matrix {
- uint64_t tick;
- uint32_t count;
-};
-typedef struct timer_matrix timer_matrix_t;
-
-static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS+1];
-
-#define IDLE_SPEED 100
-
-
-static inline void set_timer(void)
-{
- uint32_t index = 0, min = IDLE_SPEED;
-
- for(index = 0; index < MAX_ELEMENTS; index++) {
- if (TIMER_MATRIX[index].count) {
- if (min > index) {
- min = index;
- }
- }
- }
-
- 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;
- }
-
- 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 timer_next(switch_timer_t *timer)
-{
- 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)
-
-{
- 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 {
- private_info->reference += timer->interval;
- status = SWITCH_STATUS_SUCCESS;
- }
-
- return status;
-}
-
-
-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 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_threadtimer_module_interface = {
- /*.module_name */ modname,
- /*.endpoint_interface */ NULL,
- /*.timer_interface */ &timer_interface,
- /*.switch_dialplan_interface */ NULL,
- /*.switch_codec_interface */ NULL,
- /*.switch_application_interface */ NULL
-};
-
-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_threadtimer_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;
-}
+++ /dev/null
-<?xml version="1.0" encoding="Windows-1252"?>\r
-<VisualStudioProject\r
- ProjectType="Visual C++"\r
- Version="8.00"\r
- Name="mod_threadtimer"\r
- ProjectGUID="{F2DCC46E-3BE4-4392-81BF-973B2E47EB64}"\r
- RootNamespace="mod_threadtimer"\r
- Keyword="Win32Proj"\r
- >\r
- <Platforms>\r
- <Platform\r
- Name="Win32"\r
- />\r
- </Platforms>\r
- <ToolFiles>\r
- </ToolFiles>\r
- <Configurations>\r
- <Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="$(ConfigurationName)"\r
- IntermediateDirectory="$(ConfigurationName)"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- Optimization="0"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\..\libs\include""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="1"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="4"\r
- WarnAsError="true"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="3"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- OutputFile="$(SolutionDir)$(OutDir)/mod/$(InputName).dll"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories="..\..\..\..\w32\vsnet\$(OutDir)"\r
- GenerateDebugInformation="true"\r
- ProgramDatabaseFile="$(OutDir)$(TargetName).pdb"\r
- SubSystem="2"\r
- ImportLibrary="$(OutDir)/mod_threadtimer.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- <Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="$(ConfigurationName)"\r
- IntermediateDirectory="$(ConfigurationName)"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\..\libs\include""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- RuntimeLibrary="0"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="4"\r
- WarnAsError="true"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="3"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- OutputFile="$(SolutionDir)$(OutDir)/mod/$(InputName).dll"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories="..\..\..\..\w32\vsnet\$(OutDir)"\r
- GenerateDebugInformation="true"\r
- ProgramDatabaseFile="$(OutDir)$(TargetName).pdb"\r
- SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- ImportLibrary="$(OutDir)/mod_threadtimer.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- </Configurations>\r
- <References>\r
- </References>\r
- <Files>\r
- <Filter\r
- Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
- >\r
- <File\r
- RelativePath=".\mod_threadtimer.c"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
- >\r
- </Filter>\r
- <Filter\r
- Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
- >\r
- </Filter>\r
- </Files>\r
- <Globals>\r
- </Globals>\r
-</VisualStudioProject>\r