From 40b48d4adc8a441c2cb1ecd847c1ebbb3ae98fd2 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Mon, 1 Apr 2024 14:48:46 -0400 Subject: [PATCH] MT#55283 allocated memory for per-interface stats There isn't any immediate benefit to this, but it prepares the code for use of shared memory for statistics. Use the opportunity to switch accesses to these to relaxed memory order. Change-Id: I585fef7579202179fbbcbc1b843d3bbe440a723b --- daemon/cli.c | 40 ++++++++++++++++++++-------------------- daemon/codec.c | 6 +++--- daemon/media_player.c | 4 ++-- daemon/media_socket.c | 18 ++++++++++-------- daemon/statistics.c | 18 +++++++++--------- include/media_socket.h | 2 +- include/statistics.h | 12 ++++++------ t/test-transcode.c | 3 ++- 8 files changed, 53 insertions(+), 50 deletions(-) diff --git a/daemon/cli.c b/daemon/cli.c index f363ce53f..0dac17fbe 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -1711,31 +1711,31 @@ static void cli_incoming_list_interfaces(str *instr, struct cli_writer *cw) { r - f, r, (double) (r - f) * 100.0 / r); cw->cw_printf(cw, " Packets/bytes/errors:\n"); cw->cw_printf(cw, " Ingress: %10" PRIu64 " / %10" PRIu64 " / %10" PRIu64 "\n", - atomic64_get(&lif->stats.in.packets), - atomic64_get(&lif->stats.in.bytes), - atomic64_get(&lif->stats.in.errors)); + atomic64_get_na(&lif->stats->in.packets), + atomic64_get_na(&lif->stats->in.bytes), + atomic64_get_na(&lif->stats->in.errors)); cw->cw_printf(cw, " Egress: %10" PRIu64 " / %10" PRIu64 " / %10" PRIu64 "\n", - atomic64_get(&lif->stats.out.packets), - atomic64_get(&lif->stats.out.bytes), - atomic64_get(&lif->stats.out.errors)); + atomic64_get_na(&lif->stats->out.packets), + atomic64_get_na(&lif->stats->out.bytes), + atomic64_get_na(&lif->stats->out.errors)); cw->cw_printf(cw, " Packets lost/duplicates: %10" PRIu64 " / %10" PRIu64 "\n", - atomic64_get(&lif->stats.s.packets_lost), - atomic64_get(&lif->stats.s.duplicates)); + atomic64_get_na(&lif->stats->s.packets_lost), + atomic64_get_na(&lif->stats->s.duplicates)); cw->cw_printf(cw, " MOS: avg %3.1f, packet loss avg %3.0f%%\n", - (double) atomic64_get(&lif->stats.sampled.sums.mos) - / atomic64_get(&lif->stats.sampled.counts.mos) / 10., - (double) atomic64_get(&lif->stats.sampled.sums.packetloss) - / atomic64_get(&lif->stats.sampled.counts.packetloss)); + (double) atomic64_get_na(&lif->stats->sampled.sums.mos) + / atomic64_get_na(&lif->stats->sampled.counts.mos) / 10., + (double) atomic64_get_na(&lif->stats->sampled.sums.packetloss) + / atomic64_get_na(&lif->stats->sampled.counts.packetloss)); cw->cw_printf(cw, " Jitter: avg %3.0f (measured %3.0f)\n", - (double) atomic64_get(&lif->stats.sampled.sums.jitter) - / atomic64_get(&lif->stats.sampled.counts.jitter), - (double) atomic64_get(&lif->stats.sampled.sums.jitter_measured) - / atomic64_get(&lif->stats.sampled.counts.jitter_measured)); + (double) atomic64_get_na(&lif->stats->sampled.sums.jitter) + / atomic64_get_na(&lif->stats->sampled.counts.jitter), + (double) atomic64_get_na(&lif->stats->sampled.sums.jitter_measured) + / atomic64_get_na(&lif->stats->sampled.counts.jitter_measured)); cw->cw_printf(cw, " RTT: e2e %3.0f, dsct %3.0f\n", - (double) atomic64_get(&lif->stats.sampled.sums.rtt_e2e) - / atomic64_get(&lif->stats.sampled.counts.rtt_e2e), - (double) atomic64_get(&lif->stats.sampled.sums.rtt_dsct) - / atomic64_get(&lif->stats.sampled.counts.rtt_dsct)); + (double) atomic64_get_na(&lif->stats->sampled.sums.rtt_e2e) + / atomic64_get_na(&lif->stats->sampled.counts.rtt_e2e), + (double) atomic64_get_na(&lif->stats->sampled.sums.rtt_dsct) + / atomic64_get_na(&lif->stats->sampled.counts.rtt_dsct)); } } diff --git a/daemon/codec.c b/daemon/codec.c index c40ec609e..33964f4dc 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -1847,8 +1847,8 @@ static int __handler_func_sequencer(struct media_packet *mp, struct transcode_pa atomic64_inc(&ssrc_in->packets); atomic64_add(&ssrc_in->octets, mp->payload.len); - atomic64_inc(&mp->sfd->local_intf->stats.in.packets); - atomic64_add(&mp->sfd->local_intf->stats.in.bytes, mp->payload.len); + atomic64_inc_na(&mp->sfd->local_intf->stats->in.packets); + atomic64_add_na(&mp->sfd->local_intf->stats->in.bytes, mp->payload.len); struct codec_ssrc_handler *input_ch = get_ssrc(ssrc_in_p->h.ssrc, h->input_handler->ssrc_hash); @@ -1890,7 +1890,7 @@ static int __handler_func_sequencer(struct media_packet *mp, struct transcode_pa if (func_ret != 1) __transcode_packet_free(packet); ssrc_in_p->duplicates++; - atomic64_inc(&mp->sfd->local_intf->stats.s.duplicates); + atomic64_inc_na(&mp->sfd->local_intf->stats->s.duplicates); RTPE_STATS_INC(rtp_duplicates); goto out; } diff --git a/daemon/media_player.c b/daemon/media_player.c index 24600b95f..a1a0b8bdd 100644 --- a/daemon/media_player.c +++ b/daemon/media_player.c @@ -305,8 +305,8 @@ static bool __send_timer_send_1(struct rtp_header *rh, struct packet_stream *sin atomic64_inc(&sink->stats_out.packets); atomic64_add(&sink->stats_out.bytes, cp->s.len); - atomic64_inc(&sink_fd->local_intf->stats.out.packets); - atomic64_add(&sink_fd->local_intf->stats.out.bytes, cp->s.len); + atomic64_inc_na(&sink_fd->local_intf->stats->out.packets); + atomic64_add_na(&sink_fd->local_intf->stats->out.bytes, cp->s.len); log_info_pop(); diff --git a/daemon/media_socket.c b/daemon/media_socket.c index 304cefc9f..0e770384f 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -54,7 +54,7 @@ diff_ ## x ## _ ## io = (ke)->x - ks_val; \ atomic64_add(&ps->stats_ ## io.x, diff_ ## x ## _ ## io); \ if (ps->selected_sfd) \ - atomic64_add(&ps->selected_sfd->local_intf->stats.io.x, diff_ ## x ## _ ## io); \ + atomic64_add_na(&ps->selected_sfd->local_intf->stats->io.x, diff_ ## x ## _ ## io); \ RTPE_STATS_ADD(x ## _kernel, diff_ ## x ## _ ## io); \ } while (0) @@ -822,6 +822,7 @@ static void __interface_append(struct intf_config *ifa, sockfamily_t *fam, bool ifc->advertised_address = ifa->advertised_address; ifc->spec = spec; ifc->logical = lif; + ifc->stats = g_malloc0(sizeof(*ifc->stats)); g_queue_push_tail(&all_local_interfaces, ifc); @@ -1808,7 +1809,7 @@ static void __stream_consume_stats(struct packet_stream *ps, const struct rtpeng atomic64_set(&ssrc_ctx->last_ts, stats_info->ssrc_stats[u].timestamp); RTPE_STATS_ADD(packets_lost, stats_info->ssrc_stats[u].total_lost); - atomic64_add(&ps->selected_sfd->local_intf->stats.s.packets_lost, + atomic64_add_na(&ps->selected_sfd->local_intf->stats->s.packets_lost, stats_info->ssrc_stats[u].total_lost); uint32_t ssrc_map_out = ssrc_ctx->ssrc_map_out; @@ -2280,7 +2281,7 @@ static void media_packet_rtp_in(struct packet_handler_ctx *phc) phc->payload_type, FMT_M(endpoint_print_buf(&phc->mp.fsin))); atomic64_inc(&phc->mp.stream->stats_in.errors); - atomic64_inc(&phc->mp.sfd->local_intf->stats.in.errors); + atomic64_inc_na(&phc->mp.sfd->local_intf->stats->in.errors); RTPE_STATS_INC(errors_user); } else { @@ -2491,7 +2492,7 @@ static bool media_packet_address_check(struct packet_handler_ctx *phc) FMT_M(sockaddr_print_buf(&ps_endpoint->address), ps_endpoint->port)); atomic64_inc(&phc->mp.stream->stats_in.errors); - atomic64_inc(&phc->mp.sfd->local_intf->stats.in.errors); + atomic64_inc_na(&phc->mp.sfd->local_intf->stats->in.errors); ret = true; } } @@ -2896,8 +2897,8 @@ static int stream_packet(struct packet_handler_ctx *phc) { } } atomic64_add(&phc->mp.stream->stats_in.bytes, phc->s.len); - atomic64_inc(&phc->mp.sfd->local_intf->stats.in.packets); - atomic64_add(&phc->mp.sfd->local_intf->stats.in.bytes, phc->s.len); + atomic64_inc_na(&phc->mp.sfd->local_intf->stats->in.packets); + atomic64_add_na(&phc->mp.sfd->local_intf->stats->in.bytes, phc->s.len); atomic64_set(&phc->mp.stream->last_packet, rtpe_now.tv_sec); RTPE_STATS_INC(packets_user); RTPE_STATS_ADD(bytes_user, phc->s.len); @@ -3071,7 +3072,7 @@ err_next: ilog(LOG_DEBUG | LOG_FLAG_LIMIT ,"Error when sending message. Error: %s", strerror(errno)); atomic64_inc(&sink->stats_in.errors); if (sink->selected_sfd) - atomic64_inc(&sink->selected_sfd->local_intf->stats.out.errors); + atomic64_inc_na(&sink->selected_sfd->local_intf->stats->out.errors); RTPE_STATS_INC(errors_user); goto next; @@ -3122,7 +3123,7 @@ out: if (handler_ret < 0) { atomic64_inc(&phc->mp.stream->stats_in.errors); - atomic64_inc(&phc->mp.sfd->local_intf->stats.in.errors); + atomic64_inc_na(&phc->mp.sfd->local_intf->stats->in.errors); RTPE_STATS_INC(errors_user); } @@ -3403,6 +3404,7 @@ void interfaces_free(void) { while ((ifc = g_queue_pop_head(&all_local_interfaces))) { free(ifc->ice_foundation.s); + g_free(ifc->stats); g_slice_free1(sizeof(*ifc), ifc); } diff --git a/daemon/statistics.c b/daemon/statistics.c index 5dd568f14..105e7d257 100644 --- a/daemon/statistics.c +++ b/daemon/statistics.c @@ -684,7 +684,7 @@ stats_metric_q *statistics_gather_metrics(struct interface_sampled_rate_stats *i HEADER("}", NULL); #define F(f) \ - METRICs(#f, UINT64F, atomic64_get(&lif->stats.s.f)); \ + METRICs(#f, UINT64F, atomic64_get_na(&lif->stats->s.f)); \ PROM("interface_" #f, "counter"); \ PROMLAB("name=\"%s\",address=\"%s\"", lif->logical->name.s, \ sockaddr_print_buf(&lif->spec->local_address.addr)); @@ -701,7 +701,7 @@ stats_metric_q *statistics_gather_metrics(struct interface_sampled_rate_stats *i HEADER("{", NULL); struct interface_counter_stats diff; - interface_counter_calc_diff(&lif->stats.s, &intv_stats->s, &diff); + interface_counter_calc_diff(&lif->stats->s, &intv_stats->s, &diff); #define F(f) METRICs(#f, UINT64F, atomic64_get(&diff.f)); #include "interface_counter_stats_fields.inc" @@ -728,10 +728,10 @@ stats_metric_q *statistics_gather_metrics(struct interface_sampled_rate_stats *i HEADER("{", NULL); struct interface_sampled_stats_avg stat_avg; - interface_sampled_avg(&stat_avg, &lif->stats.sampled); + interface_sampled_avg(&stat_avg, &lif->stats->sampled); #define INTF_SAMPLED_STAT(stat_name, name, divisor, prefix, label...) \ - STAT_GET_PRINT_GEN(&lif->stats.sampled, &stat_avg, stat_name, name, divisor, prefix, label) + STAT_GET_PRINT_GEN(&lif->stats->sampled, &stat_avg, stat_name, name, divisor, prefix, label) INTF_SAMPLED_STAT(mos, "MOS", 10.0, "interface_", "name=\"%s\",address=\"%s\"", lif->logical->name.s, @@ -760,7 +760,7 @@ stats_metric_q *statistics_gather_metrics(struct interface_sampled_rate_stats *i HEADER("{", NULL); struct interface_sampled_stats diff; - interface_sampled_calc_diff(&lif->stats.sampled, &intv_stats->sampled, &diff); + interface_sampled_calc_diff(&lif->stats->sampled, &intv_stats->sampled, &diff); struct interface_sampled_stats_avg avg; interface_sampled_avg(&avg, &diff); @@ -795,7 +795,7 @@ stats_metric_q *statistics_gather_metrics(struct interface_sampled_rate_stats *i HEADER("ingress", NULL); HEADER("{", NULL); #define F(f) \ - METRICs(#f, UINT64F, atomic64_get(&lif->stats.in.f)); \ + METRICs(#f, UINT64F, atomic64_get_na(&lif->stats->in.f)); \ PROM("interface_" #f, "gauge"); \ PROMLAB("name=\"%s\",address=\"%s\",direction=\"ingress\"", lif->logical->name.s, \ sockaddr_print_buf(&lif->spec->local_address.addr)); @@ -806,7 +806,7 @@ stats_metric_q *statistics_gather_metrics(struct interface_sampled_rate_stats *i HEADER("egress", NULL); HEADER("{", NULL); #define F(f) \ - METRICs(#f, UINT64F, atomic64_get(&lif->stats.out.f)); \ + METRICs(#f, UINT64F, atomic64_get_na(&lif->stats->out.f)); \ PROM("interface_" #f, "gauge"); \ PROMLAB("name=\"%s\",address=\"%s\",direction=\"egress\"", lif->logical->name.s, \ sockaddr_print_buf(&lif->spec->local_address.addr)); @@ -819,7 +819,7 @@ stats_metric_q *statistics_gather_metrics(struct interface_sampled_rate_stats *i HEADER("{", NULL); struct interface_counter_stats_dir diff_in; - interface_counter_calc_diff_dir(&lif->stats.in, &intv_stats->in, &diff_in); + interface_counter_calc_diff_dir(&lif->stats->in, &intv_stats->in, &diff_in); #define F(f) METRICs(#f, UINT64F, atomic64_get(&diff_in.f)); #include "interface_counter_stats_fields_dir.inc" @@ -831,7 +831,7 @@ stats_metric_q *statistics_gather_metrics(struct interface_sampled_rate_stats *i HEADER("{", NULL); struct interface_counter_stats_dir diff_out; - interface_counter_calc_diff_dir(&lif->stats.out, &intv_stats->out, &diff_out); + interface_counter_calc_diff_dir(&lif->stats->out, &intv_stats->out, &diff_out); #define F(f) METRICs(#f, UINT64F, atomic64_get(&diff_out.f)); #include "interface_counter_stats_fields_dir.inc" diff --git a/include/media_socket.h b/include/media_socket.h index f343996cc..3e9b4ded1 100644 --- a/include/media_socket.h +++ b/include/media_socket.h @@ -187,7 +187,7 @@ struct local_intf { const struct logical_intf *logical; str ice_foundation; - struct interface_stats_block stats; + struct interface_stats_block *stats; }; struct socket_intf_list { struct local_intf *local_intf; diff --git a/include/statistics.h b/include/statistics.h index ff5d80a5f..2519d7a7c 100644 --- a/include/statistics.h +++ b/include/statistics.h @@ -154,9 +154,9 @@ extern struct global_sampled_min_max rtpe_sampled_min_max; // master lifetime m #define RTPE_STATS_SAMPLE(field, num) \ do { \ - atomic64_add(&rtpe_stats_sampled.sums.field, num); \ - atomic64_add(&rtpe_stats_sampled.sums_squared.field, num * num); \ - atomic64_inc(&rtpe_stats_sampled.counts.field); \ + atomic64_add_na(&rtpe_stats_sampled.sums.field, num); \ + atomic64_add_na(&rtpe_stats_sampled.sums_squared.field, num * num); \ + atomic64_inc_na(&rtpe_stats_sampled.counts.field); \ RTPE_GAUGE_SET_MIN_MAX(field, rtpe_sampled_min_max, num); \ RTPE_GAUGE_SET_MIN_MAX(field, rtpe_sampled_graphite_min_max, num); \ } while (0) @@ -166,9 +166,9 @@ extern struct global_sampled_min_max rtpe_sampled_min_max; // master lifetime m RTPE_STATS_SAMPLE(field, num); \ if (sfd) { \ struct local_intf *__intf = sfd->local_intf; \ - atomic64_add(&__intf->stats.sampled.sums.field, num); \ - atomic64_add(&__intf->stats.sampled.sums_squared.field, num * num); \ - atomic64_inc(&__intf->stats.sampled.counts.field); \ + atomic64_add(&__intf->stats->sampled.sums.field, num); \ + atomic64_add(&__intf->stats->sampled.sums_squared.field, num * num); \ + atomic64_inc(&__intf->stats->sampled.counts.field); \ } \ } while (0) diff --git a/t/test-transcode.c b/t/test-transcode.c index 9f4773c0c..dc4a942a8 100644 --- a/t/test-transcode.c +++ b/t/test-transcode.c @@ -249,7 +249,8 @@ static void __packet_seq_ts(const char *file, int line, struct call_media *media str pl_exp = pload_exp; // from media_packet_rtp() - struct local_intf lif = { }; + struct interface_stats_block sblock; + struct local_intf lif = { .stats = &sblock }; stream_fd sfd = { .local_intf = &lif, };