]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
trade some max call count for more accurate timing in full media situations, hint...
authorAnthony Minessale <anthony.minessale@gmail.com>
Tue, 29 Dec 2009 23:21:20 +0000 (23:21 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Tue, 29 Dec 2009 23:21:20 +0000 (23:21 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16081 d0543943-73ff-0310-b7d9-9358b9ac24b2

configure.in
src/include/switch_core.h
src/switch_core.c
src/switch_core_session.c
src/switch_time.c

index 313c83fc77d3d67589cff451220552f18a2202d9..7a4523eeedcb908ce8d67f5415db2cb61e71fc17 100644 (file)
@@ -399,7 +399,7 @@ AC_FUNC_MALLOC
 AC_TYPE_SIGNAL
 AC_FUNC_STRFTIME
 AC_CHECK_FUNCS([gethostname vasprintf mmap mlock mlockall usleep getifaddrs])
-AC_CHECK_FUNCS([sched_setscheduler setpriority setrlimit setgroups initgroups])
+AC_CHECK_FUNCS([sched_setscheduler sched_setaffinity setpriority setrlimit setgroups initgroups])
 AC_CHECK_FUNCS([wcsncmp setgroups asprintf setenv pselect gettimeofday localtime_r gmtime_r strcasecmp stricmp _stricmp])
 
 AC_CHECK_LIB(rt, clock_gettime, [AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Define if you have clock_gettime()])])
index 3bd75e0c5f9b6edb9e5bbf3f9727464d8b492f8e..4f157a0cc85049293fd047d43d9d47e6fd9f41d5 100644 (file)
@@ -1941,6 +1941,7 @@ SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload);
 SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token);
 #define switch_check_network_list_ip(_ip_str, _list_name) switch_check_network_list_ip_token(_ip_str, _list_name, NULL)
 SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable);
+SWITCH_DECLARE(void) switch_time_set_nanosleep(switch_bool_t enable);
 SWITCH_DECLARE(uint32_t) switch_core_min_dtmf_duration(uint32_t duration);
 SWITCH_DECLARE(uint32_t) switch_core_max_dtmf_duration(uint32_t duration);
 SWITCH_DECLARE(uint32_t) switch_core_default_dtmf_duration(uint32_t duration);
index ab61aa602ee9e7678dc31373374c107245df6eba..c1d243580a08b03f9acf89309862d83287c751c9 100644 (file)
@@ -1409,8 +1409,10 @@ static void switch_load_core_config(const char *file)
                                        if (tmp > 0) {
                                                switch_core_default_dtmf_duration((uint32_t) tmp);
                                        }
-                               } else if (!strcasecmp(var, "disable-monotonic-timing")) {
-                                       switch_time_set_monotonic(SWITCH_FALSE);
+                               } else if (!strcasecmp(var, "enable-monotonic-timing")) {
+                                       switch_time_set_monotonic(switch_true(var));
+                               } else if (!strcasecmp(var, "enable-clock-nanosleep")) {
+                                       switch_time_set_nanosleep(switch_true(var));
                                } else if (!strcasecmp(var, "max-sessions") && !zstr(val)) {
                                        switch_core_session_limit(atoi(val));
                                } else if (!strcasecmp(var, "rtp-start-port") && !zstr(val)) {
index 20cd367ccb96e3b024f2ebcd9656517ab20e4f7f..30e0fa4bbfaf55f4e9589b35678f34f084280016 100644 (file)
@@ -1281,13 +1281,13 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_
        switch_mutex_unlock(runtime.throttle_mutex);
 
        if (sps <= 0) {
-               //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Throttle Error!\n");
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Throttle Error! %d\n", session_manager.session_count);
                UNPROTECT_INTERFACE(endpoint_interface);
                return NULL;
        }
 
        if ((count + 1) > session_manager.session_limit) {
-               //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Limit!\n");
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Limit! %d\n", session_manager.session_limit);
                UNPROTECT_INTERFACE(endpoint_interface);
                return NULL;
        }
index 19eb412aea7cbfd0e09016fe80ad26118a18e903..5da9dee5163f7a2a939b64a92b2a02fb6023b818 100644 (file)
@@ -70,6 +70,7 @@ SWITCH_MODULE_DEFINITION(CORE_SOFTTIMER_MODULE, softtimer_load, softtimer_shutdo
 #define IDLE_SPEED 100
 #define STEP_MS 1
 #define STEP_MIC 1000
+#define TICK_PER_SEC 1000
 
 struct timer_private {
        switch_size_t reference;
@@ -85,6 +86,7 @@ struct timer_matrix {
        uint32_t roll;
        switch_mutex_t *mutex;
        switch_thread_cond_t *cond;
+       switch_thread_rwlock_t *rwlock;
 };
 typedef struct timer_matrix timer_matrix_t;
 
@@ -92,23 +94,39 @@ static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS + 1];
 
 static void do_sleep(switch_interval_time_t t)
 {
+#if defined(HAVE_CLOCK_NANOSLEEP) || defined(DARWIN)
+       struct timespec ts;
+#endif
+
 #if defined(WIN32)
        if (t < 1000) {
                t = 1000;
        }
 #endif
 
-#if defined(DARWIN)
-       struct timespec ts;
+#if !defined(DARWIN)
+       if (t > 100000) {
+               apr_sleep(t);
+       }
+#endif
+       
+
+#if defined(HAVE_CLOCK_NANOSLEEP)
+       ts.tv_sec = t / APR_USEC_PER_SEC;
+       ts.tv_nsec = ((t % APR_USEC_PER_SEC) * 1000) - 1000000;
+       clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
+#elif defined(DARWIN)
        ts.tv_sec = t / APR_USEC_PER_SEC;
        ts.tv_nsec = (t % APR_USEC_PER_SEC) * 1000;
-       
        nanosleep(&ts, NULL);
-       sched_yield();
 #else
        apr_sleep(t);
 #endif
 
+#if defined(DARWIN)
+sched_yield();
+#endif
+
 }
 
 SWITCH_DECLARE(switch_time_t) switch_micro_time_now(void)
@@ -132,6 +150,12 @@ static int MONO = 1;
 static int MONO = 0;
 #endif
 
+#if defined(HAVE_CLOCK_NANOSLEEP)
+static int NANO = 1;
+#else
+static int NANO = 0;
+#endif
+
 
 SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable)
 {
@@ -139,6 +163,11 @@ SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable)
        switch_time_sync();
 }
 
