mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-03-30 11:10:29 -04:00
impl-node: improve node activation
Only activate the nodes when it was not-triggered, do this check with an atomic compare-and-swap so that we only activate a node once. We might be able to use this later to make sure that we resume the untriggered peer nodes when we remove a node from the graph.
This commit is contained in:
parent
9cb4d820d5
commit
74de723ecc
2 changed files with 29 additions and 24 deletions
|
|
@ -1888,13 +1888,16 @@ static inline void signal_sync(struct client *c)
|
||||||
state->pending, state->required);
|
state->pending, state->required);
|
||||||
|
|
||||||
if (pw_node_activation_state_dec(state)) {
|
if (pw_node_activation_state_dec(state)) {
|
||||||
l->activation->status = PW_NODE_ACTIVATION_TRIGGERED;
|
if (SPA_ATOMIC_CAS(l->activation->status,
|
||||||
l->activation->signal_time = nsec;
|
PW_NODE_ACTIVATION_NOT_TRIGGERED,
|
||||||
|
PW_NODE_ACTIVATION_TRIGGERED)) {
|
||||||
|
l->activation->signal_time = nsec;
|
||||||
|
|
||||||
pw_log_trace_fp("%p: signal %p %p", c, l, state);
|
pw_log_trace_fp("%p: signal %p %p", c, l, state);
|
||||||
|
|
||||||
if (SPA_UNLIKELY(write(l->signalfd, &cmd, sizeof(cmd)) != sizeof(cmd)))
|
if (SPA_UNLIKELY(write(l->signalfd, &cmd, sizeof(cmd)) != sizeof(cmd)))
|
||||||
pw_log_warn("%p: write failed %m", c);
|
pw_log_warn("%p: write failed %m", c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1210,10 +1210,17 @@ static inline uint64_t get_time_ns(struct spa_system *system)
|
||||||
return SPA_TIMESPEC_TO_NSEC(&ts);
|
return SPA_TIMESPEC_TO_NSEC(&ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void wake_target(struct pw_node_target *t)
|
static inline void wake_target(struct pw_node_target *t, uint64_t nsec)
|
||||||
{
|
{
|
||||||
if (SPA_UNLIKELY(spa_system_eventfd_write(t->system, t->fd, 1) < 0))
|
struct pw_node_activation *a = t->activation;
|
||||||
pw_log_warn("%p: write failed %m", t->node);
|
|
||||||
|
if (SPA_ATOMIC_CAS(a->status,
|
||||||
|
PW_NODE_ACTIVATION_NOT_TRIGGERED,
|
||||||
|
PW_NODE_ACTIVATION_TRIGGERED)) {
|
||||||
|
a->signal_time = nsec;
|
||||||
|
if (SPA_UNLIKELY(spa_system_eventfd_write(t->system, t->fd, 1) < 0))
|
||||||
|
pw_log_warn("%p: write failed %m", t->node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called from data-loop decrement the dependency counter of the target and when
|
/* called from data-loop decrement the dependency counter of the target and when
|
||||||
|
|
@ -1226,22 +1233,20 @@ static inline void trigger_target(struct pw_node_target *t, uint64_t nsec)
|
||||||
pw_log_trace_fp("%p: (%s-%u) state:%p pending:%d/%d", t->node,
|
pw_log_trace_fp("%p: (%s-%u) state:%p pending:%d/%d", t->node,
|
||||||
t->name, t->id, state, state->pending, state->required);
|
t->name, t->id, state, state->pending, state->required);
|
||||||
|
|
||||||
if (pw_node_activation_state_dec(state)) {
|
if (pw_node_activation_state_dec(state))
|
||||||
a->status = PW_NODE_ACTIVATION_TRIGGERED;
|
wake_target(t, nsec);
|
||||||
a->signal_time = nsec;
|
|
||||||
wake_target(t);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called from data-loop when all the targets of a node need to be triggered */
|
/* called from data-loop when all the targets of a node need to be triggered */
|
||||||
static inline int trigger_targets(struct pw_impl_node *this, int status, uint64_t nsec)
|
static inline int trigger_targets(struct pw_node_target *t, int status, uint64_t nsec)
|
||||||
{
|
{
|
||||||
struct pw_node_target *t;
|
struct pw_node_target *ta;
|
||||||
|
|
||||||
pw_log_trace_fp("%p: %s trigger targets %"PRIu64, this, this->name, nsec);
|
pw_log_trace_fp("%p: (%s-%u) trigger targets %"PRIu64,
|
||||||
|
t->node, t->name, t->id, nsec);
|
||||||
|
|
||||||
spa_list_for_each(t, &this->rt.target_list, link)
|
spa_list_for_each(ta, &t->node->rt.target_list, link)
|
||||||
trigger_target(t, nsec);
|
trigger_target(ta, nsec);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1323,7 +1328,7 @@ static inline int process_node(void *data)
|
||||||
/* we don't need to trigger targets when the node was driving the
|
/* we don't need to trigger targets when the node was driving the
|
||||||
* graph because that means we finished the graph. */
|
* graph because that means we finished the graph. */
|
||||||
if (SPA_LIKELY(!this->driving)) {
|
if (SPA_LIKELY(!this->driving)) {
|
||||||
trigger_targets(this, status, nsec);
|
trigger_targets(&this->rt.target, status, nsec);
|
||||||
} else {
|
} else {
|
||||||
/* calculate CPU time when finished */
|
/* calculate CPU time when finished */
|
||||||
a->signal_time = this->driver_start;
|
a->signal_time = this->driver_start;
|
||||||
|
|
@ -1852,7 +1857,7 @@ static int node_ready(void *data, int status)
|
||||||
" pending %d/%d", node->name, node->info.id,
|
" pending %d/%d", node->name, node->info.id,
|
||||||
state, a->position.clock.duration,
|
state, a->position.clock.duration,
|
||||||
pending, state->required);
|
pending, state->required);
|
||||||
wake_target(&node->rt.target);
|
wake_target(&node->rt.target, nsec);
|
||||||
check_states(node, nsec);
|
check_states(node, nsec);
|
||||||
pw_impl_node_rt_emit_incomplete(node);
|
pw_impl_node_rt_emit_incomplete(node);
|
||||||
}
|
}
|
||||||
|
|
@ -1912,9 +1917,6 @@ again:
|
||||||
a->prev_signal_time = a->signal_time;
|
a->prev_signal_time = a->signal_time;
|
||||||
node->driver_start = nsec;
|
node->driver_start = nsec;
|
||||||
|
|
||||||
a->status = PW_NODE_ACTIVATION_TRIGGERED;
|
|
||||||
a->signal_time = nsec;
|
|
||||||
|
|
||||||
a->sync_timeout = SPA_MIN(min_timeout, DEFAULT_SYNC_TIMEOUT);
|
a->sync_timeout = SPA_MIN(min_timeout, DEFAULT_SYNC_TIMEOUT);
|
||||||
|
|
||||||
if (SPA_UNLIKELY(reposition_target != NULL)) {
|
if (SPA_UNLIKELY(reposition_target != NULL)) {
|
||||||
|
|
@ -1946,7 +1948,7 @@ again:
|
||||||
spa_node_process_fast(p->mix);
|
spa_node_process_fast(p->mix);
|
||||||
}
|
}
|
||||||
/* now signal all the nodes we drive */
|
/* now signal all the nodes we drive */
|
||||||
return trigger_targets(node, status, nsec);
|
return trigger_targets(&node->rt.target, status, nsec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int node_reuse_buffer(void *data, uint32_t port_id, uint32_t buffer_id)
|
static int node_reuse_buffer(void *data, uint32_t port_id, uint32_t buffer_id)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue