]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
switch to conditional broadcast mode on slow kernels
authorAnthony Minessale <anthony.minessale@gmail.com>
Thu, 14 Jan 2010 16:02:46 +0000 (16:02 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Thu, 14 Jan 2010 16:02:46 +0000 (16:02 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16308 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/private/switch_core_pvt.h
src/include/switch_core.h
src/include/switch_types.h
src/mod/applications/mod_commands/mod_commands.c
src/switch_core.c
src/switch_time.c

index 5b13cdea62fbb996327ce30c1d4b026d38fda994..8f2ef2a3095297d1cd1f7687ee6f6ee60dbd3d48 100644 (file)
@@ -215,6 +215,7 @@ struct switch_runtime {
        char *odbc_pass;
        uint32_t debug_level;
        uint32_t runlevel;
+       uint32_t tipping_point;
 };
 
 extern struct switch_runtime runtime;
index 9ec21f039ce4a90ff25dc8bf93fa599b1a45712a..19aea4337795ce29fa82e36f770151ca09f8ca43 100644 (file)
@@ -1238,6 +1238,8 @@ SWITCH_DECLARE(void) switch_hash_this(_In_ switch_hash_index_t *hi, _Out_opt_ptr
 SWITCH_DECLARE(switch_status_t) switch_core_timer_init(switch_timer_t *timer, const char *timer_name, int interval, int samples,
                                                                                                           switch_memory_pool_t *pool);
 
+SWITCH_DECLARE(void) switch_time_calibrate_clock(void);
+
 /*! 
   \brief Wait for one cycle on an existing timer
   \param timer the timer to wait on
index fb00af9314ea2a7feb18f469374a810ad908f6d7..b0e73eae1073e24f6db6f2cc64db639899dde739 100644 (file)
@@ -1436,7 +1436,8 @@ typedef enum {
        SCSC_SEND_SIGHUP,
        SCSC_DEBUG_LEVEL,
        SCSC_FLUSH_DB_HANDLES,
-       SCSC_SHUTDOWN_NOW
+       SCSC_SHUTDOWN_NOW,
+       SCSC_CALIBRATE_CLOCK
 } switch_session_ctl_t;
 
 typedef enum {
index d052422b1a7ee736b5cd1bbd5a0a9d8677648d7c..085c5cfe10471428751eccd0908602b83df0dbb7 100644 (file)
@@ -1470,6 +1470,8 @@ SWITCH_STANDARD_API(ctl_function)
                        arg = 0;
                        switch_core_session_ctl(SCSC_PAUSE_INBOUND, &arg);
                        stream->write_function(stream, "+OK\n");
+               } else if (!strcasecmp(argv[0], "calibrate_clock")) {
+                       switch_core_session_ctl(SCSC_CALIBRATE_CLOCK, NULL);
                } else if (!strcasecmp(argv[0], "shutdown")) {
                        switch_session_ctl_t command = SCSC_SHUTDOWN;
                        int x = 0;
index bbf016feee26767e7787fc601759082b6875b659..f0e6bd113cf988ef7f2e91387eef469768f59925 100644 (file)
@@ -1301,7 +1301,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc
        switch_rtp_init(runtime.memory_pool);
 
        runtime.running = 1;
-
+       runtime.tipping_point = 1000;
        runtime.initiated = switch_time_now();
 
        switch_scheduler_add_task(switch_epoch_time_now(NULL), heartbeat_callback, "heartbeat", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL);
@@ -1442,6 +1442,8 @@ static void switch_load_core_config(const char *file)
                                        switch_time_set_matrix(switch_true(var));
                                } else if (!strcasecmp(var, "max-sessions") && !zstr(val)) {
                                        switch_core_session_limit(atoi(val));
+                               } else if (!strcasecmp(var, "tipping-point") && !zstr(val)) {
+                                       runtime.tipping_point = atoi(val);
                                } else if (!strcasecmp(var, "rtp-start-port") && !zstr(val)) {
                                        switch_rtp_set_start_port((switch_port_t) atoi(val));
                                } else if (!strcasecmp(var, "rtp-end-port") && !zstr(val)) {
@@ -1605,6 +1607,9 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, int32_
        }
 
        switch (cmd) {
+       case SCSC_CALIBRATE_CLOCK:
+               switch_time_calibrate_clock();
+               break;
        case SCSC_FLUSH_DB_HANDLES:
                switch_cache_db_flush_handles();
                break;
index c8768e55be8b703e8acb8faf96a30b969e28c044..a50a1d51b656172a85a343ab982fb5eee5b7eb70 100644 (file)
@@ -177,7 +177,7 @@ static switch_interval_time_t average_time(switch_interval_time_t t, int reps)
 }
 
 #define calc_step() if (step > 11) step -= 10; else if (step > 1) step--
-static void calibrate_clock(void)
+SWITCH_DECLARE(void) switch_time_calibrate_clock(void)
 {
        int x;
        switch_interval_time_t avg, val = 1000, want = 1000;
@@ -188,15 +188,18 @@ static void calibrate_clock(void)
        clock_getres(CLOCK_MONOTONIC, &ts);
        if (ts.tv_nsec / 1000 > 1500) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
-                                               "Timer resolution of %ld microseconds detected!\n"
-                                               "Do you have your kernel timer set to higher than 1khz? You may experience audio problems.\n", ts.tv_nsec / 1000);
-               sleep(5);
+                                                 "Timer resolution of %ld microseconds detected!\n"
+                                                 "Do you have your kernel timer set to higher than 1khz? You may experience audio problems.\n", ts.tv_nsec / 1000);
+               do_sleep(5000000);
+               switch_time_set_cond_yield(SWITCH_TRUE);
                return;
        }
 #endif
 
+       OFFSET = 0;
+       
        for (x = 0; x < 500; x++) {
-               avg = average_time(val, 100);
+               avg = average_time(val, 50);
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Test: %ld Average: %ld Step: %d\n", (long)val, (long)avg, step);
 
                diff = abs((int)(want - avg));
@@ -204,11 +207,8 @@ static void calibrate_clock(void)
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, 
                                                          "Abnormally large timer gap %d detected!\n"
                                                          "Do you have your kernel timer set to higher than 1khz? You may experience audio problems.\n", diff);
-#ifdef WIN32
-                       Sleep(5*1000);
-#else
-                       sleep(5);
-#endif
+                       do_sleep(5000000);
+                       switch_time_set_cond_yield(SWITCH_TRUE);
                        return;
                }
 
@@ -220,12 +220,12 @@ static void calibrate_clock(void)
                        }
                } else if (avg > want) {
                        if (under) {calc_step();}
-                       under = 0;
+                       under = good = 0;
                        val -= step;
                        over++;
                } else if (avg < want) {
                        if (over) {calc_step();}
-                       over = 0;
+                       over = good = 0;
                        val += step;
                        under++;
                }
@@ -261,15 +261,6 @@ SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable)
 SWITCH_DECLARE(void) switch_time_set_matrix(switch_bool_t enable)
 {
        MATRIX = enable ? 1 : 0;
-       if (MATRIX) {
-               STEP_MS = 1;
-               STEP_MIC = 1000;
-               TICK_PER_SEC = 10000;
-       } else {
-               STEP_MS = 10;
-               STEP_MIC = 10000;
-               TICK_PER_SEC = 1000;
-       }
        switch_time_sync();
 }
 
@@ -286,6 +277,7 @@ SWITCH_DECLARE(void) switch_time_set_cond_yield(switch_bool_t enable)
        if (COND) {
                MATRIX = 1;
        }
+       switch_time_sync();
 }
 
 static switch_time_t time_now(int64_t offset)
@@ -498,15 +490,15 @@ static switch_status_t timer_next(switch_timer_t *timer)
        while (globals.RUNNING == 1 && private_info->ready && TIMER_MATRIX[timer->interval].tick < private_info->reference) {
                check_roll();
                
-               if (globals.use_cond_yield == 1) {
-                       switch_mutex_lock(TIMER_MATRIX[cond_index].mutex);
-                       if (TIMER_MATRIX[timer->interval].tick < private_info->reference) {
-                               switch_thread_cond_wait(TIMER_MATRIX[cond_index].cond, TIMER_MATRIX[cond_index].mutex); 
-                       }
-                       switch_mutex_unlock(TIMER_MATRIX[cond_index].mutex);
+               if (session_manager.session_count > runtime.tipping_point) {
+                       os_yield();
                } else {
-                       if (session_manager.session_count > 1000) {
-                               os_yield();
+                       if (globals.use_cond_yield == 1) {
+                               switch_mutex_lock(TIMER_MATRIX[cond_index].mutex);
+                               if (TIMER_MATRIX[timer->interval].tick < private_info->reference) {
+                                       switch_thread_cond_wait(TIMER_MATRIX[cond_index].cond, TIMER_MATRIX[cond_index].mutex); 
+                               }
+                               switch_mutex_unlock(TIMER_MATRIX[cond_index].mutex);
                        } else {
                                do_sleep(1000);
                        }
@@ -640,10 +632,10 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
                                rev_errs = 0;
                        }
 
-                       if (session_manager.session_count > 1000) {
+                       if (session_manager.session_count > runtime.tipping_point) {
                                os_yield();
                        } else {
-                               do_sleep(STEP_MIC);
+                               do_sleep(1000);
                        }
 
                        last = ts;
@@ -952,7 +944,7 @@ SWITCH_MODULE_LOAD_FUNCTION(softtimer_load)
        timer_interface->timer_destroy = timer_destroy;
 
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Calibrating timer, please wait...\n");
-       calibrate_clock();
+       switch_time_calibrate_clock();
 
        /* indicate that the module should continue to be loaded */
        return SWITCH_STATUS_SUCCESS;