Timer Functions
[Core Library]

Collaboration diagram for Timer Functions:

Functions

switch_status_t switch_core_timer_init (switch_timer_t *timer, const char *timer_name, int interval, int samples, switch_memory_pool_t *pool)
 Request a timer handle using given time module.
void switch_time_calibrate_clock (void)
switch_status_t switch_core_timer_next (switch_timer_t *timer)
 Wait for one cycle on an existing timer.
switch_status_t switch_core_timer_step (switch_timer_t *timer)
 Step the timer one step.
switch_status_t switch_core_timer_sync (switch_timer_t *timer)
switch_status_t switch_core_timer_check (switch_timer_t *timer, switch_bool_t step)
 Check if the current step has been exceeded.
switch_status_t switch_core_timer_destroy (switch_timer_t *timer)
 Destroy an allocated timer.


Function Documentation

switch_status_t switch_core_timer_check ( switch_timer_t timer,
switch_bool_t  step 
)

Check if the current step has been exceeded.

Parameters:
timer the timer to wait on
step increment timer if a tick was detected
Returns:
the newest sample count

Definition at line 103 of file switch_core_timer.c.

References SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, switch_log_printf(), and SWITCH_STATUS_GENERR.

00104 {
00105         if (!timer->timer_interface || !timer->timer_interface->timer_check) {
00106                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timer is not properly configured.\n");
00107                 return SWITCH_STATUS_GENERR;
00108         }
00109 
00110         return timer->timer_interface->timer_check(timer, step);
00111 }

switch_status_t switch_core_timer_destroy ( switch_timer_t timer  ) 

Destroy an allocated timer.

Parameters:
timer timer to destroy
Returns:
SWITCH_STATUS_SUCCESS after destruction

Definition at line 114 of file switch_core_timer.c.

References SWITCH_CHANNEL_LOG, switch_core_destroy_memory_pool, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_STATUS_GENERR, SWITCH_STATUS_SUCCESS, switch_test_flag, SWITCH_TIMER_FLAG_FREE_POOL, and UNPROTECT_INTERFACE.

Referenced by switch_ivr_clear_speech_cache(), switch_ivr_play_file(), switch_ivr_speak_text(), switch_rtp_change_interval(), switch_rtp_destroy(), and switch_rtp_udptl_mode().

00115 {
00116         if (!timer->timer_interface || !timer->timer_interface->timer_destroy) {
00117                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timer is not properly configured.\n");
00118                 return SWITCH_STATUS_GENERR;
00119         }
00120 
00121         timer->timer_interface->timer_destroy(timer);
00122         UNPROTECT_INTERFACE(timer->timer_interface);
00123 
00124         if (switch_test_flag(timer, SWITCH_TIMER_FLAG_FREE_POOL)) {
00125                 switch_core_destroy_memory_pool(&timer->memory_pool);
00126         }
00127 
00128         memset(timer, 0, sizeof(*timer));
00129 
00130         return SWITCH_STATUS_SUCCESS;
00131 }

switch_status_t switch_core_timer_init ( switch_timer_t timer,
const char *  timer_name,
int  interval,
int  samples,
switch_memory_pool_t pool 
)

Request a timer handle using given time module.

Parameters:
timer a timer object to allocate to
timer_name the name of the timer module to use
interval desired interval
samples the number of samples to increment on each cycle
pool the memory pool to use for allocation
Returns:

Definition at line 38 of file switch_core_timer.c.

References SWITCH_CHANNEL_LOG, switch_core_new_memory_pool, switch_loadable_module_get_timer_interface(), SWITCH_LOG_ERROR, switch_log_printf(), switch_set_flag, SWITCH_STATUS_GENERR, SWITCH_STATUS_SUCCESS, SWITCH_TIMER_FLAG_FREE_POOL, switch_timer_interface::timer_init, and UNPROTECT_INTERFACE.

Referenced by switch_ivr_play_file(), switch_ivr_speak_text(), switch_rtp_change_interval(), and switch_rtp_create().

00040 {
00041         switch_timer_interface_t *timer_interface;
00042         switch_status_t status;
00043         memset(timer, 0, sizeof(*timer));
00044         if ((timer_interface = switch_loadable_module_get_timer_interface(timer_name)) == 0 || !timer_interface->timer_init) {
00045                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid timer %s!\n", timer_name);
00046                 return SWITCH_STATUS_GENERR;
00047         }
00048 
00049         timer->interval = interval;
00050         timer->samples = samples;
00051         timer->samplecount = samples;
00052         timer->timer_interface = timer_interface;
00053 
00054         if (pool) {
00055                 timer->memory_pool = pool;
00056         } else {
00057                 if ((status = switch_core_new_memory_pool(&timer->memory_pool)) != SWITCH_STATUS_SUCCESS) {
00058                         UNPROTECT_INTERFACE(timer->timer_interface);
00059                         return status;
00060                 }
00061                 switch_set_flag(timer, SWITCH_TIMER_FLAG_FREE_POOL);
00062         }
00063 
00064         return timer->timer_interface->timer_init(timer);
00065 }

switch_status_t switch_core_timer_next ( switch_timer_t timer  ) 

Wait for one cycle on an existing timer.

Parameters:
timer the timer to wait on
Returns:
the newest sample count

Definition at line 67 of file switch_core_timer.c.

References SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_STATUS_GENERR, and SWITCH_STATUS_SUCCESS.

Referenced by rtp_common_read(), switch_ivr_play_file(), and switch_ivr_speak_text_handle().

