mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-02 09:01:46 -05:00
core: Expose API to elevate a thread to realtime priority
This should make it easier for clients to elevate their audio threads to real time priority without having to dig through much through specific system internals.
This commit is contained in:
parent
651a3d108e
commit
878ef44079
17 changed files with 205 additions and 184 deletions
|
|
@ -225,6 +225,7 @@ pa_mainloop_run;
|
|||
pa_mainloop_set_poll_func;
|
||||
pa_mainloop_wakeup;
|
||||
pa_msleep;
|
||||
pa_thread_make_realtime
|
||||
pa_operation_cancel;
|
||||
pa_operation_get_state;
|
||||
pa_operation_ref;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include <pulse/rtclock.h>
|
||||
#include <pulse/timeval.h>
|
||||
#include <pulse/util.h>
|
||||
#include <pulse/volume.h>
|
||||
#include <pulse/xmalloc.h>
|
||||
#include <pulse/internal.h>
|
||||
|
|
@ -1780,7 +1781,7 @@ static void thread_func(void *userdata) {
|
|||
pa_log_debug("Thread starting up");
|
||||
|
||||
if (u->core->realtime_scheduling)
|
||||
pa_make_realtime(u->core->realtime_priority);
|
||||
pa_thread_make_realtime(u->core->realtime_priority);
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include <pulse/rtclock.h>
|
||||
#include <pulse/timeval.h>
|
||||
#include <pulse/util.h>
|
||||
#include <pulse/volume.h>
|
||||
#include <pulse/xmalloc.h>
|
||||
|
||||
|
|
@ -1504,7 +1505,7 @@ static void thread_func(void *userdata) {
|
|||
pa_log_debug("Thread starting up");
|
||||
|
||||
if (u->core->realtime_scheduling)
|
||||
pa_make_realtime(u->core->realtime_priority);
|
||||
pa_thread_make_realtime(u->core->realtime_priority);
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include <pulse/rtclock.h>
|
||||
#include <pulse/timeval.h>
|
||||
#include <pulse/utf8.h>
|
||||
#include <pulse/util.h>
|
||||
|
||||
#include <pulsecore/core-error.h>
|
||||
#include <pulsecore/core-rtclock.h>
|
||||
|
|
@ -1500,7 +1501,7 @@ static void thread_func(void *userdata) {
|
|||
pa_log_debug("IO Thread starting up");
|
||||
|
||||
if (u->core->realtime_scheduling)
|
||||
pa_make_realtime(u->core->realtime_priority);
|
||||
pa_thread_make_realtime(u->core->realtime_priority);
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include <jack/jack.h>
|
||||
|
||||
#include <pulse/util.h>
|
||||
#include <pulse/xmalloc.h>
|
||||
|
||||
#include <pulsecore/sink.h>
|
||||
|
|
@ -224,7 +225,7 @@ static void thread_func(void *userdata) {
|
|||
pa_log_debug("Thread starting up");
|
||||
|
||||
if (u->core->realtime_scheduling)
|
||||
pa_make_realtime(u->core->realtime_priority);
|
||||
pa_thread_make_realtime(u->core->realtime_priority);
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
|
||||
|
|
@ -267,7 +268,7 @@ static void jack_init(void *arg) {
|
|||
pa_log_info("JACK thread starting up.");
|
||||
|
||||
if (u->core->realtime_scheduling)
|
||||
pa_make_realtime(u->core->realtime_priority+4);
|
||||
pa_thread_make_realtime(u->core->realtime_priority+4);
|
||||
}
|
||||
|
||||
/* JACK Callback: This is called when JACK kicks us */
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include <jack/jack.h>
|
||||
|
||||
#include <pulse/util.h>
|
||||
#include <pulse/xmalloc.h>
|
||||
|
||||
#include <pulsecore/source.h>
|
||||
|
|
@ -187,7 +188,7 @@ static void thread_func(void *userdata) {
|
|||
pa_log_debug("Thread starting up");
|
||||
|
||||
if (u->core->realtime_scheduling)
|
||||
pa_make_realtime(u->core->realtime_priority);
|
||||
pa_thread_make_realtime(u->core->realtime_priority);
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
|
||||
|
|
@ -225,7 +226,7 @@ static void jack_init(void *arg) {
|
|||
pa_log_info("JACK thread starting up.");
|
||||
|
||||
if (u->core->realtime_scheduling)
|
||||
pa_make_realtime(u->core->realtime_priority+4);
|
||||
pa_thread_make_realtime(u->core->realtime_priority+4);
|
||||
}
|
||||
|
||||
static void jack_shutdown(void* arg) {
|
||||
|
|
|
|||
|
|
@ -722,7 +722,7 @@ static void thread_func(void *userdata) {
|
|||
pa_log_debug("Thread starting up");
|
||||
|
||||
if (u->module->core->realtime_scheduling)
|
||||
pa_make_realtime(u->module->core->realtime_priority);
|
||||
pa_thread_make_realtime(u->module->core->realtime_priority);
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <pulse/rtclock.h>
|
||||
#include <pulse/timeval.h>
|
||||
#include <pulse/util.h>
|
||||
#include <pulse/xmalloc.h>
|
||||
|
||||
#include <pulsecore/macro.h>
|
||||
|
|
@ -319,7 +320,7 @@ static void thread_func(void *userdata) {
|
|||
pa_log_debug("Thread starting up");
|
||||
|
||||
if (u->core->realtime_scheduling)
|
||||
pa_make_realtime(u->core->realtime_priority+1);
|
||||
pa_thread_make_realtime(u->core->realtime_priority+1);
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
|
||||
|
|
|
|||
|
|
@ -650,7 +650,7 @@ static void thread_func(void *userdata) {
|
|||
pa_log_debug("Thread starting up");
|
||||
|
||||
if (u->core->realtime_scheduling)
|
||||
pa_make_realtime(u->core->realtime_priority);
|
||||
pa_thread_make_realtime(u->core->realtime_priority);
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ static void thread_func(void *userdata) {
|
|||
pa_log_debug("Thread starting up");
|
||||
|
||||
if (u->core->realtime_scheduling)
|
||||
pa_make_realtime(u->core->realtime_priority);
|
||||
pa_thread_make_realtime(u->core->realtime_priority);
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
|
||||
|
|
|
|||
|
|
@ -899,7 +899,7 @@ static void thread_func(void *userdata) {
|
|||
pa_log_debug("Thread starting up");
|
||||
|
||||
if (u->core->realtime_scheduling)
|
||||
pa_make_realtime(u->core->realtime_priority);
|
||||
pa_thread_make_realtime(u->core->realtime_priority);
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
|
||||
|
|
|
|||
176
src/pulse/util.c
176
src/pulse/util.c
|
|
@ -56,6 +56,7 @@
|
|||
#include <pulse/timeval.h>
|
||||
|
||||
#include <pulsecore/socket.h>
|
||||
#include <pulsecore/core-error.h>
|
||||
#include <pulsecore/core-util.h>
|
||||
#include <pulsecore/macro.h>
|
||||
#include <pulsecore/usergroup.h>
|
||||
|
|
@ -71,6 +72,29 @@
|
|||
static int _main() PA_GCC_WEAKREF(main);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PTHREAD
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SCHED_H
|
||||
#include <sched.h>
|
||||
|
||||
#if defined(__linux__) && !defined(SCHED_RESET_ON_FORK)
|
||||
#define SCHED_RESET_ON_FORK 0x40000000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <mach/mach_init.h>
|
||||
#include <mach/thread_act.h>
|
||||
#include <mach/thread_policy.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
#include <pulsecore/rtkit.h>
|
||||
#endif
|
||||
|
||||
char *pa_get_user_name(char *s, size_t l) {
|
||||
const char *p;
|
||||
char *name = NULL;
|
||||
|
|
@ -342,3 +366,155 @@ int pa_msleep(unsigned long t) {
|
|||
#error "Platform lacks a sleep function."
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _POSIX_PRIORITY_SCHEDULING
|
||||
static int set_scheduler(int rtprio) {
|
||||
#ifdef HAVE_SCHED_H
|
||||
struct sched_param sp;
|
||||
#ifdef HAVE_DBUS
|
||||
int r;
|
||||
long long rttime;
|
||||
#ifdef RLIMIT_RTTIME
|
||||
struct rlimit rl;
|
||||
#endif
|
||||
DBusError error;
|
||||
DBusConnection *bus;
|
||||
|
||||
dbus_error_init(&error);
|
||||
#endif
|
||||
|
||||
pa_zero(sp);
|
||||
sp.sched_priority = rtprio;
|
||||
|
||||
#ifdef SCHED_RESET_ON_FORK
|
||||
if (pthread_setschedparam(pthread_self(), SCHED_RR|SCHED_RESET_ON_FORK, &sp) == 0) {
|
||||
pa_log_debug("SCHED_RR|SCHED_RESET_ON_FORK worked.");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pthread_setschedparam(pthread_self(), SCHED_RR, &sp) == 0) {
|
||||
pa_log_debug("SCHED_RR worked.");
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_SCHED_H */
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
/* Try to talk to RealtimeKit */
|
||||
|
||||
if (!(bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error))) {
|
||||
pa_log("Failed to connect to system bus: %s", error.message);
|
||||
dbus_error_free(&error);
|
||||
errno = -EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* We need to disable exit on disconnect because otherwise
|
||||
* dbus_shutdown will kill us. See
|
||||
* https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
|
||||
dbus_connection_set_exit_on_disconnect(bus, FALSE);
|
||||
|
||||
rttime = rtkit_get_rttime_usec_max(bus);
|
||||
if (rttime >= 0) {
|
||||
#ifdef RLIMIT_RTTIME
|
||||
r = getrlimit(RLIMIT_RTTIME, &rl);
|
||||
|
||||
if (r >= 0 && (long long) rl.rlim_max > rttime) {
|
||||
pa_log_info("Clamping rlimit-rttime to %lld for RealtimeKit", rttime);
|
||||
rl.rlim_cur = rl.rlim_max = rttime;
|
||||
r = setrlimit(RLIMIT_RTTIME, &rl);
|
||||
|
||||
if (r < 0)
|
||||
pa_log("setrlimit() failed: %s", pa_cstrerror(errno));
|
||||
}
|
||||
#endif
|
||||
r = rtkit_make_realtime(bus, 0, rtprio);
|
||||
dbus_connection_close(bus);
|
||||
dbus_connection_unref(bus);
|
||||
|
||||
if (r >= 0) {
|
||||
pa_log_debug("RealtimeKit worked.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
errno = -r;
|
||||
} else {
|
||||
dbus_connection_close(bus);
|
||||
dbus_connection_unref(bus);
|
||||
errno = -rttime;
|
||||
}
|
||||
|
||||
#else
|
||||
errno = 0;
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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_thread_make_realtime(int rtprio) {
|
||||
|
||||
#if defined(OS_IS_DARWIN)
|
||||
struct thread_time_constraint_policy ttcpolicy;
|
||||
uint64_t freq = 0;
|
||||
size_t size = sizeof(freq);
|
||||
int ret;
|
||||
|
||||
ret = sysctlbyname("hw.cpufrequency", &freq, &size, NULL, 0);
|
||||
if (ret < 0) {
|
||||
pa_log_info("Unable to read CPU frequency, acquisition of real-time scheduling failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pa_log_debug("sysctl for hw.cpufrequency: %llu", freq);
|
||||
|
||||
/* See http://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/KernelProgramming/scheduler/scheduler.html */
|
||||
ttcpolicy.period = freq / 160;
|
||||
ttcpolicy.computation = freq / 3300;
|
||||
ttcpolicy.constraint = freq / 2200;
|
||||
ttcpolicy.preemptible = 1;
|
||||
|
||||
ret = thread_policy_set(mach_thread_self(),
|
||||
THREAD_TIME_CONSTRAINT_POLICY,
|
||||
(thread_policy_t) &ttcpolicy,
|
||||
THREAD_TIME_CONSTRAINT_POLICY_COUNT);
|
||||
if (ret) {
|
||||
pa_log_info("Unable to set real-time thread priority (%08x).", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pa_log_info("Successfully acquired real-time thread priority.");
|
||||
return 0;
|
||||
|
||||
#elif defined(_POSIX_PRIORITY_SCHEDULING)
|
||||
int p;
|
||||
|
||||
if (set_scheduler(rtprio) >= 0) {
|
||||
pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i.", rtprio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (p = rtprio-1; p >= 1; p--)
|
||||
if (set_scheduler(p) >= 0) {
|
||||
pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i, which is lower than the requested %i.", p, rtprio);
|
||||
return 0;
|
||||
}
|
||||
#elif defined(OS_IS_WIN32)
|
||||
/* Windows only allows realtime scheduling to be set on a per process basis.
|
||||
* Therefore, instead of making the thread realtime, just give it the highest non-realtime priority. */
|
||||
if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL)) {
|
||||
pa_log_info("Successfully enabled THREAD_PRIORITY_TIME_CRITICAL scheduling for thread.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pa_log_warn("SetThreadPriority() failed: 0x%08X", GetLastError());
|
||||
errno = EPERM;
|
||||
#else
|
||||
errno = ENOTSUP;
|
||||
#endif
|
||||
pa_log_info("Failed to acquire real-time scheduling: %s", pa_cstrerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,12 @@ char *pa_path_get_filename(const char *p);
|
|||
/** Wait t milliseconds */
|
||||
int pa_msleep(unsigned long t);
|
||||
|
||||
/** Make the calling thread realtime if we can. On Linux, this uses RealTimeKit
|
||||
* if available and POSIX APIs otherwise (the latter applies to other UNIX
|
||||
* variants as well). This is also implemented for macOS and Windows.
|
||||
* \since 13.0 */
|
||||
int pa_thread_make_realtime(int rtprio);
|
||||
|
||||
PA_C_DECL_END
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -61,14 +61,6 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SCHED_H
|
||||
#include <sched.h>
|
||||
|
||||
#if defined(__linux__) && !defined(SCHED_RESET_ON_FORK)
|
||||
#define SCHED_RESET_ON_FORK 0x40000000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
|
@ -109,15 +101,8 @@
|
|||
#include <samplerate.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <mach/mach_init.h>
|
||||
#include <mach/thread_act.h>
|
||||
#include <mach/thread_policy.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
#include "rtkit.h"
|
||||
#include <pulsecore/rtkit.h>
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && !defined(__ANDROID__)
|
||||
|
|
@ -697,158 +682,6 @@ char *pa_strlcpy(char *b, const char *s, size_t l) {
|
|||
return b;
|
||||
}
|
||||
|
||||
#ifdef _POSIX_PRIORITY_SCHEDULING
|
||||
static int set_scheduler(int rtprio) {
|
||||
#ifdef HAVE_SCHED_H
|
||||
struct sched_param sp;
|
||||
#ifdef HAVE_DBUS
|
||||
int r;
|
||||
long long rttime;
|
||||
#ifdef RLIMIT_RTTIME
|
||||
struct rlimit rl;
|
||||
#endif
|
||||
DBusError error;
|
||||
DBusConnection *bus;
|
||||
|
||||
dbus_error_init(&error);
|
||||
#endif
|
||||
|
||||
pa_zero(sp);
|
||||
sp.sched_priority = rtprio;
|
||||
|
||||
#ifdef SCHED_RESET_ON_FORK
|
||||
if (pthread_setschedparam(pthread_self(), SCHED_RR|SCHED_RESET_ON_FORK, &sp) == 0) {
|
||||
pa_log_debug("SCHED_RR|SCHED_RESET_ON_FORK worked.");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pthread_setschedparam(pthread_self(), SCHED_RR, &sp) == 0) {
|
||||
pa_log_debug("SCHED_RR worked.");
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_SCHED_H */
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
/* Try to talk to RealtimeKit */
|
||||
|
||||
if (!(bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error))) {
|
||||
pa_log("Failed to connect to system bus: %s", error.message);
|
||||
dbus_error_free(&error);
|
||||
errno = -EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* We need to disable exit on disconnect because otherwise
|
||||
* dbus_shutdown will kill us. See
|
||||
* https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
|
||||
dbus_connection_set_exit_on_disconnect(bus, FALSE);
|
||||
|
||||
rttime = rtkit_get_rttime_usec_max(bus);
|
||||
if (rttime >= 0) {
|
||||
#ifdef RLIMIT_RTTIME
|
||||
r = getrlimit(RLIMIT_RTTIME, &rl);
|
||||
|
||||
if (r >= 0 && (long long) rl.rlim_max > rttime) {
|
||||
pa_log_info("Clamping rlimit-rttime to %lld for RealtimeKit", rttime);
|
||||
rl.rlim_cur = rl.rlim_max = rttime;
|
||||
r = setrlimit(RLIMIT_RTTIME, &rl);
|
||||
|
||||
if (r < 0)
|
||||
pa_log("setrlimit() failed: %s", pa_cstrerror(errno));
|
||||
}
|
||||
#endif
|
||||
r = rtkit_make_realtime(bus, 0, rtprio);
|
||||
dbus_connection_close(bus);
|
||||
dbus_connection_unref(bus);
|
||||
|
||||
if (r >= 0) {
|
||||
pa_log_debug("RealtimeKit worked.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
errno = -r;
|
||||
} else {
|
||||
dbus_connection_close(bus);
|
||||
dbus_connection_unref(bus);
|
||||
errno = -rttime;
|
||||
}
|
||||
|
||||
#else
|
||||
errno = 0;
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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) {
|
||||
|
||||
#if defined(OS_IS_DARWIN)
|
||||
struct thread_time_constraint_policy ttcpolicy;
|
||||
uint64_t freq = 0;
|
||||
size_t size = sizeof(freq);
|
||||
int ret;
|
||||
|
||||
ret = sysctlbyname("hw.cpufrequency", &freq, &size, NULL, 0);
|
||||
if (ret < 0) {
|
||||
pa_log_info("Unable to read CPU frequency, acquisition of real-time scheduling failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pa_log_debug("sysctl for hw.cpufrequency: %llu", freq);
|
||||
|
||||
/* See http://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/KernelProgramming/scheduler/scheduler.html */
|
||||
ttcpolicy.period = freq / 160;
|
||||
ttcpolicy.computation = freq / 3300;
|
||||
ttcpolicy.constraint = freq / 2200;
|
||||
ttcpolicy.preemptible = 1;
|
||||
|
||||
ret = thread_policy_set(mach_thread_self(),
|
||||
THREAD_TIME_CONSTRAINT_POLICY,
|
||||
(thread_policy_t) &ttcpolicy,
|
||||
THREAD_TIME_CONSTRAINT_POLICY_COUNT);
|
||||
if (ret) {
|
||||
pa_log_info("Unable to set real-time thread priority (%08x).", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pa_log_info("Successfully acquired real-time thread priority.");
|
||||
return 0;
|
||||
|
||||
#elif defined(_POSIX_PRIORITY_SCHEDULING)
|
||||
int p;
|
||||
|
||||
if (set_scheduler(rtprio) >= 0) {
|
||||
pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i.", rtprio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (p = rtprio-1; p >= 1; p--)
|
||||
if (set_scheduler(p) >= 0) {
|
||||
pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i, which is lower than the requested %i.", p, rtprio);
|
||||
return 0;
|
||||
}
|
||||
#elif defined(OS_IS_WIN32)
|
||||
/* Windows only allows realtime scheduling to be set on a per process basis.
|
||||
* Therefore, instead of making the thread realtime, just give it the highest non-realtime priority. */
|
||||
if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL)) {
|
||||
pa_log_info("Successfully enabled THREAD_PRIORITY_TIME_CRITICAL scheduling for thread.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pa_log_warn("SetThreadPriority() failed: 0x%08X", GetLastError());
|
||||
errno = EPERM;
|
||||
#else
|
||||
errno = ENOTSUP;
|
||||
#endif
|
||||
pa_log_info("Failed to acquire real-time scheduling: %s", pa_cstrerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
static int set_nice(int nice_level) {
|
||||
#ifdef HAVE_DBUS
|
||||
|
|
@ -935,7 +768,7 @@ int pa_raise_priority(int nice_level) {
|
|||
}
|
||||
|
||||
/* Reset the priority to normal, inverting the changes made by
|
||||
* pa_raise_priority() and pa_make_realtime()*/
|
||||
* pa_raise_priority() and pa_thread_make_realtime()*/
|
||||
void pa_reset_priority(void) {
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
struct sched_param sp;
|
||||
|
|
|
|||
|
|
@ -81,7 +81,6 @@ char *pa_strlcpy(char *b, const char *s, size_t l);
|
|||
|
||||
char *pa_parent_dir(const char *fn);
|
||||
|
||||
int pa_make_realtime(int rtprio);
|
||||
int pa_raise_priority(int nice_level);
|
||||
void pa_reset_priority(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ static void context_state_callback(pa_context *c, void *userdata) {
|
|||
case PA_CONTEXT_READY: {
|
||||
pa_buffer_attr buffer_attr;
|
||||
|
||||
pa_make_realtime(4);
|
||||
pa_thread_make_realtime(4);
|
||||
|
||||
/* Create playback stream */
|
||||
buffer_attr.maxlength = -1;
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ static void work(void *p) {
|
|||
|
||||
pa_log_notice("CPU%i: Created thread.", PA_PTR_TO_UINT(p));
|
||||
|
||||
pa_make_realtime(12);
|
||||
pa_thread_make_realtime(12);
|
||||
|
||||
#ifdef HAVE_PTHREAD_SETAFFINITY_NP
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue