diff options
-rw-r--r-- | lib/block_handlers.cpp | 2 | ||||
-rw-r--r-- | lib/gras_impl/input_buffer_queues.hpp | 16 | ||||
-rw-r--r-- | lib/gras_impl/output_buffer_queues.hpp | 23 | ||||
-rw-r--r-- | lib/top_block_query.cpp | 2 | ||||
-rw-r--r-- | python/gras/query/CMakeLists.txt | 1 | ||||
-rw-r--r-- | python/gras/query/chart_factory.js | 1 | ||||
-rw-r--r-- | python/gras/query/chart_port_downtime.js | 47 | ||||
-rw-r--r-- | python/gras/query/main.html | 1 |
8 files changed, 87 insertions, 6 deletions
diff --git a/lib/block_handlers.cpp b/lib/block_handlers.cpp index d548ee0..12ba065 100644 --- a/lib/block_handlers.cpp +++ b/lib/block_handlers.cpp @@ -149,6 +149,8 @@ void BlockActor::handle_get_stats( } this->stats.actor_queue_depth = this->GetNumQueuedMessages(); this->stats.bytes_copied = this->input_queues.bytes_copied; + this->stats.inputs_idle = this->input_queues.total_idle_times; + this->stats.outputs_idle = this->output_queues.total_idle_times; //create the message reply object GetStatsMessage message; diff --git a/lib/gras_impl/input_buffer_queues.hpp b/lib/gras_impl/input_buffer_queues.hpp index f9ae3a2..86b0932 100644 --- a/lib/gras_impl/input_buffer_queues.hpp +++ b/lib/gras_impl/input_buffer_queues.hpp @@ -40,6 +40,10 @@ struct InputBufferQueues return null; } + InputBufferQueues(void): + _init_time(time_now()) + {} + ~InputBufferQueues(void) { this->resize(0); @@ -143,7 +147,12 @@ struct InputBufferQueues GRAS_FORCE_INLINE void __update(const size_t i) { + const bool was_ready = _bitset[i]; _bitset.set(i, _enqueued_bytes[i] >= _reserve_bytes[i]); + const bool is_ready = _bitset[i]; + if (is_ready and not was_ready) total_idle_times[i] += (time_now() - _became_idle_times[i]); + if (not is_ready and was_ready) _became_idle_times[i] = time_now(); + ASSERT(total_idle_times[i] <= (time_now() - _init_time)); } GRAS_FORCE_INLINE size_t get_items_enqueued(const size_t i) @@ -166,6 +175,9 @@ struct InputBufferQueues std::vector<size_t> _preload_bytes; std::vector<boost::shared_ptr<SimpleBufferQueue> > _aux_queues; std::vector<item_index_t> bytes_copied; + std::vector<time_ticks_t> total_idle_times; + std::vector<time_ticks_t> _became_idle_times; + const time_ticks_t _init_time; }; @@ -179,7 +191,9 @@ GRAS_FORCE_INLINE void InputBufferQueues::resize(const size_t size) _preload_bytes.resize(size, 0); _reserve_bytes.resize(size, 1); _maximum_bytes.resize(size, MAX_AUX_BUFF_BYTES); - bytes_copied.resize(size); + bytes_copied.resize(size, 0); + total_idle_times.resize(size, 0); + _became_idle_times.resize(size, time_now()); } inline void InputBufferQueues::update_config( diff --git a/lib/gras_impl/output_buffer_queues.hpp b/lib/gras_impl/output_buffer_queues.hpp index f0859a3..2d7304a 100644 --- a/lib/gras_impl/output_buffer_queues.hpp +++ b/lib/gras_impl/output_buffer_queues.hpp @@ -14,6 +14,10 @@ struct OutputBufferQueues { std::string name; //for debug + OutputBufferQueues(void): + _init_time(time_now()) + {} + void set_buffer_queue(const size_t i, BufferQueueSptr queue) { _queues[i] = queue; @@ -32,6 +36,8 @@ struct OutputBufferQueues _queues.resize(size); _reserve_bytes.resize(size, 1); _inline_buffer.resize(size); + total_idle_times.resize(size, 0); + _became_idle_times.resize(size, time_now()); } GRAS_FORCE_INLINE void push(const size_t i, const SBuffer &buff) @@ -116,14 +122,18 @@ struct OutputBufferQueues GRAS_FORCE_INLINE void _update(const size_t i) { - if (not _queues[i] or _queues[i]->empty()) + size_t avail = 0; + if (_queues[i] and not _queues[i]->empty()) { - _bitset.reset(i); - return; + const SBuffer &front = _queues[i]->front(); + avail = front.get_actual_length() - front.offset - front.length; } - const SBuffer &front = _queues[i]->front(); - const size_t avail = front.get_actual_length() - front.offset - front.length; + const bool was_ready = _bitset[i]; _bitset.set(i, avail >= _reserve_bytes[i]); + const bool is_ready = _bitset[i]; + if (is_ready and not was_ready) total_idle_times[i] += (time_now() - _became_idle_times[i]); + if (not is_ready and was_ready) _became_idle_times[i] = time_now(); + ASSERT(total_idle_times[i] <= (time_now() - _init_time)); } GRAS_FORCE_INLINE void set_inline(const size_t i, const SBuffer &inline_buffer) @@ -137,6 +147,9 @@ struct OutputBufferQueues std::vector<BufferQueueSptr> _queues; std::vector<size_t> _reserve_bytes; std::vector<SBuffer> _inline_buffer; + std::vector<time_ticks_t> total_idle_times; + std::vector<time_ticks_t> _became_idle_times; + const time_ticks_t _init_time; }; diff --git a/lib/top_block_query.cpp b/lib/top_block_query.cpp index b7a532f..29d3bb0 100644 --- a/lib/top_block_query.cpp +++ b/lib/top_block_query.cpp @@ -146,6 +146,8 @@ static std::string query_stats(ElementImpl *self, const boost::property_tree::pt my_block_ptree_append(tags_produced); my_block_ptree_append(msgs_produced); my_block_ptree_append(bytes_copied); + my_block_ptree_append(inputs_idle); + my_block_ptree_append(outputs_idle); blocks.push_back(std::make_pair(message.block_id, block)); } root.push_back(std::make_pair("blocks", blocks)); diff --git a/python/gras/query/CMakeLists.txt b/python/gras/query/CMakeLists.txt index 2758d11..f9a855e 100644 --- a/python/gras/query/CMakeLists.txt +++ b/python/gras/query/CMakeLists.txt @@ -21,6 +21,7 @@ INSTALL( chart_handler_breakdown.js chart_port_counters.js chart_global_counters.js + chart_port_downtime.js main.css DESTINATION ${GR_PYTHON_DIR}/gras/query COMPONENT ${GRAS_COMP_PYTHON} diff --git a/python/gras/query/chart_factory.js b/python/gras/query/chart_factory.js index 01a7244..8b9656a 100644 --- a/python/gras/query/chart_factory.js +++ b/python/gras/query/chart_factory.js @@ -14,6 +14,7 @@ var gras_chart_get_registry = function() {key:'handler_breakdown', name:'Handler Breakdown', factory:GrasChartHandlerBreakdown}, {key:'port_counters', name:'Port Counters', factory:GrasChartPortCounts}, {key:'global_counters', name:'Global Counters', factory:GrasChartGlobalCounts}, + {key:'port_downtime', name:'Port downtime', factory:GrasChartPortDowntime}, ]; } diff --git a/python/gras/query/chart_port_downtime.js b/python/gras/query/chart_port_downtime.js new file mode 100644 index 0000000..2de421d --- /dev/null +++ b/python/gras/query/chart_port_downtime.js @@ -0,0 +1,47 @@ +function GrasChartPortDowntime(args, panel) +{ + //input checking + if (args.block_ids.length != 1) throw gras_error_dialog( + "GrasChartPortDowntime", + "Error making port downtime chart.\n"+ + "Specify only one block for this chart." + ); + + //save enable + this.block_id = args.block_ids[0]; + + //make new chart + this.chart = new google.visualization.PieChart(panel); + + this.title = "Port Downtime - " + this.block_id; + this.default_width = GRAS_CHARTS_STD_WIDTH; +} + +GrasChartPortDowntime.prototype.update = function(point) +{ + var block_data = point.blocks[this.block_id]; + if (!block_data) return; + + var raw_data = new Array(); + raw_data.push(['Port', 'Percent']); //key + + //now add input and output port data + $.each(block_data.inputs_idle, function(index, downtime) + { + raw_data.push(['Input'+index.toString(), downtime/block_data.tps]); + }); + $.each(block_data.outputs_idle, function(index, downtime) + { + raw_data.push(['Output'+index.toString(), downtime/block_data.tps]); + }); + + //update the chart from raw data + var data = google.visualization.arrayToDataTable(raw_data); + var options = { + chartArea:{left:5,top:0,right:5,bottom:0,width:"100%",height:"100%"}, + }; + if (this.gc_resize) options.width = 50; + if (this.gc_resize) options.height = 50; + + this.chart.draw(data, options); +}; diff --git a/python/gras/query/main.html b/python/gras/query/main.html index ca957be..3fc3508 100644 --- a/python/gras/query/main.html +++ b/python/gras/query/main.html @@ -16,6 +16,7 @@ <script type="text/javascript" src="/chart_handler_breakdown.js"></script> <script type="text/javascript" src="/chart_port_counters.js"></script> <script type="text/javascript" src="/chart_global_counters.js"></script> + <script type="text/javascript" src="/chart_port_downtime.js"></script> <script type="text/javascript" src="/main.js"></script> <script type="text/javascript"> google.load('visualization', '1.0', {'packages':['corechart']}); |