mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-07 13:30:09 -05:00
impl-node: update xrun_count of late nodes
When the graph didn't complete, update the xrun_count in each node that didn't complete. We can then remove the code to simulate that from pw-top.
This commit is contained in:
parent
de7883024b
commit
3f46044c39
2 changed files with 22 additions and 32 deletions
|
|
@ -1077,11 +1077,23 @@ static const char *str_status(uint32_t status)
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_states(struct pw_impl_node *driver)
|
static void update_xrun_stats(struct pw_node_activation *a, uint64_t trigger, uint64_t delay)
|
||||||
|
{
|
||||||
|
a->xrun_count++;
|
||||||
|
a->xrun_time = trigger;
|
||||||
|
a->xrun_delay = delay;
|
||||||
|
a->max_delay = SPA_MAX(a->max_delay, delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_states(struct pw_impl_node *driver, uint64_t nsec)
|
||||||
{
|
{
|
||||||
struct pw_node_target *t;
|
struct pw_node_target *t;
|
||||||
struct pw_node_activation *na = driver->rt.activation;
|
struct pw_node_activation *na = driver->rt.activation;
|
||||||
struct spa_io_clock *cl = &na->position.clock;
|
struct spa_io_clock *cl = &na->position.clock;
|
||||||
|
enum spa_log_level level = SPA_LOG_LEVEL_DEBUG;
|
||||||
|
|
||||||
|
if (ratelimit_test(&driver->rt.rate_limit, na->signal_time, SPA_LOG_LEVEL_DEBUG))
|
||||||
|
level = SPA_LOG_LEVEL_INFO;
|
||||||
|
|
||||||
spa_list_for_each(t, &driver->rt.target_list, link) {
|
spa_list_for_each(t, &driver->rt.target_list, link) {
|
||||||
struct pw_node_activation *a = t->activation;
|
struct pw_node_activation *a = t->activation;
|
||||||
|
|
@ -1090,7 +1102,9 @@ static void dump_states(struct pw_impl_node *driver)
|
||||||
continue;
|
continue;
|
||||||
if (a->status == PW_NODE_ACTIVATION_TRIGGERED ||
|
if (a->status == PW_NODE_ACTIVATION_TRIGGERED ||
|
||||||
a->status == PW_NODE_ACTIVATION_AWAKE) {
|
a->status == PW_NODE_ACTIVATION_AWAKE) {
|
||||||
pw_log_info("(%s-%u) client too slow! rate:%u/%u pos:%"PRIu64" status:%s",
|
update_xrun_stats(a, nsec / 1000, 0);
|
||||||
|
|
||||||
|
pw_log(level, "(%s-%u) client too slow! rate:%u/%u pos:%"PRIu64" status:%s",
|
||||||
t->node->name, t->node->info.id,
|
t->node->name, t->node->info.id,
|
||||||
(uint32_t)(cl->rate.num * cl->duration), cl->rate.denom,
|
(uint32_t)(cl->rate.num * cl->duration), cl->rate.denom,
|
||||||
cl->position, str_status(a->status));
|
cl->position, str_status(a->status));
|
||||||
|
|
@ -1683,7 +1697,7 @@ static void do_reposition(struct pw_impl_node *driver, struct pw_impl_node *node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void update_position(struct pw_impl_node *node, int all_ready)
|
static inline void update_position(struct pw_impl_node *node, int all_ready, uint64_t nsec)
|
||||||
{
|
{
|
||||||
struct pw_node_activation *a = node->rt.activation;
|
struct pw_node_activation *a = node->rt.activation;
|
||||||
|
|
||||||
|
|
@ -1691,8 +1705,8 @@ static inline void update_position(struct pw_impl_node *node, int all_ready)
|
||||||
if (!all_ready && --a->sync_left == 0) {
|
if (!all_ready && --a->sync_left == 0) {
|
||||||
pw_log_warn("(%s-%u) sync timeout, going to RUNNING",
|
pw_log_warn("(%s-%u) sync timeout, going to RUNNING",
|
||||||
node->name, node->info.id);
|
node->name, node->info.id);
|
||||||
|
check_states(node, nsec);
|
||||||
pw_context_driver_emit_timeout(node->context, node);
|
pw_context_driver_emit_timeout(node->context, node);
|
||||||
dump_states(node);
|
|
||||||
all_ready = true;
|
all_ready = true;
|
||||||
}
|
}
|
||||||
if (all_ready)
|
if (all_ready)
|
||||||
|
|
@ -1737,13 +1751,12 @@ static int node_ready(void *data, int status)
|
||||||
uint64_t min_timeout = UINT64_MAX;
|
uint64_t min_timeout = UINT64_MAX;
|
||||||
|
|
||||||
if (SPA_UNLIKELY(a->status != PW_NODE_ACTIVATION_FINISHED)) {
|
if (SPA_UNLIKELY(a->status != PW_NODE_ACTIVATION_FINISHED)) {
|
||||||
pw_context_driver_emit_incomplete(node->context, node);
|
|
||||||
pw_log_debug("(%s-%u) graph not finished: state:%p quantum:%"PRIu64
|
pw_log_debug("(%s-%u) graph not finished: state:%p quantum:%"PRIu64
|
||||||
" 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,
|
||||||
state->pending, state->required);
|
state->pending, state->required);
|
||||||
if (ratelimit_test(&node->rt.rate_limit, a->signal_time, SPA_LOG_LEVEL_DEBUG))
|
check_states(node, nsec);
|
||||||
dump_states(node);
|
pw_context_driver_emit_incomplete(node->context, node);
|
||||||
} else {
|
} else {
|
||||||
uint64_t signal_time = a->signal_time;
|
uint64_t signal_time = a->signal_time;
|
||||||
/* old nodes set the TRIGGERED status on node_ready, patch this
|
/* old nodes set the TRIGGERED status on node_ready, patch this
|
||||||
|
|
@ -1836,7 +1849,7 @@ again:
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_position(node, all_ready);
|
update_position(node, all_ready, nsec);
|
||||||
|
|
||||||
pw_context_driver_emit_start(node->context, node);
|
pw_context_driver_emit_start(node->context, node);
|
||||||
}
|
}
|
||||||
|
|
@ -1875,14 +1888,6 @@ static int node_reuse_buffer(void *data, uint32_t port_id, uint32_t buffer_id)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_xrun_stats(struct pw_node_activation *a, uint64_t trigger, uint64_t delay)
|
|
||||||
{
|
|
||||||
a->xrun_count++;
|
|
||||||
a->xrun_time = trigger;
|
|
||||||
a->xrun_delay = delay;
|
|
||||||
a->max_delay = SPA_MAX(a->max_delay, delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int node_xrun(void *data, uint64_t trigger, uint64_t delay, struct spa_pod *info)
|
static int node_xrun(void *data, uint64_t trigger, uint64_t delay, struct spa_pod *info)
|
||||||
{
|
{
|
||||||
struct pw_impl_node *this = data;
|
struct pw_impl_node *this = data;
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,6 @@ struct node {
|
||||||
struct measurement measurement;
|
struct measurement measurement;
|
||||||
struct driver info;
|
struct driver info;
|
||||||
struct node *driver;
|
struct node *driver;
|
||||||
uint32_t errors;
|
|
||||||
int32_t last_error_status;
|
|
||||||
uint32_t generation;
|
uint32_t generation;
|
||||||
char format[MAX_FORMAT+1];
|
char format[MAX_FORMAT+1];
|
||||||
struct pw_proxy *proxy;
|
struct pw_proxy *proxy;
|
||||||
|
|
@ -338,12 +336,6 @@ static int process_driver_block(struct data *d, const struct spa_pod *pod, struc
|
||||||
n->info = point->info;
|
n->info = point->info;
|
||||||
point->driver = n;
|
point->driver = n;
|
||||||
n->generation = d->generation;
|
n->generation = d->generation;
|
||||||
|
|
||||||
if (m.status != 3) {
|
|
||||||
n->errors++;
|
|
||||||
if (n->last_error_status == -1)
|
|
||||||
n->last_error_status = m.status;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -376,11 +368,6 @@ static int process_follower_block(struct data *d, const struct spa_pod *pod, str
|
||||||
d->pending_refresh = true;
|
d->pending_refresh = true;
|
||||||
}
|
}
|
||||||
n->generation = d->generation;
|
n->generation = d->generation;
|
||||||
if (m.status != 3) {
|
|
||||||
n->errors++;
|
|
||||||
if (n->last_error_status == -1)
|
|
||||||
n->last_error_status = m.status;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -476,7 +463,7 @@ static void print_node(struct data *d, struct driver *i, struct node *n, int y)
|
||||||
print_time(buf2, active, 64, busy),
|
print_time(buf2, active, 64, busy),
|
||||||
print_perc(buf3, active, 64, waiting, quantum),
|
print_perc(buf3, active, 64, waiting, quantum),
|
||||||
print_perc(buf4, active, 64, busy, quantum),
|
print_perc(buf4, active, 64, busy, quantum),
|
||||||
i->xrun_count + n->errors,
|
i->xrun_count,
|
||||||
active ? n->format : "",
|
active ? n->format : "",
|
||||||
n->driver == n ? "" : " + ",
|
n->driver == n ? "" : " + ",
|
||||||
n->name);
|
n->name);
|
||||||
|
|
@ -487,8 +474,6 @@ static void clear_node(struct node *n)
|
||||||
n->driver = n;
|
n->driver = n;
|
||||||
spa_zero(n->measurement);
|
spa_zero(n->measurement);
|
||||||
spa_zero(n->info);
|
spa_zero(n->info);
|
||||||
n->errors = 0;
|
|
||||||
n->last_error_status = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_refresh(struct data *d)
|
static void do_refresh(struct data *d)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue