mirror of
https://gitlab.freedesktop.org/pipewire/pipewire
synced 2024-10-15 12:22:47 +00:00
modules: Drop module-rt
This commit is contained in:
parent
69338f797a
commit
6fc966f385
|
@ -73,7 +73,6 @@ List of known modules:
|
|||
- \subpage page_module_raop_discover
|
||||
- \subpage page_module_roc_sink
|
||||
- \subpage page_module_roc_source
|
||||
- \subpage page_module_rt
|
||||
- \subpage page_module_rtkit
|
||||
- \subpage page_module_session_manager
|
||||
- \subpage page_module_zeroconf_discover
|
||||
|
|
|
@ -35,7 +35,7 @@ context.modules = [
|
|||
#
|
||||
#
|
||||
# Boost the data thread priority.
|
||||
{ name = libpipewire-module-rt
|
||||
{ name = libpipewire-module-rtkit
|
||||
args = {
|
||||
#nice.level = -11
|
||||
#rt.prio = 88
|
||||
|
|
|
@ -68,7 +68,9 @@ context.modules = [
|
|||
# If nofail is given, module initialization failures are ignored.
|
||||
#
|
||||
|
||||
# Uses RTKit to boost the data thread priority.
|
||||
# Use realtime scheduling to boost the audio thread priorities. This uses
|
||||
# RTKit if the user doesn't have permission to use regular realtime
|
||||
# scheduling.
|
||||
{ name = libpipewire-module-rtkit
|
||||
args = {
|
||||
#nice.level = -11
|
||||
|
@ -79,17 +81,6 @@ context.modules = [
|
|||
flags = [ ifexists nofail ]
|
||||
}
|
||||
|
||||
# Set thread priorities without using RTKit.
|
||||
#{ name = libpipewire-module-rt
|
||||
# args = {
|
||||
# nice.level = -11
|
||||
# rt.prio = 88
|
||||
# rt.time.soft = 2000000
|
||||
# rt.time.hard = 2000000
|
||||
# }
|
||||
# flags = [ ifexists nofail ]
|
||||
#}
|
||||
|
||||
# The native communication protocol.
|
||||
{ name = libpipewire-module-protocol-native }
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ module_sources = [
|
|||
'module-protocol-pulse.c',
|
||||
'module-protocol-simple.c',
|
||||
'module-pulse-tunnel.c',
|
||||
'module-rt.c',
|
||||
'module-rtkit.c',
|
||||
'module-raop-discover.c',
|
||||
'module-session-manager.c',
|
||||
|
@ -137,18 +136,6 @@ pipewire_module_profiler = shared_library('pipewire-module-profiler',
|
|||
dependencies : [spa_dep, mathlib, dl_lib, pipewire_dep],
|
||||
)
|
||||
|
||||
build_module_rt = build_machine.system() == 'linux'
|
||||
if build_module_rt
|
||||
pipewire_module_rt = shared_library('pipewire-module-rt', [ 'module-rt.c' ],
|
||||
include_directories : [configinc],
|
||||
install : true,
|
||||
install_dir : modules_install_dir,
|
||||
install_rpath: modules_install_dir,
|
||||
dependencies : [dl_lib, pipewire_dep],
|
||||
)
|
||||
endif
|
||||
summary({'rt': build_module_rt}, bool_yn: true, section: 'Optional Modules')
|
||||
|
||||
build_module_rtkit = dbus_dep.found()
|
||||
if build_module_rtkit
|
||||
pipewire_module_rtkit = shared_library('pipewire-module-rtkit', [ 'module-rtkit.c' ],
|
||||
|
|
|
@ -1,277 +0,0 @@
|
|||
/* PipeWire
|
||||
*
|
||||
* Copyright © 2021 Axis Communications AB
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <spa/utils/dict.h>
|
||||
#include <spa/utils/result.h>
|
||||
|
||||
#include <pipewire/impl.h>
|
||||
#include <pipewire/thread.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/** \page page_module_rt PipeWire Module: RT
|
||||
*/
|
||||
|
||||
|
||||
#define NAME "rt"
|
||||
|
||||
PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
|
||||
#define PW_LOG_TOPIC_DEFAULT mod_topic
|
||||
|
||||
#define DEFAULT_POLICY SCHED_FIFO
|
||||
|
||||
#define DEFAULT_NICE_LEVEL -11
|
||||
#define DEFAULT_RT_PRIO 88
|
||||
#define DEFAULT_RT_TIME_SOFT 2000000
|
||||
#define DEFAULT_RT_TIME_HARD 2000000
|
||||
|
||||
#define MODULE_USAGE \
|
||||
"[nice.level=<priority: default " SPA_STRINGIFY(DEFAULT_NICE_LEVEL) ">] " \
|
||||
"[rt.prio=<priority: default " SPA_STRINGIFY(DEFAULT_RT_PRIO) ">] " \
|
||||
"[rt.time.soft=<in usec: default " SPA_STRINGIFY(DEFAULT_RT_TIME_SOFT)"] " \
|
||||
"[rt.time.hard=<in usec: default " SPA_STRINGIFY(DEFAULT_RT_TIME_HARD)"] "
|
||||
|
||||
#ifndef RLIMIT_RTTIME
|
||||
#define RLIMIT_RTTIME 15
|
||||
#endif
|
||||
|
||||
static const struct spa_dict_item module_props[] = {
|
||||
{ PW_KEY_MODULE_AUTHOR, "Jonas Holmberg <jonashg@axis.com>" },
|
||||
{ PW_KEY_MODULE_DESCRIPTION, "Set thread priorities" },
|
||||
{ PW_KEY_MODULE_USAGE, MODULE_USAGE },
|
||||
{ PW_KEY_MODULE_VERSION, PACKAGE_VERSION },
|
||||
};
|
||||
|
||||
struct impl {
|
||||
struct pw_context *context;
|
||||
|
||||
struct spa_thread_utils thread_utils;
|
||||
|
||||
int rt_prio;
|
||||
rlim_t rt_time_soft;
|
||||
rlim_t rt_time_hard;
|
||||
|
||||
struct spa_hook module_listener;
|
||||
};
|
||||
|
||||
static void module_destroy(void *data)
|
||||
{
|
||||
struct impl *impl = data;
|
||||
pw_thread_utils_set(NULL);
|
||||
spa_hook_remove(&impl->module_listener);
|
||||
free(impl);
|
||||
}
|
||||
|
||||
static const struct pw_impl_module_events module_events = {
|
||||
PW_VERSION_IMPL_MODULE_EVENTS,
|
||||
.destroy = module_destroy,
|
||||
};
|
||||
|
||||
static int set_nice(struct impl *impl, int nice_level)
|
||||
{
|
||||
long tid;
|
||||
int res = 0;
|
||||
|
||||
tid = syscall(SYS_gettid);
|
||||
if (tid < 0) {
|
||||
pw_log_warn("could not get main thread id: %m");
|
||||
tid = 0; /* means current thread in setpriority() on linux */
|
||||
}
|
||||
if (setpriority(PRIO_PROCESS, (id_t)tid, nice_level) < 0)
|
||||
res = -errno;
|
||||
|
||||
if (res < 0)
|
||||
pw_log_warn("could not set nice-level to %d: %s",
|
||||
nice_level, spa_strerror(res));
|
||||
else
|
||||
pw_log_info("main thread nice level set to %d",
|
||||
nice_level);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int set_rlimit(struct impl *impl)
|
||||
{
|
||||
struct rlimit rl;
|
||||
int res = 0;
|
||||
|
||||
rl.rlim_cur = impl->rt_time_soft;
|
||||
rl.rlim_max = impl->rt_time_hard;
|
||||
|
||||
if (setrlimit(RLIMIT_RTTIME, &rl) < 0)
|
||||
res = -errno;
|
||||
|
||||
if (res < 0)
|
||||
pw_log_warn("could not set rlimit: %s", spa_strerror(res));
|
||||
else
|
||||
pw_log_debug("rt.time.soft %"PRIi64", rt.time.hard %"PRIi64,
|
||||
(int64_t)rl.rlim_cur, (int64_t)rl.rlim_max);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct spa_thread *impl_create(void *data,
|
||||
const struct spa_dict *props,
|
||||
void *(*start)(void*), void *arg)
|
||||
{
|
||||
pthread_t pt;
|
||||
int err;
|
||||
if ((err = pthread_create(&pt, NULL, start, arg)) != 0) {
|
||||
errno = err;
|
||||
return NULL;
|
||||
}
|
||||
return (struct spa_thread*)pt;
|
||||
}
|
||||
|
||||
static int impl_join(void *data, struct spa_thread *thread, void **retval)
|
||||
{
|
||||
pthread_t pt = (pthread_t)thread;
|
||||
return pthread_join(pt, retval);
|
||||
}
|
||||
|
||||
static int impl_get_rt_range(void *data, const struct spa_dict *props,
|
||||
int *min, int *max)
|
||||
{
|
||||
int policy = DEFAULT_POLICY;
|
||||
if (min)
|
||||
*min = sched_get_priority_min(policy);
|
||||
if (max)
|
||||
*max = sched_get_priority_max(policy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int impl_acquire_rt(void *data, struct spa_thread *thread, int priority)
|
||||
{
|
||||
int err, policy = DEFAULT_POLICY;
|
||||
int rtprio = priority;
|
||||
struct sched_param sp;
|
||||
pthread_t pt = (pthread_t)thread;
|
||||
|
||||
if (rtprio < sched_get_priority_min(policy) ||
|
||||
rtprio > sched_get_priority_max(policy)) {
|
||||
pw_log_warn("invalid priority %d for policy %d", rtprio, policy);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
spa_zero(sp);
|
||||
sp.sched_priority = rtprio;
|
||||
if ((err = pthread_setschedparam(pt, policy | SCHED_RESET_ON_FORK,
|
||||
&sp)) != 0) {
|
||||
pw_log_warn("%p: could not make thread realtime: %s", thread, strerror(err));
|
||||
return -err;
|
||||
}
|
||||
pw_log_info("thread %p has realtime priority %d", thread, rtprio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int impl_drop_rt(void *data, struct spa_thread *thread)
|
||||
{
|
||||
struct sched_param sp;
|
||||
pthread_t pt = (pthread_t)thread;
|
||||
int err;
|
||||
|
||||
spa_zero(sp);
|
||||
if ((err = pthread_setschedparam(pt,
|
||||
SCHED_OTHER | SCHED_RESET_ON_FORK, &sp)) != 0) {
|
||||
pw_log_warn("%p: could not drop realtime: %s", thread, strerror(err));
|
||||
return -err;
|
||||
}
|
||||
pw_log_info("thread %p dropped realtime priority", thread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct spa_thread_utils_methods impl_thread_utils = {
|
||||
SPA_VERSION_THREAD_UTILS_METHODS,
|
||||
.create = impl_create,
|
||||
.join = impl_join,
|
||||
.get_rt_range = impl_get_rt_range,
|
||||
.acquire_rt = impl_acquire_rt,
|
||||
.drop_rt = impl_drop_rt,
|
||||
};
|
||||
|
||||
SPA_EXPORT
|
||||
int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
||||
{
|
||||
struct pw_context *context = pw_impl_module_get_context(module);
|
||||
struct impl *impl;
|
||||
struct pw_properties *props;
|
||||
int nice_level;
|
||||
int res;
|
||||
|
||||
PW_LOG_TOPIC_INIT(mod_topic);
|
||||
|
||||
impl = calloc(1, sizeof(struct impl));
|
||||
if (impl == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
pw_log_debug("module %p: new %s", impl, args);
|
||||
|
||||
impl->context = context;
|
||||
props = args ? pw_properties_new_string(args) : pw_properties_new(NULL, NULL);
|
||||
if (props == NULL) {
|
||||
res = -errno;
|
||||
goto error;
|
||||
}
|
||||
|
||||
nice_level = pw_properties_get_int32(props, "nice.level", DEFAULT_NICE_LEVEL);
|
||||
set_nice(impl, nice_level);
|
||||
|
||||
impl->rt_prio = pw_properties_get_int32(props, "rt.prio", DEFAULT_RT_PRIO);
|
||||
impl->rt_time_soft = pw_properties_get_int32(props, "rt.time.soft", DEFAULT_RT_TIME_SOFT);
|
||||
impl->rt_time_hard = pw_properties_get_int32(props, "rt.time.hard", DEFAULT_RT_TIME_HARD);
|
||||
|
||||
set_rlimit(impl);
|
||||
|
||||
impl->thread_utils.iface = SPA_INTERFACE_INIT(
|
||||
SPA_TYPE_INTERFACE_ThreadUtils,
|
||||
SPA_VERSION_THREAD_UTILS,
|
||||
&impl_thread_utils, impl);
|
||||
|
||||
pw_thread_utils_set(&impl->thread_utils);
|
||||
|
||||
pw_impl_module_add_listener(module, &impl->module_listener, &module_events, impl);
|
||||
|
||||
pw_impl_module_update_properties(module, &SPA_DICT_INIT_ARRAY(module_props));
|
||||
pw_impl_module_update_properties(module, &props->dict);
|
||||
pw_properties_free(props);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
pw_properties_free(props);
|
||||
free(impl);
|
||||
return res;
|
||||
}
|
Loading…
Reference in a new issue