summaryrefslogtreecommitdiff
path: root/gnuradio-runtime/lib/block.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-runtime/lib/block.cc')
-rw-r--r--gnuradio-runtime/lib/block.cc141
1 files changed, 141 insertions, 0 deletions
diff --git a/gnuradio-runtime/lib/block.cc b/gnuradio-runtime/lib/block.cc
index cddf5a5baa..bb6ce95298 100644
--- a/gnuradio-runtime/lib/block.cc
+++ b/gnuradio-runtime/lib/block.cc
@@ -24,6 +24,12 @@
namespace gr {
+// Moved from flat_flowgraph.cc
+// 32Kbyte buffer size between blocks
+#define GR_FIXED_BUFFER_SIZE (32 * (1L << 10))
+
+static const unsigned int s_fixed_buffer_size = GR_FIXED_BUFFER_SIZE;
+
block::block(const std::string& name,
io_signature::sptr input_signature,
io_signature::sptr output_signature)
@@ -375,11 +381,146 @@ void block::set_min_output_buffer(int port, long min_output_buffer)
d_min_output_buffer[port] = min_output_buffer;
}
+void block::allocate_detail(int ninputs,
+ int noutputs,
+ const std::vector<int>& downstream_max_nitems_vec,
+ const std::vector<uint64_t>& downstream_lcm_nitems_vec)
+{
+ block_detail_sptr detail = make_block_detail(ninputs, noutputs);
+
+ GR_LOG_DEBUG(d_debug_logger, "Creating block detail for " + identifier());
+
+ for (int i = 0; i < noutputs; i++) {
+ expand_minmax_buffer(i);
+
+ buffer_sptr buffer = allocate_buffer(
+ i, downstream_max_nitems_vec[i], downstream_lcm_nitems_vec[i]);
+ GR_LOG_DEBUG(d_debug_logger,
+ "Allocated buffer for output " + identifier() + " " +
+ std::to_string(i));
+ detail->set_output(i, buffer);
+
+ // Update the block's max_output_buffer based on what was actually allocated.
+ if ((max_output_buffer(i) != buffer->bufsize()) && (max_output_buffer(i) != -1))
+ GR_LOG_WARN(d_logger,
+ boost::format("Block (%1%) max output buffer set to %2%"
+ " instead of requested %3%") %
+ alias() % buffer->bufsize() % max_output_buffer(i));
+ set_max_output_buffer(i, buffer->bufsize());
+ }
+
+ // Store the block_detail that was created above
+ set_detail(detail);
+}
+
+buffer_sptr block::replace_buffer(uint32_t out_port, block_sptr block_owner)
+{
+ block_detail_sptr detail_ = detail();
+ buffer_sptr orig_buffer = detail_->output(out_port);
+
+ // Make a new buffer but this time use the passed in block as the owner
+ buffer_sptr new_buffer = make_buffer(orig_buffer->bufsize(),
+ orig_buffer->get_sizeof_item(),
+ orig_buffer->get_downstream_lcm_nitems(),
+ shared_from_base<block>(),
+ block_owner);
+
+ detail_->set_output(out_port, new_buffer);
+ return new_buffer;
+}
bool block::update_rate() const { return d_update_rate; }
void block::enable_update_rate(bool en) { d_update_rate = en; }
+buffer_sptr block::allocate_buffer(int port,
+ int downstream_max_nitems,
+ uint64_t downstream_lcm_nitems)
+{
+ int item_size = output_signature()->sizeof_stream_item(port);
+
+ // *2 because we're now only filling them 1/2 way in order to
+ // increase the available parallelism when using the TPB scheduler.
+ // (We're double buffering, where we used to single buffer)
+ int nitems = s_fixed_buffer_size * 2 / item_size;
+
+ // Make sure there are at least twice the output_multiple no. of items
+ if (nitems < 2 * output_multiple()) // Note: this means output_multiple()
+ nitems = 2 * output_multiple(); // can't be changed by block dynamically
+
+ // Limit buffer size if indicated
+ if (max_output_buffer(port) > 0) {
+ // std::cout << "constraining output items to " << block->max_output_buffer(port)
+ // << "\n";
+ nitems = std::min((long)nitems, (long)max_output_buffer(port));
+ nitems -= nitems % output_multiple();
+ if (nitems < 1)
+ throw std::runtime_error("problems allocating a buffer with the given max "
+ "output buffer constraint!");
+ } else if (min_output_buffer(port) > 0) {
+ nitems = std::max((long)nitems, (long)min_output_buffer(port));
+ nitems -= nitems % output_multiple();
+ if (nitems < 1)
+ throw std::runtime_error("problems allocating a buffer with the given min "
+ "output buffer constraint!");
+ }
+
+ // If any downstream blocks are decimators and/or have a large output_multiple,
+ // ensure we have a buffer at least twice their decimation factor*output_multiple
+ nitems = std::max(nitems, downstream_max_nitems);
+
+ // We're going to let this fail once and retry. If that fails, throw and exit.
+ buffer_sptr buf;
+
+#ifdef BUFFER_DEBUG
+ // BUFFER DEBUG
+ GR_LOG_DEBUG(d_logger,
+ "Block: " + name() + " allocated buffer for output " + identifier());
+#endif
+
+ try {
+#ifdef BUFFER_DEBUG
+ // BUFFER DEBUG
+ std::ostringstream msg;
+ msg << "downstream_max_nitems: " << downstream_max_nitems
+ << " -- downstream_lcm_nitems: " << downstream_lcm_nitems
+ << " -- output_multiple(): " << output_multiple()
+ << " -- out_mult_set: " << output_multiple_set() << " -- nitems: " << nitems
+ << " -- history: " << history() << " -- relative_rate: " << relative_rate();
+ if (relative_rate() != 1.0) {
+ msg << " (" << relative_rate_i() << " / " << relative_rate_d() << ")";
+ }
+ msg << " -- fixed_rate: " << fixed_rate();
+ if (fixed_rate()) {
+ int num_inputs = fixed_rate_noutput_to_ninput(1) - (history() - 1);
+ msg << " (" << num_inputs << " -> "
+ << fixed_rate_ninput_to_noutput(num_inputs + (history() - 1)) << ")";
+ }
+ GR_LOG_DEBUG(d_logger, msg.str());
+#endif
+ buf = make_buffer(nitems,
+ item_size,
+ downstream_lcm_nitems,
+ shared_from_base<block>(),
+ shared_from_base<block>());
+
+ } catch (std::bad_alloc&) {
+ buf = make_buffer(nitems,
+ item_size,
+ downstream_lcm_nitems,
+ shared_from_base<block>(),
+ shared_from_base<block>());
+ }
+
+ // Set the max noutput items size here to make sure it's always
+ // set in the block and available in the start() method.
+ // But don't overwrite if the user has set this externally.
+ if (!is_set_max_noutput_items())
+ set_max_noutput_items(nitems);
+
+ return buf;
+}
+
float block::pc_noutput_items()
{
if (d_detail) {