+SWITCH_DECLARE(void) switch_time_set_nanosleep(switch_bool_t enable)
+{
+       NANO = enable ? 1 : 0;
+}
+
 static switch_time_t time_now(int64_t offset)
 {
        switch_time_t now;
@@ -334,17 +363,26 @@ 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 (NANO) {
+                       do_sleep(1000 * timer->interval);
+                       continue;
+               }
+
                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); 
+                       if (switch_mutex_lock(TIMER_MATRIX[cond_index].mutex) == SWITCH_STATUS_SUCCESS) {
+                               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);
                        }
-                       switch_mutex_unlock(TIMER_MATRIX[cond_index].mutex);
                } else {
                        do_sleep(1000);
                }
        }
-       
+
        if (globals.RUNNING == 1) {
                return SWITCH_STATUS_SUCCESS;
        }
@@ -406,6 +444,13 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
        switch_time_t ts = 0, last = 0;
        int fwd_errs = 0, rev_errs = 0;
 
+#ifdef HAVE_SCHED_SETAFFINITY
+       cpu_set_t set;
+       CPU_ZERO(&set);
+       CPU_SET(0, &set);
+       sched_setaffinity(0, sizeof(set), &set);
+#endif
+
        switch_time_sync();
 
        globals.STARTED = globals.RUNNING = 1;
@@ -421,6 +466,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
                        if (ts == last) {
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Broken MONOTONIC Clock Detected!, Support Disabled.\n");
                                MONO = 0;
+                               NANO = 0;
                                runtime.reference = switch_time_now();
                                runtime.initiated = runtime.reference;
                                break;
@@ -435,15 +481,16 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
        fwd_errs = rev_errs = 0;
 
 #ifndef DISABLE_1MS_COND
-       switch_mutex_init(&TIMER_MATRIX[1].mutex, SWITCH_MUTEX_NESTED, module_pool);
-       switch_thread_cond_create(&TIMER_MATRIX[1].cond, module_pool);
+       if (!NANO) {
+               switch_mutex_init(&TIMER_MATRIX[1].mutex, SWITCH_MUTEX_NESTED, module_pool);
+               switch_thread_cond_create(&TIMER_MATRIX[1].cond, module_pool);
+       }
 #endif
 
-       globals.use_cond_yield = globals.RUNNING == 1;
-
+       globals.use_cond_yield = globals.RUNNING = 1;
+       
        while (globals.RUNNING == 1) {
                runtime.reference += STEP_MIC;
-
                while ((ts = time_now(runtime.offset)) < runtime.reference) {
                        if (ts < last) {
                                if (MONO) {
@@ -461,11 +508,10 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
                        } else {
                                rev_errs = 0;
                        }
-                       do_sleep(STEP_MIC);
+                       do_sleep(STEP_MIC);             
                        last = ts;
                }
 
-
                if (ts > (runtime.reference + too_late)) {
                        if (MONO) {
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Virtual Migration Detected! Syncing Clock\n");
@@ -495,7 +541,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
                current_ms += STEP_MS;
                tick += STEP_MS;
 
-               if (tick >= 1000) {
+               if (tick >= TICK_PER_SEC) {
                        if (runtime.sps <= 0) {
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Rate of %d!\n", runtime.sps_total);
                        }
@@ -525,9 +571,11 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
                                        if (TIMER_MATRIX[x].count) {
                                                TIMER_MATRIX[x].tick++;
 #ifdef DISABLE_1MS_COND
-                                               if (TIMER_MATRIX[x].mutex && switch_mutex_trylock(TIMER_MATRIX[x].mutex) == SWITCH_STATUS_SUCCESS) {
-                                                       switch_thread_cond_broadcast(TIMER_MATRIX[x].cond);
-                                                       switch_mutex_unlock(TIMER_MATRIX[x].mutex);
+                                               if (!NANO) {
+                                                       if (TIMER_MATRIX[x].mutex && switch_mutex_trylock(TIMER_MATRIX[x].mutex) == SWITCH_STATUS_SUCCESS) {
+                                                               switch_thread_cond_broadcast(TIMER_MATRIX[x].cond);
+                                                               switch_mutex_unlock(TIMER_MATRIX[x].mutex);
+                                                       }
                                                }
 #endif
                                                if (TIMER_MATRIX[x].tick == MAX_TICK) {