mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-02 09:01:46 -05:00
core: ask RealtimeKit for RT scheduling
This commit is contained in:
parent
6ad3855639
commit
8474fd7c62
4 changed files with 337 additions and 20 deletions
|
|
@ -50,6 +50,10 @@
|
|||
|
||||
#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
|
||||
|
|
@ -92,6 +96,10 @@
|
|||
#include <xlocale.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
#include "rtkit.h"
|
||||
#endif
|
||||
|
||||
#include <pulse/xmalloc.h>
|
||||
#include <pulse/util.h>
|
||||
#include <pulse/utf8.h>
|
||||
|
|
@ -552,16 +560,68 @@ char *pa_strlcpy(char *b, const char *s, size_t l) {
|
|||
return b;
|
||||
}
|
||||
|
||||
static int set_scheduler(int rtprio) {
|
||||
struct sched_param sp;
|
||||
int r;
|
||||
#ifdef HAVE_DBUS
|
||||
DBusError error;
|
||||
DBusConnection *bus;
|
||||
|
||||
dbus_error_init(&error);
|
||||
#endif
|
||||
|
||||
pa_zero(sp);
|
||||
sp.sched_priority = rtprio;
|
||||
|
||||
#ifdef SCHED_RESET_ON_FORK
|
||||
if ((r = 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 ((r = pthread_setschedparam(pthread_self(), SCHED_RR, &sp)) == 0) {
|
||||
pa_log_debug("SCHED_RR worked.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
/* Try to talk to RealtimeKit */
|
||||
|
||||
if (!(bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) {
|
||||
pa_log("Failed to connect to system bus: %s\n", error.message);
|
||||
dbus_error_free(&error);
|
||||
errno = -EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = rtkit_make_realtime(bus, 0, rtprio);
|
||||
dbus_connection_unref(bus);
|
||||
|
||||
if (r >= 0) {
|
||||
pa_log_debug("RealtimeKit worked.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
errno = -r;
|
||||
#else
|
||||
errno = r;
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
int r, policy;
|
||||
struct sched_param sp;
|
||||
int rtprio_try;
|
||||
|
||||
memset(&sp, 0, sizeof(sp));
|
||||
pa_zero(sp);
|
||||
policy = 0;
|
||||
|
||||
if ((r = pthread_getschedparam(pthread_self(), &policy, &sp)) != 0) {
|
||||
|
|
@ -569,29 +629,29 @@ int pa_make_realtime(int rtprio) {
|
|||
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);
|
||||
#ifdef SCHED_RESET_ON_FORK
|
||||
policy &= ~SCHED_RESET_ON_FORK;
|
||||
#endif
|
||||
|
||||
if ((policy == SCHED_FIFO || policy == SCHED_RR) && sp.sched_priority >= rtprio) {
|
||||
pa_log_info("Thread already being scheduled with SCHED_FIFO/SCHED_RR with priority %i.", sp.sched_priority);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 -1;
|
||||
if (set_scheduler(rtprio) >= 0) {
|
||||
pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i.", rtprio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread, with priority %i.", sp.sched_priority);
|
||||
return 0;
|
||||
for (rtprio_try = rtprio-1; rtprio_try >= 1; rtprio_try--) {
|
||||
if (set_scheduler(rtprio_try)) {
|
||||
pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i, which is lower than the requested %i.", rtprio_try, rtprio);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
pa_log_warn("Failed to acquire real-time scheduling: %s", pa_cstrerror(r));
|
||||
return -1;
|
||||
#else
|
||||
|
||||
errno = ENOTSUP;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue