context: improve graph recalc

Add reason to why we recalculate the graph for debugging purposes
Only recalculate graph when something relevant changed.
Block recalc from being called recursively.
This commit is contained in:
Wim Taymans 2020-04-24 11:27:00 +02:00
parent 39c2d5b963
commit 667c08ecc4
4 changed files with 28 additions and 15 deletions

View file

@ -61,6 +61,7 @@
struct impl {
struct pw_context this;
struct spa_handle *dbus_handle;
unsigned int recalc;
};
@ -799,10 +800,18 @@ static int collect_nodes(struct pw_impl_node *driver)
return 0;
}
int pw_context_recalc_graph(struct pw_context *context)
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;
pw_log_info(NAME" %p: busy:%d reason:%s", context, impl->recalc, reason);
if (impl->recalc)
return -EBUSY;
impl->recalc = true;
/* start from all drivers and group all nodes that are linked
* to it. Some nodes are not (yet) linked to anything and they
* will end up 'unassigned' to a master. Other nodes are master
@ -882,9 +891,11 @@ int pw_context_recalc_graph(struct pw_context *context)
state = PW_NODE_STATE_IDLE;
if (n->rt.position && n->quantum_current != n->rt.position->clock.duration) {
pw_log_info("(%s-%u) new quantum:%"PRIu64"->%u",
n->name, n->info.id,
n->rt.position->clock.duration,
n->quantum_current);
n->rt.position->clock.duration = n->quantum_current;
pw_log_info("(%s-%u) new quantum:%u",
n->name, n->info.id, n->quantum_current);
}
pw_log_debug(NAME" %p: master %p quantum:%u '%s'", context, n,
@ -897,6 +908,7 @@ int pw_context_recalc_graph(struct pw_context *context)
}
pw_impl_node_set_state(n, state);
}
impl->recalc = false;
return 0;
}

View file

@ -117,10 +117,10 @@ static void pw_impl_link_update_state(struct pw_impl_link *link, enum pw_link_st
if (old != PW_LINK_STATE_PAUSED && state == PW_LINK_STATE_PAUSED) {
link->prepared = true;
pw_context_recalc_graph(link->context);
pw_context_recalc_graph(link->context, "link prepared");
} else if (old == PW_LINK_STATE_PAUSED && state < PW_LINK_STATE_PAUSED) {
link->prepared = false;
pw_context_recalc_graph(link->context);
pw_context_recalc_graph(link->context, "link unprepared");
}
}
@ -1080,8 +1080,6 @@ struct pw_impl_link *pw_context_create_link(struct pw_context *context,
pw_impl_node_emit_peer_added(output_node, input_node);
pw_context_recalc_graph(context);
return this;
error_same_ports:
@ -1229,8 +1227,6 @@ void pw_impl_link_destroy(struct pw_impl_link *link)
pw_properties_free(link->properties);
pw_context_recalc_graph(link->context);
free(link->name);
free(link->info.format);
free(impl);

View file

@ -161,7 +161,7 @@ static int pause_node(struct pw_impl_node *this)
pw_log_debug(NAME" %p: pause node state:%s pause-on-idle:%d", this,
pw_node_state_as_string(this->info.state), impl->pause_on_idle);
if (this->info.state <= PW_NODE_STATE_IDLE && impl->pause_on_idle)
if (this->info.state <= PW_NODE_STATE_IDLE)
return 0;
node_deactivate(this);
@ -611,7 +611,8 @@ int pw_impl_node_register(struct pw_impl_node *this,
spa_list_for_each(port, &this->output_ports, link)
pw_impl_port_register(port, NULL);
pw_context_recalc_graph(context);
if (this->active || this->want_driver)
pw_context_recalc_graph(context, "active node register");
return 0;
@ -774,7 +775,7 @@ static void check_properties(struct pw_impl_node *node)
pw_log_debug(NAME" %p: driver:%d recalc:%d", node, node->driver, do_recalc);
if (do_recalc)
pw_context_recalc_graph(context);
pw_context_recalc_graph(context, "quantum change");
}
static const char *str_status(uint32_t status)
@ -1521,7 +1522,9 @@ void pw_impl_node_destroy(struct pw_impl_node *node)
struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this);
struct pw_impl_port *port;
struct pw_impl_node *follower;
bool active;
active = node->active;
node->active = false;
pw_log_debug(NAME" %p: destroy", impl);
@ -1569,7 +1572,8 @@ void pw_impl_node_destroy(struct pw_impl_node *node)
pw_global_destroy(node->global);
}
pw_context_recalc_graph(node->context);
if (active)
pw_context_recalc_graph(node->context, "active node destroy");
pw_log_debug(NAME" %p: free", node);
pw_impl_node_emit_free(node);
@ -1861,7 +1865,8 @@ int pw_impl_node_set_active(struct pw_impl_node *node, bool active)
pw_impl_node_emit_active_changed(node, active);
if (node->registered)
pw_context_recalc_graph(node->context);
pw_context_recalc_graph(node->context,
active ? "node activate" : "node deactivate");
}
return 0;
}

View file

@ -964,7 +964,7 @@ int pw_proxy_init(struct pw_proxy *proxy, const char *type, uint32_t version);
void pw_proxy_remove(struct pw_proxy *proxy);
int pw_context_recalc_graph(struct pw_context *context);
int pw_context_recalc_graph(struct pw_context *context, const char *reason);
void pw_impl_port_update_info(struct pw_impl_port *port, const struct spa_port_info *info);