From b028dc9ff71233a964d3d1debca35eb32c83d58d Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 10 Mar 2016 10:53:49 +0100 Subject: [PATCH] tii_stats - add mutex and atomic ops (clang sanitizer) --- src/input.h | 1 + src/input/mpegts/iptv/iptv_udp.c | 2 +- src/input/mpegts/linuxdvb/linuxdvb_frontend.c | 19 ++++++++--- src/input/mpegts/mpegts_input.c | 33 ++++++++++++++----- src/input/mpegts/mpegts_mux.c | 3 ++ src/input/mpegts/satip/satip_frontend.c | 27 ++++++++------- .../mpegts/tvhdhomerun/tvhdhomerun_frontend.c | 6 +++- 7 files changed, 65 insertions(+), 26 deletions(-) diff --git a/src/input.h b/src/input.h index 6718f7793..1ae6236dc 100644 --- a/src/input.h +++ b/src/input.h @@ -101,6 +101,7 @@ struct tvh_input_instance { LIST_ENTRY(tvh_input_instance) tii_input_link; + pthread_mutex_t tii_stats_mutex; tvh_input_stream_stats_t tii_stats; void (*tii_delete) (tvh_input_instance_t *tii); diff --git a/src/input/mpegts/iptv/iptv_udp.c b/src/input/mpegts/iptv/iptv_udp.c index ab6636c9d..a264cda72 100644 --- a/src/input/mpegts/iptv/iptv_udp.c +++ b/src/input/mpegts/iptv/iptv_udp.c @@ -161,7 +161,7 @@ iptv_rtp_read ( iptv_mux_t *im, udp_multirecv_t *um, im->mm_iptv_rtp_seq = seq; if (im->mm_active) - im->mm_active->tii_stats.unc += unc; + atomic_add(&im->mm_active->tii_stats.unc, unc); return res; } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index b7c9f264b..ec5bb296f 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -799,6 +799,9 @@ linuxdvb_frontend_monitor ( void *aux ) lfe->lfe_monitor = mclk() + ms2mono(period); } + + pthread_mutex_lock(&mmi->tii_stats_mutex); + /* Statistics - New API */ #if DVB_VER_ATLEAST(5,10) memset(&fe_properties, 0, sizeof(fe_properties)); @@ -937,7 +940,8 @@ linuxdvb_frontend_monitor ( void *aux ) gotprop = 0; if(ioctl_check(lfe, 8) && fe_properties[4].u.st.len > 0) { if(fe_properties[4].u.st.stat[0].scale == FE_SCALE_COUNTER) { - mmi->tii_stats.unc = mmi->tii_stats.ec_block = fe_properties[4].u.st.stat[0].uvalue; + atomic_set(&mmi->tii_stats.unc, fe_properties[4].u.st.stat[0].uvalue); + mmi->tii_stats.ec_block = fe_properties[4].u.st.stat[0].uvalue; gotprop = 1; } else { @@ -957,7 +961,9 @@ linuxdvb_frontend_monitor ( void *aux ) } else { ioctl_bad(lfe, 9); - mmi->tii_stats.ec_block = mmi->tii_stats.unc = 0; /* both values or none */ + /* both values to none */ + mmi->tii_stats.ec_block = 0; + atomic_set(&mmi->tii_stats.unc, 0); if (logit) tvhlog(LOG_WARNING, "linuxdvb", "Unhandled TOTAL_BLOCK_COUNT scale: %d", fe_properties[5].u.st.stat[0].scale); @@ -966,7 +972,7 @@ linuxdvb_frontend_monitor ( void *aux ) if(!gotprop && ioctl_check(lfe, 10)) { /* try old API */ if (!ioctl(lfe->lfe_fe_fd, FE_READ_UNCORRECTED_BLOCKS, &u32)) { - mmi->tii_stats.unc = u32; + atomic_set(&mmi->tii_stats.unc, u32); gotprop = 1; } else { @@ -1008,7 +1014,7 @@ linuxdvb_frontend_monitor ( void *aux ) tvhlog(LOG_WARNING, "linuxdvb", "Unable to provide SNR value."); } if (ioctl_check(lfe, 4) && !ioctl(lfe->lfe_fe_fd, FE_READ_UNCORRECTED_BLOCKS, &u32)) - mmi->tii_stats.unc = u32; + atomic_set(&mmi->tii_stats.unc, u32); else { ioctl_bad(lfe, 4); if (logit) @@ -1021,7 +1027,7 @@ linuxdvb_frontend_monitor ( void *aux ) sigstat.snr = mmi->tii_stats.snr; sigstat.signal = mmi->tii_stats.signal; sigstat.ber = mmi->tii_stats.ber; - sigstat.unc = mmi->tii_stats.unc; + sigstat.unc = atomic_get(&mmi->tii_stats.unc); sigstat.signal_scale = mmi->tii_stats.signal_scale; sigstat.snr_scale = mmi->tii_stats.snr_scale; sigstat.ec_bit = mmi->tii_stats.ec_bit; @@ -1030,6 +1036,9 @@ linuxdvb_frontend_monitor ( void *aux ) sigstat.tc_block = mmi->tii_stats.tc_block; sm.sm_type = SMT_SIGNAL_STATUS; sm.sm_data = &sigstat; + + pthread_mutex_unlock(&mmi->tii_stats_mutex); + LIST_FOREACH(s, &mmi->mmi_mux->mm_transports, s_active_link) { pthread_mutex_lock(&s->s_stream_mutex); streaming_pad_deliver(&s->s_streaming_pad, streaming_msg_clone(&sm)); diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index 131ee9c5b..c7b322610 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -1061,7 +1061,7 @@ mpegts_input_recv_packets /* Check for sync */ while ( (len >= MIN_TS_SYN) && ((len2 = ts_sync_count(tsb, len)) < MIN_TS_SYN) ) { - mmi->tii_stats.unc++; + atomic_add(&mmi->tii_stats.unc, 1); --len; ++tsb; ++off; @@ -1295,7 +1295,7 @@ mpegts_input_process /* Transport error */ if (pid & 0x8000) { if ((pid & 0x1FFF) != 0x1FFF) - ++mmi->tii_stats.te; + atomic_add(&mmi->tii_stats.te, 1); } pid &= 0x1FFF; @@ -1318,7 +1318,7 @@ mpegts_input_process cc = tsb2[3] & 0x0f; if (cc2 != 0xff && cc2 != cc) { tvhtrace("mpegts", "%s: pid %04X cc err %2d != %2d", muxname, pid, cc, cc2); - ++mmi->tii_stats.cc; + atomic_add(&mmi->tii_stats.cc, 1); } cc2 = (cc + 1) & 0xF; } @@ -1615,7 +1615,20 @@ mpegts_input_stream_status st->stream_name = strdup(buf); st->subs_count = s; st->max_weight = w; - st->stats = mmi->tii_stats; + pthread_mutex_lock(&mmi->tii_stats_mutex); + st->stats.signal = mmi->tii_stats.signal; + st->stats.snr = mmi->tii_stats.snr; + st->stats.ber = mmi->tii_stats.ber; + st->stats.signal_scale = mmi->tii_stats.signal_scale; + st->stats.snr_scale = mmi->tii_stats.snr_scale; + st->stats.ec_bit = mmi->tii_stats.ec_bit; + st->stats.tc_bit = mmi->tii_stats.tc_bit; + st->stats.ec_block = mmi->tii_stats.ec_block; + st->stats.tc_block = mmi->tii_stats.tc_block; + pthread_mutex_unlock(&mmi->tii_stats_mutex); + st->stats.unc = atomic_get(&mmi->tii_stats.unc); + st->stats.cc = atomic_get(&mmi->tii_stats.cc); + st->stats.te = atomic_get(&mmi->tii_stats.te); st->stats.bps = atomic_exchange(&mmi->tii_stats.bps, 0) * 8; } @@ -1632,11 +1645,13 @@ mpegts_input_empty_status st->input_name = strdup(buf); LIST_FOREACH(mmi_, &mi->mi_mux_instances, tii_input_link) { mmi = (mpegts_mux_instance_t *)mmi_; - st->stats.unc += mmi->tii_stats.unc; - st->stats.cc += mmi->tii_stats.cc; + st->stats.unc += atomic_get(&mmi->tii_stats.unc); + st->stats.cc += atomic_get(&mmi->tii_stats.cc); + pthread_mutex_lock(&mmi->tii_stats_mutex); st->stats.te += mmi->tii_stats.te; st->stats.ec_block += mmi->tii_stats.ec_block; st->stats.tc_block += mmi->tii_stats.tc_block; + pthread_mutex_unlock(&mmi->tii_stats_mutex); } } @@ -1672,11 +1687,13 @@ mpegts_input_clear_stats ( tvh_input_t *i ) pthread_mutex_lock(&mi->mi_output_lock); LIST_FOREACH(mmi_, &mi->mi_mux_instances, tii_input_link) { mmi = (mpegts_mux_instance_t *)mmi_; - mmi->tii_stats.unc = 0; - mmi->tii_stats.cc = 0; + atomic_set(&mmi->tii_stats.unc, 0); + atomic_set(&mmi->tii_stats.cc, 0); + pthread_mutex_lock(&mmi->tii_stats_mutex); mmi->tii_stats.te = 0; mmi->tii_stats.ec_block = 0; mmi->tii_stats.tc_block = 0; + pthread_mutex_unlock(&mmi->tii_stats_mutex); } pthread_mutex_unlock(&mi->mi_output_lock); notify_reload("input_status"); diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index 971d4faed..c4ff822a2 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -52,6 +52,7 @@ mpegts_mux_instance_delete idnode_unlink(&tii->tii_id); LIST_REMOVE(mmi, mmi_mux_link); LIST_REMOVE(tii, tii_input_link); + pthread_mutex_destroy(&mmi->tii_stats_mutex); free(mmi); } @@ -66,6 +67,8 @@ mpegts_mux_instance_create0 return NULL; } + pthread_mutex_init(&mmi->tii_stats_mutex, NULL); + /* Setup links */ mmi->mmi_mux = mm; mmi->mmi_input = mi; diff --git a/src/input/mpegts/satip/satip_frontend.c b/src/input/mpegts/satip/satip_frontend.c index 5d4f6cb0d..c52b636c2 100644 --- a/src/input/mpegts/satip/satip_frontend.c +++ b/src/input/mpegts/satip/satip_frontend.c @@ -69,16 +69,18 @@ satip_frontend_signal_cb( void *aux ) lfe->sf_tables = 1; } sigstat.status_text = signal2str(lfe->sf_status); + pthread_mutex_lock(&mmi->tii_stats_mutex); sigstat.snr = mmi->tii_stats.snr; sigstat.signal = mmi->tii_stats.signal; sigstat.ber = mmi->tii_stats.ber; - sigstat.unc = mmi->tii_stats.unc; + sigstat.unc = atomic_get(&mmi->tii_stats.unc); sigstat.signal_scale = mmi->tii_stats.signal_scale; sigstat.snr_scale = mmi->tii_stats.snr_scale; sigstat.ec_bit = mmi->tii_stats.ec_bit; sigstat.tc_bit = mmi->tii_stats.tc_bit; sigstat.ec_block = mmi->tii_stats.ec_block; sigstat.tc_block = mmi->tii_stats.tc_block; + pthread_mutex_unlock(&mmi->tii_stats_mutex); sm.sm_type = SMT_SIGNAL_STATUS; sm.sm_data = &sigstat; LIST_FOREACH(svc, &mmi->mmi_mux->mm_transports, s_active_link) { @@ -726,6 +728,7 @@ satip_frontend_decode_rtcp( satip_frontend_t *lfe, const char *name, * -a BER lower than 2x10-4 after Viterbi for DVB-S * -a PER lower than 10-7 for DVB-S2 */ + pthread_mutex_lock(&mmi->tii_stats_mutex); while (len >= 12) { if ((rtcp[0] & 0xc0) != 0x80) /* protocol version: v2 */ return; @@ -746,9 +749,9 @@ satip_frontend_decode_rtcp( satip_frontend_t *lfe, const char *name, strncmp(s, "ver=1.2;tuner=", 14) == 0) { n = http_tokenize(s + 14, argv, 4, ','); if (n < 4) - return; + goto fail; if (atoi(argv[0]) != lfe->sf_number) - return; + goto fail; mmi->tii_stats.signal = atoi(argv[1]) * 0xffff / lfe->sf_device->sd_sig_scale; mmi->tii_stats.signal_scale = @@ -767,13 +770,13 @@ satip_frontend_decode_rtcp( satip_frontend_t *lfe, const char *name, goto ok; } else if (strncmp(s, "ver=1.0;", 8) == 0) { if ((s = strstr(s + 8, ";tuner=")) == NULL) - return; + goto fail; s += 7; n = http_tokenize(s, argv, 4, ','); if (n < 4) - return; + goto fail; if (atoi(argv[0]) != lfe->sf_number) - return; + goto fail; mmi->tii_stats.signal = atoi(argv[1]) * 0xffff / lfe->sf_device->sd_sig_scale; mmi->tii_stats.signal_scale = @@ -787,9 +790,9 @@ satip_frontend_decode_rtcp( satip_frontend_t *lfe, const char *name, } else if (strncmp(s, "ver=1.1;tuner=", 14) == 0) { n = http_tokenize(s + 14, argv, 4, ','); if (n < 4) - return; + goto fail; if (atoi(argv[0]) != lfe->sf_number) - return; + goto fail; mmi->tii_stats.signal = atoi(argv[1]) * 0xffff / lfe->sf_device->sd_sig_scale; mmi->tii_stats.signal_scale = @@ -806,7 +809,7 @@ satip_frontend_decode_rtcp( satip_frontend_t *lfe, const char *name, rtcp += l; len -= l; } - return; + goto fail; ok: if (mmi->tii_stats.snr < 2 && status == SIGNAL_GOOD) @@ -814,6 +817,8 @@ ok: else if (mmi->tii_stats.snr < 4 && status == SIGNAL_GOOD) status = SIGNAL_FAINT; lfe->sf_status = status; +fail: + pthread_mutex_unlock(&mmi->tii_stats_mutex); } static int @@ -1127,7 +1132,7 @@ wrdata: pthread_mutex_lock(&lfe->sf_dvr_lock); if (lfe->sf_req == lfe->sf_req_thread) { mmi = lfe->sf_req->sf_mmi; - mmi->tii_stats.unc += unc; + atomic_add(&mmi->tii_stats.unc, unc); mpegts_input_recv_packets((mpegts_input_t*)lfe, mmi, &lfe->sf_sbuf, 0, NULL); } @@ -1687,7 +1692,7 @@ wrdata: } pthread_mutex_lock(&lfe->sf_dvr_lock); if (lfe->sf_req == lfe->sf_req_thread) { - mmi->tii_stats.unc += unc; + atomic_add(&mmi->tii_stats.unc, unc); mpegts_input_recv_packets((mpegts_input_t*)lfe, mmi, sb, 0, NULL); } else fatal = 1; diff --git a/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c b/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c index 179774afc..4dfa459ca 100644 --- a/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c +++ b/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c @@ -272,6 +272,8 @@ tvhdhomerun_frontend_monitor_cb( void *aux ) } } + pthread_mutex_lock(&mmi->tii_stats_mutex); + if(tuner_status.signal_present) { /* TODO: totaly stupid conversion from 0-100 scale to 0-655.35 */ mmi->tii_stats.snr = tuner_status.signal_to_noise_quality * 655.35; @@ -286,10 +288,12 @@ tvhdhomerun_frontend_monitor_cb( void *aux ) sigstat.signal = mmi->tii_stats.signal; sigstat.signal_scale = mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE; sigstat.ber = mmi->tii_stats.ber; - sigstat.unc = mmi->tii_stats.unc; + sigstat.unc = atomic_get(&mmi->tii_stats.unc); sm.sm_type = SMT_SIGNAL_STATUS; sm.sm_data = &sigstat; + pthread_mutex_unlock(&mmi->tii_stats_mutex); + LIST_FOREACH(svc, &mmi->mmi_mux->mm_transports, s_active_link) { pthread_mutex_lock(&svc->s_stream_mutex); streaming_pad_deliver(&svc->s_streaming_pad, streaming_msg_clone(&sm)); -- 2.47.3