mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-01 22:58:50 -04: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 spa_poll_event ep[MAX_EP], *e;
|
||||
|
|
@ -444,6 +444,49 @@ static int loop_iterate(void *object, int timeout)
|
|||
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)
|
||||
{
|
||||
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,
|
||||
};
|
||||
|
||||
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 = {
|
||||
SPA_VERSION_LOOP_CONTROL_METHODS,
|
||||
.get_fd = loop_get_fd,
|
||||
|
|
@ -908,6 +961,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
uint32_t n_support)
|
||||
{
|
||||
struct impl *impl;
|
||||
const char *str;
|
||||
int res;
|
||||
|
||||
spa_return_val_if_fail(factory != NULL, -EINVAL);
|
||||
|
|
@ -930,6 +984,12 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
SPA_VERSION_LOOP_UTILS,
|
||||
&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);
|
||||
spa_log_topic_init(impl->log, &log_topic);
|
||||
impl->system = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_System);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue