mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
loop: add optimized non-cancellable iterate
Only use the more heavy cancellable loop when the loop.cancel property was set. Makes pipewire go from 5% to 3% in high frequency wakeups.
This commit is contained in:
parent
67c38490a5
commit
fbf17cf980
1 changed files with 61 additions and 1 deletions
|
|
@ -397,7 +397,7 @@ static void cancellation_handler(void *closure)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int loop_iterate(void *object, int timeout)
|
static int loop_iterate_cancel(void *object, int timeout)
|
||||||
{
|
{
|
||||||
struct impl *impl = object;
|
struct impl *impl = object;
|
||||||
struct spa_poll_event ep[MAX_EP], *e;
|
struct spa_poll_event ep[MAX_EP], *e;
|
||||||
|
|
@ -444,6 +444,49 @@ static int loop_iterate(void *object, int timeout)
|
||||||
return nfds;
|
return nfds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int loop_iterate(void *object, int timeout)
|
||||||
|
{
|
||||||
|
struct impl *impl = object;
|
||||||
|
struct spa_poll_event ep[MAX_EP], *e;
|
||||||
|
int i, nfds;
|
||||||
|
|
||||||
|
impl->polling = true;
|
||||||
|
spa_loop_control_hook_before(&impl->hooks_list);
|
||||||
|
|
||||||
|
nfds = spa_system_pollfd_wait(impl->system, impl->poll_fd, ep, SPA_N_ELEMENTS(ep), timeout);
|
||||||
|
|
||||||
|
spa_loop_control_hook_after(&impl->hooks_list);
|
||||||
|
impl->polling = false;
|
||||||
|
|
||||||
|
/* first we set all the rmasks, then call the callbacks. The reason is that
|
||||||
|
* some callback might also want to look at other sources it manages and
|
||||||
|
* can then reset the rmask to suppress the callback */
|
||||||
|
for (i = 0; i < nfds; i++) {
|
||||||
|
struct spa_source *s = ep[i].data;
|
||||||
|
|
||||||
|
s->rmask = ep[i].events;
|
||||||
|
/* already active in another iteration of the loop,
|
||||||
|
* remove it from that iteration */
|
||||||
|
if (SPA_UNLIKELY(e = s->priv))
|
||||||
|
e->data = NULL;
|
||||||
|
s->priv = &ep[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SPA_UNLIKELY(!spa_list_is_empty(&impl->destroy_list)))
|
||||||
|
process_destroy(impl);
|
||||||
|
|
||||||
|
for (i = 0; i < nfds; i++) {
|
||||||
|
struct spa_source *s = ep[i].data;
|
||||||
|
if (SPA_LIKELY(s)) {
|
||||||
|
if (SPA_LIKELY(s->rmask))
|
||||||
|
s->func(s);
|
||||||
|
s->rmask = 0;
|
||||||
|
s->priv = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nfds;
|
||||||
|
}
|
||||||
|
|
||||||
static void source_io_func(struct spa_source *source)
|
static void source_io_func(struct spa_source *source)
|
||||||
{
|
{
|
||||||
struct source_impl *s = SPA_CONTAINER_OF(source, struct source_impl, source);
|
struct source_impl *s = SPA_CONTAINER_OF(source, struct source_impl, source);
|
||||||
|
|
@ -826,6 +869,16 @@ static const struct spa_loop_methods impl_loop = {
|
||||||
.invoke = loop_invoke,
|
.invoke = loop_invoke,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct spa_loop_control_methods impl_loop_control_cancel = {
|
||||||
|
SPA_VERSION_LOOP_CONTROL_METHODS,
|
||||||
|
.get_fd = loop_get_fd,
|
||||||
|
.add_hook = loop_add_hook,
|
||||||
|
.enter = loop_enter,
|
||||||
|
.leave = loop_leave,
|
||||||
|
.iterate = loop_iterate_cancel,
|
||||||
|
.check = loop_check,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct spa_loop_control_methods impl_loop_control = {
|
static const struct spa_loop_control_methods impl_loop_control = {
|
||||||
SPA_VERSION_LOOP_CONTROL_METHODS,
|
SPA_VERSION_LOOP_CONTROL_METHODS,
|
||||||
.get_fd = loop_get_fd,
|
.get_fd = loop_get_fd,
|
||||||
|
|
@ -908,6 +961,7 @@ impl_init(const struct spa_handle_factory *factory,
|
||||||
uint32_t n_support)
|
uint32_t n_support)
|
||||||
{
|
{
|
||||||
struct impl *impl;
|
struct impl *impl;
|
||||||
|
const char *str;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
spa_return_val_if_fail(factory != NULL, -EINVAL);
|
spa_return_val_if_fail(factory != NULL, -EINVAL);
|
||||||
|
|
@ -930,6 +984,12 @@ impl_init(const struct spa_handle_factory *factory,
|
||||||
SPA_VERSION_LOOP_UTILS,
|
SPA_VERSION_LOOP_UTILS,
|
||||||
&impl_loop_utils, impl);
|
&impl_loop_utils, impl);
|
||||||
|
|
||||||
|
if (info) {
|
||||||
|
if ((str = spa_dict_lookup(info, "loop.cancel")) != NULL &&
|
||||||
|
spa_atob(str))
|
||||||
|
impl->control.iface.cb.funcs = &impl_loop_control_cancel;
|
||||||
|
}
|
||||||
|
|
||||||
impl->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
|
impl->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
|
||||||
spa_log_topic_init(impl->log, &log_topic);
|
spa_log_topic_init(impl->log, &log_topic);
|
||||||
impl->system = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_System);
|
impl->system = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_System);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue