add softtimer to the core, begin framework for static modules and reduces calls to gettimeofday for timestamps

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5784 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale
2007-10-03 16:44:11 +00:00
parent 23758b1965
commit bd6bd9ad57
21 changed files with 163 additions and 303 deletions
+6 -3
View File
@@ -112,7 +112,7 @@ SWITCH_STANDARD_APP(fifo_function)
switch_event_t *event = NULL;
char date[80] = "";
switch_time_exp_t tm;
switch_time_t ts = switch_time_now();
switch_time_t ts = switch_timestamp_now();
switch_size_t retsize;
@@ -181,6 +181,7 @@ SWITCH_STANDARD_APP(fifo_function)
switch_queue_push(node->fifo, uuid);
switch_mutex_unlock(node->mutex);
ts = switch_timestamp_now();
switch_time_exp_lt(&tm, ts);
switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
switch_channel_set_variable(channel, "fifo_status", "WAITING");
@@ -208,7 +209,7 @@ SWITCH_STANDARD_APP(fifo_function)
if (switch_channel_ready(channel)) {
switch_channel_set_state(channel, CS_HIBERNATE);
} else {
ts = switch_timestamp_now();
switch_time_exp_lt(&tm, ts);
switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
switch_channel_set_variable(channel, "fifo_status", "ABORTED");
@@ -263,7 +264,7 @@ SWITCH_STANDARD_APP(fifo_function)
switch_event_fire(&event);
}
ts = switch_timestamp_now();
switch_time_exp_lt(&tm, ts);
switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
switch_channel_set_variable(channel, "fifo_status", "WAITING");
@@ -344,6 +345,7 @@ SWITCH_STANDARD_APP(fifo_function)
assert(cloned_profile->next == NULL);
switch_channel_set_originatee_caller_profile(channel, cloned_profile);
ts = switch_timestamp_now();
switch_time_exp_lt(&tm, ts);
switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
switch_channel_set_variable(channel, "fifo_status", "TALKING");
@@ -355,6 +357,7 @@ SWITCH_STANDARD_APP(fifo_function)
switch_channel_set_variable(other_channel, "fifo_target", switch_core_session_get_uuid(session));
switch_ivr_multi_threaded_bridge(session, other_session, on_dtmf, other_session, session);
ts = switch_timestamp_now();
switch_time_exp_lt(&tm, ts);
switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
switch_channel_set_variable(channel, "fifo_status", "WAITING");
+3 -3
View File
@@ -180,7 +180,7 @@ static switch_status_t channel_on_init(switch_core_session_t *session)
assert(channel != NULL);
last = switch_time_now() - waitsec;
last = switch_timestamp_now() - waitsec;
@@ -243,7 +243,7 @@ static switch_status_t channel_on_init(switch_core_session_t *session)
switch_channel_mark_ring_ready(channel);
while (switch_channel_get_state(channel) == CS_INIT && !switch_test_flag(tech_pvt, TFLAG_ANSWER)) {
if (switch_time_now() - last >= waitsec) {
if (switch_timestamp_now() - last >= waitsec) {
char buf[512];
switch_event_t *event;
@@ -257,7 +257,7 @@ static switch_status_t channel_on_init(switch_core_session_t *session)
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s\n", buf);
last = switch_time_now();
last = switch_timestamp_now();
if (ring_file) {
unsigned int pos = 0;
switch_core_file_seek(&fh, &pos, 0, SEEK_SET);
@@ -1061,18 +1061,18 @@ static switch_status_t negotiate_media(switch_core_session_t *session)
switch_set_flag_locked(tech_pvt, TFLAG_IO);
started = switch_time_now();
started = switch_timestamp_now();
/* jingle has no ringing indication so we will just pretend that we got one */
switch_core_session_queue_indication(session, SWITCH_MESSAGE_INDICATE_RINGING);
switch_channel_mark_ring_ready(channel);
if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
tech_pvt->next_cand = switch_time_now() + DL_CAND_WAIT;
tech_pvt->next_desc = switch_time_now();
tech_pvt->next_cand = started + DL_CAND_WAIT;
tech_pvt->next_desc = started;
} else {
tech_pvt->next_cand = switch_time_now() + DL_CAND_WAIT;
tech_pvt->next_desc = switch_time_now() + DL_CAND_WAIT;
tech_pvt->next_cand = started + DL_CAND_WAIT;
tech_pvt->next_desc = started + DL_CAND_WAIT;
}
while (!(switch_test_flag(tech_pvt, TFLAG_CODEC_READY) &&
@@ -1080,7 +1080,7 @@ static switch_status_t negotiate_media(switch_core_session_t *session)
switch_test_flag(tech_pvt, TFLAG_ANSWER) && switch_test_flag(tech_pvt, TFLAG_TRANSPORT_ACCEPT) &&
tech_pvt->remote_ip && tech_pvt->remote_port
&& switch_test_flag(tech_pvt, TFLAG_TRANSPORT))) {
now = switch_time_now();
now = switch_timestamp_now();
elapsed = (unsigned int) ((now - started) / 1000);
if (switch_channel_get_state(channel) >= CS_HANGUP || switch_test_flag(tech_pvt, TFLAG_BYE)) {
@@ -1365,7 +1365,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
#if 0
if (tech_pvt->last_read) {
elapsed = (unsigned int) ((switch_time_now() - tech_pvt->last_read) / 1000);
elapsed = (unsigned int) ((switch_timestamp_now() - tech_pvt->last_read) / 1000);
if (elapsed > 60000) {
return SWITCH_STATUS_TIMEOUT;
}
@@ -1393,7 +1393,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
payload = tech_pvt->read_frame.payload;
#if 0
elapsed = (unsigned int) ((switch_time_now() - started) / 1000);
elapsed = (unsigned int) ((switch_timestamp_now() - started) / 1000);
if (timeout > -1) {
if (elapsed >= (unsigned int) timeout) {
@@ -1401,7 +1401,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
}
}
elapsed = (unsigned int) ((switch_time_now() - last_act) / 1000);
elapsed = (unsigned int) ((switch_timestamp_now() - last_act) / 1000);
if (elapsed >= hard_timeout) {
return SWITCH_STATUS_BREAK;
}
@@ -179,7 +179,7 @@ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan)
assert(channel != NULL);
last = switch_time_now() - waitsec;
last = switch_timestamp_now() - waitsec;
@@ -244,7 +244,7 @@ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan)
while (switch_channel_get_state(channel) == CS_INIT && !switch_test_flag(tech_pvt, TFLAG_ANSWER)) {
switch_size_t olen = globals.timer.samples;
if (switch_time_now() - last >= waitsec) {
if (switch_timestamp_now() - last >= waitsec) {
char buf[512];
switch_event_t *event;
@@ -257,7 +257,7 @@ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan)
switch_event_fire(&event);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s\n", buf);
last = switch_time_now();
last = switch_timestamp_now();
}
if (ring_file) {
+1 -2
View File
@@ -1832,8 +1832,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
}
if (!sofia_endpoint_interface || !(session = switch_core_session_request(sofia_endpoint_interface, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Session Alloc Failed!\n");
nua_respond(nh, SIP_503_SERVICE_UNAVAILABLE, TAG_END());
nua_respond(nh, SIP_486_BUSY_HERE, TAG_END());
return;
}
+1 -1
View File
@@ -346,7 +346,7 @@ static switch_status_t en_say_time(switch_core_session_t *session, char *tosay,
if ((t = atoi(tosay)) > 0) {
target = switch_time_make(t, 0);
} else {
target = switch_time_now();
target = switch_timestamp_now();
}
switch_time_exp_lt(&tm, target);
@@ -1,298 +0,0 @@
/*
* 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_softtimer.c -- Software Timer Module
*
*/
#include <switch.h>
#include <stdio.h>
#ifndef UINT32_MAX
#define UINT32_MAX 0xffffffff
#endif
#define MAX_TICK UINT32_MAX - 1024
static switch_memory_pool_t *module_pool = NULL;
static struct {
int32_t RUNNING;
int32_t STARTED;
switch_mutex_t *mutex;
} globals;
SWITCH_MODULE_LOAD_FUNCTION(mod_softtimer_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_softtimer_shutdown);
SWITCH_MODULE_RUNTIME_FUNCTION(mod_softtimer_runtime);
SWITCH_MODULE_DEFINITION(mod_softtimer, mod_softtimer_load, mod_softtimer_shutdown, mod_softtimer_runtime);
#define MAX_ELEMENTS 1000
struct timer_private {
switch_size_t reference;
switch_size_t start;
uint32_t roll;
uint32_t ready;
};
typedef struct timer_private timer_private_t;
struct timer_matrix {
switch_size_t tick;
uint32_t count;
uint32_t roll;
};
typedef struct timer_matrix timer_matrix_t;
static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS + 1];
#define IDLE_SPEED 100
static switch_status_t timer_init(switch_timer_t *timer)
{
timer_private_t *private_info;
int sanity = 0;
while(globals.STARTED == 0) {
switch_yield(100000);
if (++sanity == 10) {
break;
}
}
if (globals.RUNNING != 1 || !globals.mutex) {
return SWITCH_STATUS_FALSE;
}
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->start = private_info->reference = TIMER_MATRIX[timer->interval].tick;
private_info->roll = TIMER_MATRIX[timer->interval].roll;
private_info->ready = 1;
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_MEMERR;
}
#define check_roll() if (private_info->roll < TIMER_MATRIX[timer->interval].roll) {\
private_info->roll++;\
private_info->reference = private_info->start = TIMER_MATRIX[timer->interval].tick;\
}\
static switch_status_t timer_step(switch_timer_t *timer)
{
timer_private_t *private_info = timer->private_info;
uint64_t samples;
if (globals.RUNNING != 1 || private_info->ready == 0) {
return SWITCH_STATUS_FALSE;
}
check_roll();
samples = timer->samples * (private_info->reference - private_info->start);
if (samples > UINT32_MAX) {
private_info->start = private_info->reference;
samples = timer->samples;
}
timer->samplecount = (uint32_t) samples;
private_info->reference++;
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t timer_next(switch_timer_t *timer)
{
timer_private_t *private_info = timer->private_info;
timer_step(timer);
while (globals.RUNNING == 1 && private_info->ready && TIMER_MATRIX[timer->interval].tick < private_info->reference) {
check_roll();
switch_yield(1000);
}
if (globals.RUNNING == 1) {
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_FALSE;
}
static switch_status_t timer_check(switch_timer_t *timer)
{
timer_private_t *private_info = timer->private_info;
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_size_t diff;
if (globals.RUNNING != 1 || !private_info->ready) {
return SWITCH_STATUS_SUCCESS;
}
check_roll();
if (TIMER_MATRIX[timer->interval].tick < private_info->reference) {
diff = private_info->reference - TIMER_MATRIX[timer->interval].tick;
} else {
diff = 0;
}
if (diff) {
status = SWITCH_STATUS_FALSE;
} else {
timer_step(timer);
}
return status;
}
static switch_status_t timer_destroy(switch_timer_t *timer)
{
timer_private_t *private_info = timer->private_info;
switch_mutex_lock(globals.mutex);
TIMER_MATRIX[timer->interval].count--;
if (TIMER_MATRIX[timer->interval].count == 0) {
TIMER_MATRIX[timer->interval].tick = 0;
}
switch_mutex_unlock(globals.mutex);
private_info->ready = 0;
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_LOAD_FUNCTION(mod_softtimer_load)
{
switch_timer_interface_t *timer_interface;
module_pool = pool;
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
timer_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_TIMER_INTERFACE);
timer_interface->interface_name = "soft";
timer_interface->timer_init = timer_init;
timer_interface->timer_next = timer_next;
timer_interface->timer_step = timer_step;
timer_interface->timer_check = timer_check;
timer_interface->timer_destroy = timer_destroy;
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
/* I cant resist setting this to 10ms, we dont even run anything smaller than 20ms so this is already
twice the granularity we need, we'll change it if we need anything smaller
*/
#define STEP_MS 1
#define STEP_MIC 1000
SWITCH_MODULE_RUNTIME_FUNCTION(mod_softtimer_runtime)
{
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.STARTED = globals.RUNNING = 1;
while (globals.RUNNING == 1) {
reference += STEP_MIC;
while (switch_time_now() < reference) {
switch_yield(STEP_MIC);
}
current_ms += STEP_MS;
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++;
if (TIMER_MATRIX[index].tick == MAX_TICK) {
TIMER_MATRIX[index].tick = 0;
TIMER_MATRIX[index].roll++;
}
}
}
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_MODULE_SHUTDOWN_FUNCTION(mod_softtimer_shutdown)
{
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;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
*/
@@ -1,210 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="mod_softtimer"
ProjectGUID="{DCC13474-28DF-47CA-A8EB-72F8CE9A78C5}"
RootNamespace="mod_softtimer"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;$(InputDir)..\..\..\include&quot;;&quot;$(InputDir)include&quot;;&quot;$(InputDir)..\..\..\..\libs\include&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(SolutionDir)$(OutDir)/mod/$(InputName).dll"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\..\..\w32\vsnet\$(OutDir)"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)$(TargetName).pdb"
SubSystem="2"
ImportLibrary="$(OutDir)/mod_softtimer.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(InputDir)..\..\..\include&quot;;&quot;$(InputDir)include&quot;;&quot;$(InputDir)..\..\..\..\libs\include&quot;"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(SolutionDir)$(OutDir)/mod/$(InputName).dll"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\..\..\w32\vsnet\$(OutDir)"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)$(TargetName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
ImportLibrary="$(OutDir)/mod_softtimer.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\mod_softtimer.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>