mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-29 11:08:40 -05:00
profiler: use rt_events
Track the driver nodes and listen for rt events to collect stats.
This commit is contained in:
parent
cfd3bcd6b2
commit
7ae59ff399
5 changed files with 107 additions and 65 deletions
|
|
@ -71,6 +71,16 @@ static const struct spa_dict_item module_props[] = {
|
|||
{ PW_KEY_MODULE_VERSION, PACKAGE_VERSION },
|
||||
};
|
||||
|
||||
struct node {
|
||||
struct spa_list link;
|
||||
struct impl *impl;
|
||||
|
||||
struct pw_impl_node *node;
|
||||
struct spa_hook node_rt_listener;
|
||||
|
||||
unsigned enabled:1;
|
||||
};
|
||||
|
||||
struct impl {
|
||||
struct pw_context *context;
|
||||
struct pw_properties *properties;
|
||||
|
|
@ -84,6 +94,8 @@ struct impl {
|
|||
struct pw_global *global;
|
||||
struct spa_hook global_listener;
|
||||
|
||||
struct spa_list node_list;
|
||||
|
||||
int64_t count;
|
||||
uint32_t busy;
|
||||
uint32_t empty;
|
||||
|
|
@ -94,7 +106,6 @@ struct impl {
|
|||
struct spa_ringbuffer buffer;
|
||||
uint8_t tmp[TMP_BUFFER];
|
||||
uint8_t data[MAX_BUFFER];
|
||||
|
||||
uint8_t flush[MAX_BUFFER + sizeof(struct spa_pod_struct)];
|
||||
};
|
||||
|
||||
|
|
@ -278,15 +289,88 @@ done:
|
|||
impl->count++;
|
||||
}
|
||||
|
||||
static void node_complete(void *data)
|
||||
{
|
||||
struct node *n = data;
|
||||
pw_log_info("complete");
|
||||
context_do_profile(n->impl, n->node);
|
||||
}
|
||||
|
||||
static struct pw_impl_node_rt_events node_rt_events = {
|
||||
PW_VERSION_IMPL_NODE_RT_EVENTS,
|
||||
.complete = node_complete,
|
||||
};
|
||||
|
||||
static void enable_node_profiling(struct node *n, bool enabled)
|
||||
{
|
||||
if (enabled && !n->enabled) {
|
||||
SPA_FLAG_SET(n->node->rt.target.activation->flags, PW_NODE_ACTIVATION_FLAG_PROFILER);
|
||||
pw_impl_node_add_rt_listener(n->node, &n->node_rt_listener, &node_rt_events, n);
|
||||
} else if (!enabled && n->enabled) {
|
||||
SPA_FLAG_CLEAR(n->node->rt.target.activation->flags, PW_NODE_ACTIVATION_FLAG_PROFILER);
|
||||
pw_impl_node_remove_rt_listener(n->node, &n->node_rt_listener);
|
||||
}
|
||||
n->enabled = enabled;
|
||||
}
|
||||
|
||||
static void enable_profiling(struct impl *impl, bool enabled)
|
||||
{
|
||||
struct node *n;
|
||||
spa_list_for_each(n, &impl->node_list, link)
|
||||
enable_node_profiling(n, enabled);
|
||||
}
|
||||
|
||||
static void context_driver_added(void *data, struct pw_impl_node *node)
|
||||
{
|
||||
struct impl *impl = data;
|
||||
struct node *n;
|
||||
|
||||
n = calloc(1, sizeof(*n));
|
||||
if (n == NULL)
|
||||
return;
|
||||
|
||||
n->impl = impl;
|
||||
n->node = node;
|
||||
spa_list_append(&impl->node_list, &n->link);
|
||||
|
||||
if (impl->busy > 0)
|
||||
enable_node_profiling(n, true);
|
||||
}
|
||||
|
||||
static struct node *find_node(struct impl *impl, struct pw_impl_node *node)
|
||||
{
|
||||
struct node *n;
|
||||
spa_list_for_each(n, &impl->node_list, link) {
|
||||
if (n->node == node)
|
||||
return n;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void context_driver_removed(void *data, struct pw_impl_node *node)
|
||||
{
|
||||
struct impl *impl = data;
|
||||
struct node *n;
|
||||
|
||||
n = find_node(impl, node);
|
||||
if (n == NULL)
|
||||
return;
|
||||
|
||||
enable_node_profiling(n, false);
|
||||
spa_list_remove(&n->link);
|
||||
free(n);
|
||||
}
|
||||
|
||||
static const struct pw_context_events context_events = {
|
||||
PW_VERSION_CONTEXT_EVENTS,
|
||||
.profiler = context_do_profile,
|
||||
.driver_added = context_driver_added,
|
||||
.driver_removed = context_driver_removed,
|
||||
};
|
||||
|
||||
static void stop_listener(struct impl *impl)
|
||||
{
|
||||
if (impl->listening) {
|
||||
pw_context_stop_profiler(impl->context);
|
||||
enable_profiling(impl, false);
|
||||
impl->listening = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -329,7 +413,7 @@ global_bind(void *object, struct pw_impl_client *client, uint32_t permissions,
|
|||
|
||||
if (++impl->busy == 1) {
|
||||
pw_log_info("%p: starting profiler", impl);
|
||||
pw_context_start_profiler(impl->context);
|
||||
enable_profiling(impl, true);
|
||||
impl->listening = true;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -390,6 +474,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
|||
if (impl == NULL)
|
||||
return -errno;
|
||||
|
||||
spa_list_init(&impl->node_list);
|
||||
pw_protocol_native_ext_profiler_init(context);
|
||||
|
||||
pw_log_debug("module %p: new %s", impl, args);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue