Main Page | Modules | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

switch_time.c File Reference


Data Structures

struct  timer_private
struct  timer_matrix

Defines

#define UINT32_MAX   0xffffffff
#define MAX_TICK   UINT32_MAX - 1024
#define MS_PER_TICK   10
#define MAX_ELEMENTS   3600
#define IDLE_SPEED   100
#define STEP_MS   1
#define STEP_MIC   1000
#define check_roll()

Typedefs

typedef timer_private timer_private_t
typedef timer_matrix timer_matrix_t

Functions

 SWITCH_MODULE_LOAD_FUNCTION (softtimer_load)
 SWITCH_MODULE_SHUTDOWN_FUNCTION (softtimer_shutdown)
 SWITCH_MODULE_RUNTIME_FUNCTION (softtimer_runtime)
 SWITCH_MODULE_DEFINITION (CORE_SOFTTIMER_MODULE, softtimer_load, softtimer_shutdown, softtimer_runtime)
switch_time_t switch_timestamp_now (void)
time_t switch_timestamp (time_t *t)
void switch_time_set_monotonic (switch_bool_t enable)
void switch_time_sync (void)
void switch_sleep (switch_interval_time_t t)


Define Documentation

 
#define check_roll  ) 
 

Value:

if (private_info->roll < TIMER_MATRIX[timer->interval].roll) {  \
                private_info->roll++;                                                                                   \
                private_info->reference = private_info->start = TIMER_MATRIX[timer->interval].tick;     \
        }                                                                                                                                       \

#define IDLE_SPEED   100
 

#define MAX_ELEMENTS   3600
 

#define MAX_TICK   UINT32_MAX - 1024
 

#define MS_PER_TICK   10
 

#define STEP_MIC   1000
 

#define STEP_MS   1
 

#define UINT32_MAX   0xffffffff
 


Typedef Documentation

typedef struct timer_matrix timer_matrix_t
 

typedef struct timer_private timer_private_t
 


Function Documentation

SWITCH_MODULE_DEFINITION CORE_SOFTTIMER_MODULE  ,
softtimer_load  ,
softtimer_shutdown  ,
softtimer_runtime 
 

SWITCH_MODULE_LOAD_FUNCTION softtimer_load   ) 
 

00429 {
00430         switch_timer_interface_t *timer_interface;
00431         module_pool = pool;
00432 
00433         /* connect my internal structure to the blank pointer passed to me */
00434         *module_interface = switch_loadable_module_create_module_interface(pool, modname);
00435         timer_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_TIMER_INTERFACE);
00436         timer_interface->interface_name = "soft";
00437         timer_interface->timer_init = timer_init;
00438         timer_interface->timer_next = timer_next;
00439         timer_interface->timer_step = timer_step;
00440         timer_interface->timer_sync = timer_sync;
00441         timer_interface->timer_check = timer_check;
00442         timer_interface->timer_destroy = timer_destroy;
00443 
00444         /* indicate that the module should continue to be loaded */
00445         return SWITCH_STATUS_SUCCESS;
00446 }

Here is the call graph for this function:

SWITCH_MODULE_RUNTIME_FUNCTION softtimer_runtime   ) 
 

00303 {
00304         switch_time_t too_late = STEP_MIC * 1000;
00305         uint32_t current_ms = 0;
00306         uint32_t x, tick = 0;
00307         switch_time_t ts = 0, last = 0;
00308         int fwd_errs = 0, rev_errs = 0;
00309 
00310         switch_time_sync();
00311 
00312         memset(&globals, 0, sizeof(globals));
00313         switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, module_pool);
00314         
00315         globals.STARTED = globals.RUNNING = 1;
00316         switch_mutex_lock(runtime.throttle_mutex);
00317         runtime.sps = runtime.sps_total;
00318         switch_mutex_unlock(runtime.throttle_mutex);
00319 
00320         if (MONO) {
00321                 int loops;
00322                 for(loops = 0; loops < 3; loops++) {
00323                         ts = time_now(0);
00324                         /* if it returns the same value every time it won't be of much use.*/
00325                         if (ts == last) {
00326                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Broken MONOTONIC Clock Detected!, Support Disabled.\n");
00327                                 MONO = 0;
00328                                 runtime.reference = switch_time_now();
00329                                 runtime.initiated = runtime.reference;
00330                                 break;
00331                         }
00332                         switch_yield(STEP_MIC);
00333                         last = ts;
00334                 }
00335         }
00336 
00337         ts = 0;
00338         last = 0;
00339         fwd_errs = rev_errs = 0;
00340         
00341         while (globals.RUNNING == 1) {
00342                 runtime.reference += STEP_MIC;
00343                 while ((ts = time_now(runtime.offset)) < runtime.reference) {
00344                         if (ts < last) {
00345                                 if (MONO) {
00346                                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Virtual Migration Detected! Syncing Clock\n");
00347                                         switch_time_sync();
00348                                 } else {
00349                                         int64_t diff = (int64_t)(ts - last);
00350                                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Reverse Clock Skew Detected!\n");
00351                                         runtime.reference = switch_time_now();
00352                                         current_ms = 0;
00353                                         tick = 0;
00354                                         runtime.initiated += diff;
00355                                         rev_errs++;
00356                                 }
00357                         } else {
00358                                 rev_errs = 0;
00359                         }
00360                         switch_yield(STEP_MIC);
00361                         last = ts;
00362                 } 
00363                 
00364 
00365                 if (ts > (runtime.reference + too_late)) {
00366                         if (MONO) {
00367                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Virtual Migration Detected! Syncing Clock\n");
00368                                 switch_time_sync();
00369                         } else {
00370                                 switch_time_t diff = ts - runtime.reference - STEP_MIC;
00371                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Forward Clock Skew Detected!\n");
00372                                 fwd_errs++;
00373                                 runtime.reference = switch_time_now();
00374                                 current_ms = 0;
00375                                 tick = 0;
00376                                 runtime.initiated += diff;
00377                         }
00378                 } else {
00379                         fwd_errs = 0;
00380                 }
00381                 
00382                 if (fwd_errs > 9 || rev_errs > 9) {
00383                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Auto Re-Syncing clock.\n");
00384                         switch_time_sync();
00385                         fwd_errs = rev_errs = 0;
00386                 }
00387 
00388                 runtime.timestamp = ts;
00389                 current_ms += STEP_MS;
00390                 tick += STEP_MS;
00391                 
00392                 if (tick >= 1000) {
00393                         if (runtime.sps <= 0) {
00394                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Rate of %d!\n", runtime.sps_total);
00395                         }
00396                         switch_mutex_lock(runtime.throttle_mutex);
00397                         runtime.sps_last = runtime.sps_total - runtime.sps;
00398                         runtime.sps = runtime.sps_total;
00399                         switch_mutex_unlock(runtime.throttle_mutex);
00400                         tick = 0;
00401                 }
00402 
00403                 if ((current_ms % MS_PER_TICK) == 0) {
00404                         for (x = MS_PER_TICK; x <= MAX_ELEMENTS; x += MS_PER_TICK) {
00405                                 if ((current_ms % x) == 0) {
00406                                         if (TIMER_MATRIX[x].count) {
00407                                                 TIMER_MATRIX[x].tick++;
00408                                                 if (TIMER_MATRIX[x].tick == MAX_TICK) {
00409                                                         TIMER_MATRIX[x].tick = 0;
00410                                                         TIMER_MATRIX[x].roll++;
00411                                                 }
00412                                         }
00413                                 }
00414                         }
00415                 }
00416                 if (current_ms == MAX_ELEMENTS) {
00417                         current_ms = 0;
00418                 }
00419         }
00420 
00421         switch_mutex_lock(globals.mutex);
00422         globals.RUNNING = 0;
00423         switch_mutex_unlock(globals.mutex);
00424 
00425         return SWITCH_STATUS_TERM;
00426 }

Here is the call graph for this function:

SWITCH_MODULE_SHUTDOWN_FUNCTION softtimer_shutdown   ) 
 

00449 {
00450 
00451         if (globals.RUNNING) {
00452                 switch_mutex_lock(globals.mutex);
00453                 globals.RUNNING = -1;
00454                 switch_mutex_unlock(globals.mutex);
00455 
00456                 while (globals.RUNNING) {
00457                         switch_yield(10000);
00458                 }
00459         }
00460 
00461 #if defined(WIN32)
00462         timeEndPeriod(1);
00463 #endif
00464 
00465 
00466         return SWITCH_STATUS_SUCCESS;
00467 }

Here is the call graph for this function:


Variable Documentation

switch_mutex_t* mutex
 

int32_t RUNNING
 

int32_t STARTED
 


Generated on Mon May 26 22:06:53 2008 for FreeSWITCH by  doxygen 1.3.9.1