From 0ac597ca41fdeacbe7c7e8fbe92981782a7763b3 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Thu, 15 Feb 2018 17:47:40 +0100 Subject: Do not clear statistics on read --- src/ManagementServer.cpp | 59 ++++++++++++++++++++++++------------------------ src/ManagementServer.h | 13 ++++------- 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/src/ManagementServer.cpp b/src/ManagementServer.cpp index 10ba396..d299085 100644 --- a/src/ManagementServer.cpp +++ b/src/ManagementServer.cpp @@ -34,13 +34,15 @@ #include #include #include +#include #include #include #include #include "ManagementServer.h" #include "Log.h" -static constexpr auto stats_keep_duration = std::chrono::seconds(30); +static constexpr +auto stats_keep_duration = std::chrono::seconds(INPUT_NODATA_TIMEOUT); ManagementServer& get_mgmt_server() { @@ -140,7 +142,6 @@ std::string ManagementServer::getValuesJSON() ss << " \"" << id << "\" : "; ss << stats->encodeValuesJSON(); - stats->reset(); } ss << "}\n}\n"; @@ -256,12 +257,12 @@ InputStat::InputStat(const std::string& name) /* State handling */ time_t now = time(NULL); m_time_last_event = now; - m_time_last_buffer_nonempty = 0; - m_buffer_empty = true; m_glitch_counter = 0; m_silence_counter = 0; - reset(); + buffer_fill_stats.clear(); + peaks_left.clear(); + peaks_right.clear(); } InputStat::~InputStat() @@ -274,34 +275,23 @@ void InputStat::registerAtServer() get_mgmt_server().registerInput(this); } -void InputStat::reset() -{ - min_fill_buffer = MIN_FILL_BUFFER_UNDEF; - max_fill_buffer = 0; - - peaks_left.clear(); - peaks_right.clear(); -} - void InputStat::notifyBuffer(long bufsize) { boost::mutex::scoped_lock lock(m_mutex); - // Statistics - if (bufsize > max_fill_buffer) { - max_fill_buffer = bufsize; - } + buffer_fill_stats.push_back(bufsize); - if (bufsize < min_fill_buffer || - min_fill_buffer == MIN_FILL_BUFFER_UNDEF) { - min_fill_buffer = bufsize; - } + using namespace std::chrono; + const auto time_now = steady_clock::now(); + if (buffer_fill_stats.size() > 1) { + auto insertion_interval = time_now - time_last_buffer_notify; + auto total_length = insertion_interval * buffer_fill_stats.size(); - // State - m_buffer_empty = (bufsize == 0); - if (!m_buffer_empty) { - m_time_last_buffer_nonempty = time(NULL); + if (total_length > stats_keep_duration) { + buffer_fill_stats.pop_front(); + } } + time_last_buffer_notify = time_now; } void InputStat::notifyPeakLevels(int peak_left, int peak_right) @@ -403,6 +393,15 @@ std::string InputStat::encodeValuesJSON() int dB_l = peak_left ? round(20*log10((double)peak_left / int16_max)) : -90; int dB_r = peak_right ? round(20*log10((double)peak_right / int16_max)) : -90; + long min_fill_buffer = MIN_FILL_BUFFER_UNDEF; + long max_fill_buffer = 0; + if (not buffer_fill_stats.empty()) { + auto buffer_min_max_fill = minmax_element(buffer_fill_stats.begin(), + buffer_fill_stats.end()); + min_fill_buffer = *buffer_min_max_fill.first; + max_fill_buffer = *buffer_min_max_fill.second; + } + ss << "{ \"inputstat\" : {" "\"min_fill\": " << min_fill_buffer << ", " @@ -453,12 +452,14 @@ input_state_t InputStat::determineState() /* If the buffer has been empty for more than * INPUT_NODATA_TIMEOUT, we go to the NoData state. + * + * Consider an empty deque to be NoData too. */ - if (m_buffer_empty && - now - m_time_last_buffer_nonempty > INPUT_NODATA_TIMEOUT) { + if (std::all_of( + buffer_fill_stats.begin(), buffer_fill_stats.end(), + [](long fill) { return fill == 0; }) ) { state = NoData; } - /* Otherwise, the state depends on the glitch counter */ else if (m_glitch_counter >= INPUT_UNSTABLE_THRESHOLD) { state = Unstable; diff --git a/src/ManagementServer.h b/src/ManagementServer.h index fcdbc16..1b432d5 100644 --- a/src/ManagementServer.h +++ b/src/ManagementServer.h @@ -151,10 +151,6 @@ class InputStat ~InputStat(); void registerAtServer(void); - // Gets called each time the statistics are transmitted, - // and resets the counters to zero - void reset(void); - std::string get_name(void) const { return m_name; } /* This function is called for every frame read by @@ -170,9 +166,10 @@ class InputStat std::string m_name; /************ STATISTICS ***********/ - // minimum and maximum buffer fill since last reset - long min_fill_buffer; - long max_fill_buffer; + // Calculate minimum and maximum buffer fill from + // a FIFO of values from the last few seconds + std::deque buffer_fill_stats; + std::chrono::time_point time_last_buffer_notify; // counter of number of overruns and underruns since startup uint32_t num_underruns; @@ -189,8 +186,6 @@ class InputStat int m_glitch_counter; // saturating counter int m_silence_counter; // saturating counter time_t m_time_last_event; - time_t m_time_last_buffer_nonempty; - bool m_buffer_empty; // The mutex that has to be held during all notify and readout mutable boost::mutex m_mutex; -- cgit v1.2.3