From 5e0c9199bd120126581aab739ba8b81d8b0799d9 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 5 Jul 2021 10:41:57 +0200 Subject: [PATCH] context: drop RT when freewheeling When we are freewheeling, drop the RT priority so that we don't lock up the system too much. --- src/pipewire/context.c | 34 ++++++++++++++++++++++++++++++++++ src/pipewire/private.h | 1 + 2 files changed, 35 insertions(+) diff --git a/src/pipewire/context.c b/src/pipewire/context.c index 1aa6a5cf5..ee295bb95 100644 --- a/src/pipewire/context.c +++ b/src/pipewire/context.c @@ -41,6 +41,7 @@ #include #include +#include #include #include @@ -183,6 +184,30 @@ static int try_load_conf(struct pw_context *this, const char *conf_prefix, return res; } +static int context_set_freewheel(struct pw_context *context, bool freewheel) +{ + struct pw_thread *thr; + int res; + + if ((thr = pw_data_loop_get_thread(context->data_loop_impl)) == NULL) + return -EIO; + + if (freewheel) { + pw_log_info(NAME" %p: enter freewheel", context); + res = pw_thread_utils_drop_rt(thr); + } else { + pw_log_info(NAME" %p: exit freewheel", context); + res = pw_thread_utils_acquire_rt(thr, 88); + } + if (res < 0) + pw_log_info(NAME" %p: freewheel error:%s", context, spa_strerror(res)); + + context->freewheeling = freewheel; + + return res; +} + + /** Create a new context object * * \param main_loop the main loop to use @@ -385,6 +410,8 @@ struct pw_context *pw_context_new(struct pw_loop *main_loop, if ((res = pw_data_loop_start(this->data_loop_impl)) < 0) goto error_free; + context_set_freewheel(this, false); + pw_settings_init(this); pw_log_debug(NAME" %p: created", this); @@ -982,6 +1009,7 @@ int pw_context_recalc_graph(struct pw_context *context, const char *reason) struct impl *impl = SPA_CONTAINER_OF(context, struct impl, this); struct pw_impl_node *n, *s, *target, *fallback; uint32_t max_quantum, min_quantum, def_quantum, def_rate; + bool freewheel = false; pw_log_info(NAME" %p: busy:%d reason:%s", context, impl->recalc, reason); @@ -1029,6 +1057,8 @@ again: * is a target for our unassigned nodes */ if (target == NULL) target = n; + if (n->freewheel) + freewheel = true; break; } } @@ -1037,6 +1067,10 @@ again: if (target == NULL) target = fallback; + /* update the freewheel status */ + if (context->freewheeling != freewheel) + context_set_freewheel(context, freewheel); + /* now go through all available nodes. The ones we didn't visit * in collect_nodes() are not linked to any driver. We assign them * to either an active driver of the first driver */ diff --git a/src/pipewire/private.h b/src/pipewire/private.h index bbcd5b470..915dcb449 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -450,6 +450,7 @@ struct pw_context { struct pw_impl_client *current_client; /**< client currently executing code in mainloop */ long sc_pagesize; + unsigned int freewheeling:1; void *user_data; /**< extra user data */ };