From 7bfd1b2f01613dd14b9ca478ae530c1641aa46a1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 1 Nov 2007 02:58:26 +0000 Subject: make rtprio and nice level actually configurable git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@2014 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/main.c | 7 ++-- src/modules/module-alsa-sink.c | 4 +- src/modules/module-alsa-source.c | 4 +- src/modules/module-combine.c | 4 +- src/modules/module-jack-sink.c | 8 ++-- src/modules/module-jack-source.c | 8 ++-- src/modules/module-oss.c | 4 +- src/pulsecore/core-util.c | 87 +++++++++++++++++++++++++++++----------- src/pulsecore/core-util.h | 4 +- src/pulsecore/core.c | 11 +++-- src/pulsecore/core.h | 7 ++-- 11 files changed, 94 insertions(+), 54 deletions(-) diff --git a/src/daemon/main.c b/src/daemon/main.c index 249131e0..01cbba18 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -419,9 +419,9 @@ int main(int argc, char *argv[]) { pa_log_set_target(conf->auto_log_target ? PA_LOG_STDERR : conf->log_target, NULL); if (conf->high_priority && conf->cmd == PA_CMD_DAEMON) - pa_raise_priority(); + pa_raise_priority(conf->nice_level); - if (suid_root && (conf->cmd != PA_CMD_DAEMON || !conf->high_priority)) { + if (suid_root && (conf->cmd != PA_CMD_DAEMON || !conf->realtime_scheduling)) { pa_drop_caps(); pa_drop_root(); } @@ -636,7 +636,6 @@ int main(int argc, char *argv[]) { } c->is_system_instance = !!conf->system_instance; - c->high_priority = !!conf->high_priority; c->default_sample_spec = conf->default_sample_spec; c->default_n_fragments = conf->default_n_fragments; c->default_fragment_size_msec = conf->default_fragment_size_msec; @@ -645,6 +644,8 @@ int main(int argc, char *argv[]) { c->module_idle_time = conf->module_idle_time; c->scache_idle_time = conf->scache_idle_time; c->resample_method = conf->resample_method; + c->realtime_priority = conf->realtime_priority; + c->realtime_scheduling = !!conf->realtime_scheduling; pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0); pa_signal_new(SIGINT, signal_callback, c); diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index a09247fe..88594cda 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -603,8 +603,8 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); - if (u->core->high_priority) - pa_make_realtime(); + if (u->core->realtime_scheduling) + pa_make_realtime(u->core->realtime_priority); pa_thread_mq_install(&u->thread_mq); pa_rtpoll_install(u->rtpoll); diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index d840cac3..a862657f 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -592,8 +592,8 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); - if (u->core->high_priority) - pa_make_realtime(); + if (u->core->realtime_scheduling) + pa_make_realtime(u->core->realtime_priority); pa_thread_mq_install(&u->thread_mq); pa_rtpoll_install(u->rtpoll); diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 665bf9dd..aca4ba32 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -233,8 +233,8 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); - if (u->core->high_priority) - pa_make_realtime(); + if (u->core->realtime_scheduling) + pa_make_realtime(u->core->realtime_priority+1); pa_thread_mq_install(&u->thread_mq); pa_rtpoll_install(u->rtpoll); diff --git a/src/modules/module-jack-sink.c b/src/modules/module-jack-sink.c index 2cf8a58c..840867ce 100644 --- a/src/modules/module-jack-sink.c +++ b/src/modules/module-jack-sink.c @@ -214,8 +214,8 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); - if (u->core->high_priority) - pa_make_realtime(); + if (u->core->realtime_scheduling) + pa_make_realtime(u->core->realtime_priority); pa_thread_mq_install(&u->thread_mq); pa_rtpoll_install(u->rtpoll); @@ -253,8 +253,8 @@ static void jack_init(void *arg) { pa_log_info("JACK thread starting up."); - if (u->core->high_priority) - pa_make_realtime(); + if (u->core->realtime_scheduling) + pa_make_realtime(u->core->realtime_priority+4); } static void jack_shutdown(void* arg) { diff --git a/src/modules/module-jack-source.c b/src/modules/module-jack-source.c index b62ebe7a..380f87eb 100644 --- a/src/modules/module-jack-source.c +++ b/src/modules/module-jack-source.c @@ -191,8 +191,8 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); - if (u->core->high_priority) - pa_make_realtime(); + if (u->core->realtime_scheduling) + pa_make_realtime(u->core->realtime_priority); pa_thread_mq_install(&u->thread_mq); pa_rtpoll_install(u->rtpoll); @@ -230,8 +230,8 @@ static void jack_init(void *arg) { pa_log_info("JACK thread starting up."); - if (u->core->high_priority) - pa_make_realtime(); + if (u->core->realtime_scheduling) + pa_make_realtime(u->core->realtime_priority+4); } static void jack_shutdown(void* arg) { diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 19dceef2..51ab8a85 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -863,8 +863,8 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); - if (u->core->high_priority) - pa_make_realtime(); + if (u->core->realtime_scheduling) + pa_make_realtime(u->core->realtime_priority); pa_thread_mq_install(&u->thread_mq); pa_rtpoll_install(u->rtpoll); diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 3e70eb5c..1a62bce4 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -512,8 +512,10 @@ char *pa_strlcpy(char *b, const char *s, size_t l) { return b; } -/* Make the current thread a realtime thread*/ -void pa_make_realtime(void) { +/* Make the current thread a realtime thread, and acquire the highest + * rtprio we can get that is less or equal the specified parameter. If + * the thread is already realtime, don't do anything. */ +int pa_make_realtime(int rtprio) { #ifdef _POSIX_PRIORITY_SCHEDULING struct sched_param sp; @@ -524,50 +526,87 @@ void pa_make_realtime(void) { if ((r = pthread_getschedparam(pthread_self(), &policy, &sp)) != 0) { pa_log("pthread_getschedgetparam(): %s", pa_cstrerror(r)); - return; + return -1; + } + + if (policy == SCHED_FIFO && sp.sched_priority >= rtprio) { + pa_log_info("Thread already being scheduled with SCHED_FIFO with priority %i.", sp.sched_priority); + return 0; } - sp.sched_priority = 1; + sp.sched_priority = rtprio; if ((r = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp)) != 0) { + + while (sp.sched_priority > 1) { + sp.sched_priority --; + + if ((r = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp)) == 0) { + pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread, with priority %i, which is lower than the requested %i.", sp.sched_priority, rtprio); + return 0; + } + } + pa_log_warn("pthread_setschedparam(): %s", pa_cstrerror(r)); - return; + return -1; } - pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread."); + pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread, with priority %i.", sp.sched_priority); + return 0; +#else + return -1; #endif - } -#define NICE_LEVEL (-11) - -/* Raise the priority of the current process as much as possible and -sensible: set the nice level to -11.*/ -void pa_raise_priority(void) { +/* Raise the priority of the current process as much as possible that + * is <= the specified nice level..*/ +int pa_raise_priority(int nice_level) { #ifdef HAVE_SYS_RESOURCE_H - if (setpriority(PRIO_PROCESS, 0, NICE_LEVEL) < 0) + if (setpriority(PRIO_PROCESS, 0, nice_level) < 0) { + int n; + + for (n = nice_level+1; n < 0; n++) { + + if (setpriority(PRIO_PROCESS, 0, n) == 0) { + pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n, nice_level); + return 0; + } + } + pa_log_warn("setpriority(): %s", pa_cstrerror(errno)); - else - pa_log_info("Successfully gained nice level %i.", NICE_LEVEL); + return -1; + } + + pa_log_info("Successfully gained nice level %i.", nice_level); #endif #ifdef OS_IS_WIN32 - if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) - pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError()); - else - pa_log_info("Successfully gained high priority class."); + if (nice_level < 0) { + if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) { + pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError()); + return .-1; + } else + pa_log_info("Successfully gained high priority class."); + } #endif + + return 0; } /* Reset the priority to normal, inverting the changes made by - * pa_raise_priority() */ + * pa_raise_priority() and pa_make_realtime()*/ void pa_reset_priority(void) { -#ifdef OS_IS_WIN32 - SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); -#endif - #ifdef HAVE_SYS_RESOURCE_H + struct sched_param sp; + setpriority(PRIO_PROCESS, 0, 0); + + memset(&sp, 0, sizeof(sp)); + pa_assert_se(pthread_setschedparam(pthread_self(), SCHED_OTHER, &sp) == 0); +#endif + +#ifdef OS_IS_WIN32 + SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); #endif } diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index a6d22101..c8760a1f 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -57,8 +57,8 @@ char *pa_strlcpy(char *b, const char *s, size_t l); char *pa_parent_dir(const char *fn); -void pa_make_realtime(void); -void pa_raise_priority(void); +int pa_make_realtime(int rtprio); +int pa_raise_priority(int nice_level); void pa_reset_priority(void); int pa_parse_boolean(const char *s) PA_GCC_PURE; diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c index e67f15b5..9b420c94 100644 --- a/src/pulsecore/core.c +++ b/src/pulsecore/core.c @@ -107,7 +107,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { c->scache = NULL; c->autoload_idxset = NULL; c->autoload_hashmap = NULL; - c->running_as_daemon = 0; + c->running_as_daemon = FALSE; c->default_sample_spec.format = PA_SAMPLE_S16NE; c->default_sample_spec.rate = 44100; @@ -134,10 +134,10 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { c->resample_method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 3; - c->is_system_instance = 0; - c->disallow_module_loading = 0; - c->high_priority = 0; - + c->is_system_instance = FALSE; + c->disallow_module_loading = FALSE; + c->realtime_scheduling = FALSE; + c->realtime_priority = 5; for (j = 0; j < PA_CORE_HOOK_MAX; j++) pa_hook_init(&c->hooks[j], c); @@ -217,4 +217,3 @@ void pa_core_check_quit(pa_core *c) { c->quit_event = NULL; } } - diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index dfa80f8d..9aeb7888 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -113,10 +113,11 @@ struct pa_core { pa_time_event *scache_auto_unload_event; - int disallow_module_loading, running_as_daemon; + pa_bool_t disallow_module_loading, running_as_daemon; pa_resample_method_t resample_method; - int is_system_instance; - int high_priority; + pa_bool_t is_system_instance; + pa_bool_t realtime_scheduling; + int realtime_priority; /* hooks */ pa_hook hooks[PA_CORE_HOOK_MAX]; -- cgit