summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/block_handlers.cpp2
-rw-r--r--lib/gras_impl/input_buffer_queues.hpp16
-rw-r--r--lib/gras_impl/output_buffer_queues.hpp23
-rw-r--r--lib/top_block_query.cpp2
-rw-r--r--python/gras/query/CMakeLists.txt1
-rw-r--r--python/gras/query/chart_factory.js1
-rw-r--r--python/gras/query/chart_port_downtime.js47
-rw-r--r--python/gras/query/main.html1
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']});