00068 {
00069         if (!timer->timer_interface || !timer->timer_interface->timer_next) {
00070                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timer is not properly configured.\n");
00071                 return SWITCH_STATUS_GENERR;
00072         }
00073 
00074         if (timer->timer_interface->timer_next(timer) == SWITCH_STATUS_SUCCESS) {
00075                 return SWITCH_STATUS_SUCCESS;
00076         } else {
00077                 return SWITCH_STATUS_GENERR;
00078         }
00079 
00080 }

switch_status_t switch_core_timer_step ( switch_timer_t timer  ) 

Step the timer one step.

Parameters:
timer the timer to wait on
Returns:
the newest sample count

Definition at line 82 of file switch_core_timer.c.

References SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, switch_log_printf(), and SWITCH_STATUS_GENERR.

00083 {
00084         if (!timer->timer_interface || !timer->timer_interface->timer_step) {
00085                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timer is not properly configured.\n");
00086                 return SWITCH_STATUS_GENERR;
00087         }
00088 
00089         return timer->timer_interface->timer_step(timer);
00090 }

switch_status_t switch_core_timer_sync ( switch_timer_t timer  ) 

Definition at line 93 of file switch_core_timer.c.

References SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, switch_log_printf(), and SWITCH_STATUS_GENERR.

Referenced by read_rtp_packet(), rtp_common_read(), switch_ivr_play_file(), and switch_ivr_speak_text().

00094 {
00095         if (!timer->timer_interface || !timer->timer_interface->timer_sync) {
00096                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timer is not properly configured.\n");
00097                 return SWITCH_STATUS_GENERR;
00098         }
00099 
00100         return timer->timer_interface->timer_sync(timer);
00101 }

void switch_time_calibrate_clock ( void   ) 

Definition at line 208 of file switch_time.c.

References average_time(), calc_step, do_sleep(), switch_runtime::microseconds_per_tick, OFFSET, runtime, SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, switch_log_printf(), SWITCH_LOG_WARNING, switch_time_set_cond_yield(), and SWITCH_TRUE.

Referenced by switch_core_session_ctl(), and SWITCH_MODULE_LOAD_FUNCTION().

00209 {
00210         int x;
00211         switch_interval_time_t avg, val = 1000, want = 1000;
00212         int over = 0, under = 0, good = 0, step = 50, diff = 0, retry = 0, lastgood = 0, one_k = 0;
00213 
00214 #ifdef HAVE_CLOCK_GETRES
00215         struct timespec ts;
00216         long res = 0;
00217         clock_getres(CLOCK_MONOTONIC, &ts);
00218         res = ts.tv_nsec / 1000;
00219 
00220 
00221         if (res > 900 && res < 1100) {
00222                 one_k = 1;
00223         }
00224         
00225         if (res > 1500) {
00226                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
00227                                                   "Timer resolution of %ld microseconds detected!\n"
00228                                                   "Do you have your kernel timer frequency set to lower than 1,000Hz? "
00229                                                   "You may experience audio problems. Step MS %d\n", ts.tv_nsec / 1000, runtime.microseconds_per_tick / 1000);
00230                 do_sleep(5000000);
00231                 switch_time_set_cond_yield(SWITCH_TRUE);
00232                 return;
00233         }
00234 #endif
00235 
00236   top:
00237         val = 1000;
00238         step = 50;
00239         over = under = good = 0;
00240         OFFSET = 0;
00241 
00242         for (x = 0; x < 100; x++) {
00243                 avg = average_time(val, 50);
00244                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Test: %ld Average: %ld Step: %d\n", (long) val, (long) avg, step);
00245 
00246                 diff = abs((int) (want - avg));
00247                 if (diff > 1500) {
00248                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
00249                                                           "Abnormally large timer gap %d detected!\n"
00250                                                           "Do you have your kernel timer frequency set to lower than 1,000Hz? You may experience audio problems.\n", diff);
00251                         do_sleep(5000000);
00252                         switch_time_set_cond_yield(SWITCH_TRUE);
00253                         return;
00254                 }
00255 
00256                 if (diff <= 100) {
00257                         lastgood = (int) val;
00258                 }
00259 
00260                 if (diff <= 2) {
00261                         under = over = 0;
00262                         lastgood = (int) val;
00263                         if (++good > 10) {
00264                                 break;
00265                         }
00266                 } else if (avg > want) {
00267                         if (under) {
00268                                 calc_step();
00269                         }
00270                         under = good = 0;
00271                         if ((val - step) < 0) {
00272                                 if (++retry > 2)
00273                                         break;
00274                                 goto top;
00275                         }
00276                         val -= step;
00277                         over++;
00278                 } else if (avg < want) {
00279                         if (over) {
00280                                 calc_step();
00281                         }
00282                         over = good = 0;
00283                         if ((val - step) < 0) {
00284                                 if (++retry > 2)
00285                                         break;
00286                                 goto top;
00287                         }
00288                         val += step;
00289                         under++;
00290                 }
00291         }
00292 
00293         if (good >= 10) {
00294                 OFFSET = (int) (want - val);
00295                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Timer offset of %d calculated\n", OFFSET);
00296         } else if (lastgood) {
00297                 OFFSET = (int) (want - lastgood);
00298                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Timer offset of %d calculated (fallback)\n", OFFSET);
00299                 switch_time_set_cond_yield(SWITCH_TRUE);
00300         } else if (one_k) {
00301                 OFFSET = 900;
00302                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Timer offset CANNOT BE DETECTED, forcing OFFSET to 900\n");
00303                 switch_time_set_cond_yield(SWITCH_TRUE);
00304         } else {
00305                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Timer offset NOT calculated\n");
00306                 switch_time_set_cond_yield(SWITCH_TRUE);
00307         }
00308 }


Generated on Wed May 16 04:00:18 2012 for FreeSWITCH API Documentation by  doxygen 1.4.7