From dc5ed8f327ae781ba4fbdddf5234242fdaa3a87f Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 5 Jul 2021 11:35:27 +0200 Subject: [PATCH] thread: add methods to get rt priority range --- pipewire-jack/src/pipewire-jack.c | 5 ++- src/modules/module-rt.c | 16 ++++++++- src/modules/module-rtkit.c | 12 +++++++ src/pipewire/thread.c | 54 +++++++++------------------- src/pipewire/thread.h | 58 ++++++++++++++++++++++++++++--- 5 files changed, 98 insertions(+), 47 deletions(-) diff --git a/pipewire-jack/src/pipewire-jack.c b/pipewire-jack/src/pipewire-jack.c index e9c684056..53ff72396 100644 --- a/pipewire-jack/src/pipewire-jack.c +++ b/pipewire-jack/src/pipewire-jack.c @@ -56,7 +56,6 @@ #define JACK_DEFAULT_VIDEO_TYPE "32 bit float RGBA video" -#define JACK_SCHED_POLICY SCHED_FIFO /* use 512KB stack per thread - the default is way too high to be feasible * with mlockall() on many systems */ #define THREAD_STACK 524288 @@ -5437,11 +5436,11 @@ SPA_EXPORT int jack_client_max_real_time_priority (jack_client_t *client) { struct client *c = (struct client *) client; - int max; + int min, max; spa_return_val_if_fail(c != NULL, -1); - max = sched_get_priority_max(JACK_SCHED_POLICY); + pw_thread_utils_get_rt_range(NULL, &min, &max); return SPA_MIN(max, c->rt_max) - 1; } diff --git a/src/modules/module-rt.c b/src/modules/module-rt.c index ab8b8cf4a..475afb0fc 100644 --- a/src/modules/module-rt.c +++ b/src/modules/module-rt.c @@ -45,6 +45,8 @@ /** \page page_module_rt PipeWire Module: RT */ +#define DEFAULT_POLICY SCHED_FIFO + #define DEFAULT_NICE_LEVEL -11 #define DEFAULT_RT_PRIO 88 #define DEFAULT_RT_TIME_SOFT 2000000 @@ -178,9 +180,20 @@ static int impl_join(void *data, struct pw_thread *thread, void **retval) 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 pw_thread *thread, int priority) { - int err, policy = SCHED_FIFO; + int err, policy = DEFAULT_POLICY; int rtprio = priority; struct sched_param sp; pthread_t pt = (pthread_t)thread; @@ -222,6 +235,7 @@ static const struct pw_thread_utils_methods impl_thread_utils = { PW_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, }; diff --git a/src/modules/module-rtkit.c b/src/modules/module-rtkit.c index 7961adcae..1927292ef 100644 --- a/src/modules/module-rtkit.c +++ b/src/modules/module-rtkit.c @@ -572,6 +572,17 @@ static int impl_join(void *data, struct pw_thread *thread, void **retval) return pthread_join(pt, retval); } +static int impl_get_rt_range(void *data, const struct spa_dict *props, + int *min, int *max) +{ + struct impl *impl = data; + if (min) + *min = 1; + if (max) + *max = pw_rtkit_get_max_realtime_priority(impl->system_bus); + return 0; +} + static pid_t impl_gettid(struct impl *impl, pthread_t pt) { struct thread *thr; @@ -645,6 +656,7 @@ static const struct pw_thread_utils_methods impl_thread_utils = { PW_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, }; diff --git a/src/pipewire/thread.c b/src/pipewire/thread.c index 549b63a60..bdf0fb786 100644 --- a/src/pipewire/thread.c +++ b/src/pipewire/thread.c @@ -54,6 +54,16 @@ static int impl_join(void *data, struct pw_thread *thread, void **retval) return pthread_join(pt, retval); } +static int impl_get_rt_range(void *data, const struct spa_dict *props, + int *min, int *max) +{ + if (min) + *min = sched_get_priority_min(SCHED_OTHER); + if (max) + *max = sched_get_priority_max(SCHED_OTHER); + return 0; +} + static struct { struct pw_thread_utils utils; struct pw_thread_utils_methods methods; @@ -63,8 +73,10 @@ static struct { SPA_CALLBACKS_INIT(&default_impl.methods, &default_impl) } }, { PW_VERSION_THREAD_UTILS_METHODS, - .create = impl_create, - .join = impl_join, } + .create = impl_create, + .join = impl_join, + .get_rt_range = impl_get_rt_range + } }; static struct pw_thread_utils *global_impl = &default_impl.utils; @@ -78,41 +90,7 @@ void pw_thread_utils_set_impl(struct pw_thread_utils *impl) } SPA_EXPORT -struct pw_thread *pw_thread_utils_create(const struct spa_dict *props, - void *(*start_routine)(void*), void *arg) +struct pw_thread_utils *pw_thread_utils_get_impl(void) { - struct pw_thread *res = NULL; - spa_interface_call_res(&global_impl->iface, - struct pw_thread_utils_methods, res, create, 0, - props, start_routine, arg); - return res; -} - -SPA_EXPORT -int pw_thread_utils_join(struct pw_thread *thread, void **retval) -{ - int res = -ENOTSUP; - spa_interface_call_res(&global_impl->iface, - struct pw_thread_utils_methods, res, join, 0, - thread, retval); - return res; -} - -SPA_EXPORT -int pw_thread_utils_acquire_rt(struct pw_thread *thread, int priority) -{ - int res = -ENOTSUP; - spa_interface_call_res(&global_impl->iface, - struct pw_thread_utils_methods, res, acquire_rt, 0, - thread, priority); - return res; -} - -SPA_EXPORT -int pw_thread_utils_drop_rt(struct pw_thread *thread) -{ - int res = -ENOTSUP; - spa_interface_call_res(&global_impl->iface, - struct pw_thread_utils_methods, res, drop_rt, 0, thread); - return res; + return global_impl; } diff --git a/src/pipewire/thread.h b/src/pipewire/thread.h index 58ecafb89..360e20e90 100644 --- a/src/pipewire/thread.h +++ b/src/pipewire/thread.h @@ -42,6 +42,9 @@ extern "C" { #define PW_TYPE_INTERFACE_ThreadUtils PW_TYPE_INFO_INTERFACE_BASE "ThreadUtils" +/** a thread object. + * This can be cast to a platform native thread, like pthread on posix systems + */ struct pw_thread; #define PW_VERSION_THREAD_UTILS 0 @@ -52,22 +55,67 @@ struct pw_thread_utils_methods { #define PW_VERSION_THREAD_UTILS_METHODS 0 uint32_t version; + /** create a new thread that runs \a start with \a arg */ struct pw_thread * (*create) (void *data, const struct spa_dict *props, void *(*start)(void*), void *arg); + /** stop and join a thread */ int (*join)(void *data, struct pw_thread *thread, void **retval); + /** get realtime priority range for threads created with \a props */ + int (*get_rt_range) (void *data, const struct spa_dict *props, int *min, int *max); + /** acquire realtime priority */ int (*acquire_rt) (void *data, struct pw_thread *thread, int priority); + /** drop realtime priority */ int (*drop_rt) (void *data, struct pw_thread *thread); }; void pw_thread_utils_set_impl(struct pw_thread_utils *impl); +struct pw_thread_utils *pw_thread_utils_get_impl(void); -struct pw_thread *pw_thread_utils_create(const struct spa_dict *props, - void *(*start)(void*), void *arg); -int pw_thread_utils_join(struct pw_thread *thread, void **retval); +static inline struct pw_thread *pw_thread_utils_create(const struct spa_dict *props, + void *(*start_routine)(void*), void *arg) +{ + struct pw_thread *res = NULL; + spa_interface_call_res(&pw_thread_utils_get_impl()->iface, + struct pw_thread_utils_methods, res, create, 0, + props, start_routine, arg); + return res; +} -int pw_thread_utils_acquire_rt(struct pw_thread *thread, int priority); -int pw_thread_utils_drop_rt(struct pw_thread *thread); +static inline int pw_thread_utils_join(struct pw_thread *thread, void **retval) +{ + int res = -ENOTSUP; + spa_interface_call_res(&pw_thread_utils_get_impl()->iface, + struct pw_thread_utils_methods, res, join, 0, + thread, retval); + return res; +} + +static inline int pw_thread_utils_get_rt_range(const struct spa_dict *props, int *min, int *max) +{ + int res = -ENOTSUP; + spa_interface_call_res(&pw_thread_utils_get_impl()->iface, + struct pw_thread_utils_methods, res, get_rt_range, 0, + props, min, max); + return res; +} + +static inline int pw_thread_utils_acquire_rt(struct pw_thread *thread, int priority) +{ + int res = -ENOTSUP; + spa_interface_call_res(&pw_thread_utils_get_impl()->iface, + struct pw_thread_utils_methods, res, acquire_rt, 0, + thread, priority); + return res; +} + +static inline int pw_thread_utils_drop_rt(struct pw_thread *thread) +{ + int res = -ENOTSUP; + spa_interface_call_res(&pw_thread_utils_get_impl()->iface, + struct pw_thread_utils_methods, res, drop_rt, 0, thread); + return res; +} #ifdef __cplusplus } /* extern "C" */