summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-core/src/lib')
-rw-r--r--gnuradio-core/src/lib/general/gr_skiphead.cc4
-rw-r--r--gnuradio-core/src/lib/general/gri_control_loop.cc23
-rw-r--r--gnuradio-core/src/lib/general/gri_control_loop.h39
-rw-r--r--gnuradio-core/src/lib/io/gr_udp_source.cc10
-rw-r--r--gnuradio-core/src/lib/runtime/gr_basic_block.cc4
-rw-r--r--gnuradio-core/src/lib/runtime/gr_basic_block.h74
-rw-r--r--gnuradio-core/src/lib/runtime/gr_basic_block.i6
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.cc31
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.h39
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.i6
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_executor.cc6
-rw-r--r--gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc20
-rw-r--r--gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc5
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_top_block.cc143
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_top_block.h8
15 files changed, 403 insertions, 15 deletions
diff --git a/gnuradio-core/src/lib/general/gr_skiphead.cc b/gnuradio-core/src/lib/general/gr_skiphead.cc
index c887376e4..7b441bea9 100644
--- a/gnuradio-core/src/lib/general/gr_skiphead.cc
+++ b/gnuradio-core/src/lib/general/gr_skiphead.cc
@@ -43,14 +43,14 @@ gr_make_skiphead (size_t itemsize, uint64_t nitems_to_skip)
int
gr_skiphead::general_work(int noutput_items,
- gr_vector_int &ninput_items_ignored,
+ gr_vector_int &ninput_items_,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
const char *in = (const char *) input_items[0];
char *out = (char *) output_items[0];
- int ninput_items = noutput_items; // we've got at least this many input items
+ int ninput_items = std::min(ninput_items_[0], noutput_items);
int ii = 0; // input index
while (ii < ninput_items){
diff --git a/gnuradio-core/src/lib/general/gri_control_loop.cc b/gnuradio-core/src/lib/general/gri_control_loop.cc
index 5a93737f9..bb3c4a326 100644
--- a/gnuradio-core/src/lib/general/gri_control_loop.cc
+++ b/gnuradio-core/src/lib/general/gri_control_loop.cc
@@ -144,6 +144,17 @@ gri_control_loop::set_phase(float phase)
d_phase += M_TWOPI;
}
+void
+gri_control_loop::set_max_freq(float freq)
+{
+ d_max_freq = freq;
+}
+
+void
+gri_control_loop::set_min_freq(float freq)
+{
+ d_min_freq = freq;
+}
/*******************************************************************
GET FUNCTIONS
@@ -185,3 +196,15 @@ gri_control_loop::get_phase() const
{
return d_phase;
}
+
+float
+gri_control_loop::get_max_freq() const
+{
+ return d_max_freq;
+}
+
+float
+gri_control_loop::get_min_freq() const
+{
+ return d_min_freq;
+}
diff --git a/gnuradio-core/src/lib/general/gri_control_loop.h b/gnuradio-core/src/lib/general/gri_control_loop.h
index df260d2cf..304857ac7 100644
--- a/gnuradio-core/src/lib/general/gri_control_loop.h
+++ b/gnuradio-core/src/lib/general/gri_control_loop.h
@@ -141,9 +141,9 @@ class GR_CORE_API gri_control_loop
void set_beta(float beta);
/*!
- * \brief Set the Costas loop's frequency.
+ * \brief Set the control loop's frequency.
*
- * Set's the Costas Loop's frequency. While this is normally updated by the
+ * Set's the control loop's frequency. While this is normally updated by the
* inner loop of the algorithm, it could be useful to manually initialize,
* set, or reset this under certain circumstances.
*
@@ -153,9 +153,9 @@ class GR_CORE_API gri_control_loop
void set_frequency(float freq);
/*!
- * \brief Set the Costas loop's phase.
+ * \brief Set the control loop's phase.
*
- * Set's the Costas Loop's phase. While this is normally updated by the
+ * Set's the control loop's phase. While this is normally updated by the
* inner loop of the algorithm, it could be useful to manually initialize,
* set, or reset this under certain circumstances.
*
@@ -164,6 +164,23 @@ class GR_CORE_API gri_control_loop
*/
void set_phase(float phase);
+ /*!
+ * \brief Set the control loop's maximum frequency.
+ *
+ * Set the maximum frequency the control loop can track.
+ *
+ * \param freq (float) new max frequency
+ */
+ void set_max_freq(float freq);
+
+ /*!
+ * \brief Set the control loop's minimum frequency.
+ *
+ * Set the minimum frequency the control loop can track.
+ *
+ * \param freq (float) new min frequency
+ */
+ void set_min_freq(float freq);
/*******************************************************************
GET FUNCTIONS
@@ -190,14 +207,24 @@ class GR_CORE_API gri_control_loop
float get_beta() const;
/*!
- * \brief Get the Costas loop's frequency estimate
+ * \brief Get the control loop's frequency estimate
*/
float get_frequency() const;
/*!
- * \brief Get the Costas loop's phase estimate
+ * \brief Get the control loop's phase estimate
*/
float get_phase() const;
+
+ /*!
+ * \brief Get the control loop's maximum frequency.
+ */
+ float get_max_freq() const;
+
+ /*!
+ * \brief Get the control loop's minimum frequency.
+ */
+ float get_min_freq() const;
};
#endif /* GRI_CONTROL_LOOP */
diff --git a/gnuradio-core/src/lib/io/gr_udp_source.cc b/gnuradio-core/src/lib/io/gr_udp_source.cc
index af41159ee..eca8e89d0 100644
--- a/gnuradio-core/src/lib/io/gr_udp_source.cc
+++ b/gnuradio-core/src/lib/io/gr_udp_source.cc
@@ -269,8 +269,9 @@ gr_udp_source::work (int noutput_items,
else if(r == 0 ) { // timed out
if( d_wait ) {
// Allow boost thread interrupt, then try again
- boost::this_thread::interruption_point();
- continue;
+ //boost::this_thread::interruption_point();
+ //continue;
+ return 0;
}
else
return -1;
@@ -294,8 +295,9 @@ gr_udp_source::work (int noutput_items,
if( d_wait ) {
// Allow boost thread interrupt, then try again
- boost::this_thread::interruption_point();
- continue;
+ //boost::this_thread::interruption_point();
+ //continue;
+ return 0;
}
else
return -1;
diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.cc b/gnuradio-core/src/lib/runtime/gr_basic_block.cc
index d7263b92d..3d809aa8b 100644
--- a/gnuradio-core/src/lib/runtime/gr_basic_block.cc
+++ b/gnuradio-core/src/lib/runtime/gr_basic_block.cc
@@ -45,7 +45,9 @@ gr_basic_block::gr_basic_block(const std::string &name,
d_input_signature(input_signature),
d_output_signature(output_signature),
d_unique_id(s_next_id++),
- d_color(WHITE)
+ d_color(WHITE),
+ d_max_output_buffer(std::max(output_signature->max_streams(),1), -1),
+ d_min_output_buffer(std::max(output_signature->max_streams(),1), -1)
{
s_ncurrently_allocated++;
}
diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.h b/gnuradio-core/src/lib/runtime/gr_basic_block.h
index 4d03b878e..b8e8148b2 100644
--- a/gnuradio-core/src/lib/runtime/gr_basic_block.h
+++ b/gnuradio-core/src/lib/runtime/gr_basic_block.h
@@ -29,7 +29,9 @@
#include <boost/enable_shared_from_this.hpp>
#include <boost/function.hpp>
#include <gr_msg_accepter.h>
+#include <gr_io_signature.h>
#include <string>
+#include <iostream>
/*!
* \brief The abstract base class for all signal processing blocks.
@@ -61,6 +63,20 @@ private:
msg_handler_t d_msg_handler;
+ /*
+ * Used to expand the vectors that hold the min/max buffer sizes.
+ *
+ * Specifically, when -1 is used, the vectors are just initialized
+ * with 1 value; this is used by the flat_flowgraph to expand when
+ * required to add a new value for new ports on these blocks.
+ */
+ void expand_minmax_buffer(int port) {
+ if((size_t)port >= d_max_output_buffer.size())
+ set_max_output_buffer(port, -1);
+ if((size_t)port >= d_min_output_buffer.size())
+ set_min_output_buffer(port, -1);
+ }
+
protected:
friend class gr_flowgraph;
friend class gr_flat_flowgraph; // TODO: will be redundant
@@ -73,6 +89,8 @@ protected:
gr_io_signature_sptr d_output_signature;
long d_unique_id;
vcolor d_color;
+ std::vector<long> d_max_output_buffer;
+ std::vector<long> d_min_output_buffer;
gr_basic_block(void){} //allows pure virtual interface sub-classes
@@ -106,6 +124,62 @@ public:
gr_basic_block_sptr to_basic_block(); // Needed for Python type coercion
/*!
+ * \brief Returns max buffer size on output port \p i.
+ */
+ long max_output_buffer(size_t i) {
+ if(i >= d_max_output_buffer.size())
+ throw std::invalid_argument("gr_basic_block::max_output_buffer: port out of range.");
+ return d_max_output_buffer[i];
+ }
+
+ /*!
+ * \brief Sets max buffer size on all output ports.
+ */
+ void set_max_output_buffer(long max_output_buffer) {
+ for(int i=0; i<output_signature()->max_streams(); i++) {
+ set_max_output_buffer(i, max_output_buffer);
+ }
+ }
+
+ /*!
+ * \brief Sets max buffer size on output port \p port.
+ */
+ void set_max_output_buffer(int port, long max_output_buffer) {
+ if((size_t)port >= d_max_output_buffer.size())
+ d_max_output_buffer.push_back(max_output_buffer);
+ else
+ d_max_output_buffer[port] = max_output_buffer;
+ }
+
+ /*!
+ * \brief Returns min buffer size on output port \p i.
+ */
+ long min_output_buffer(size_t i) {
+ if(i >= d_min_output_buffer.size())
+ throw std::invalid_argument("gr_basic_block::min_output_buffer: port out of range.");
+ return d_min_output_buffer[i];
+ }
+
+ /*!
+ * \brief Sets min buffer size on all output ports.
+ */
+ void set_min_output_buffer(long min_output_buffer) {
+ for(int i=0; i<output_signature()->max_streams(); i++) {
+ set_min_output_buffer(i, min_output_buffer);
+ }
+ }
+
+ /*!
+ * \brief Sets min buffer size on output port \p port.
+ */
+ void set_min_output_buffer(int port, long min_output_buffer) {
+ if((size_t)port >= d_min_output_buffer.size())
+ d_min_output_buffer.push_back(min_output_buffer);
+ else
+ d_min_output_buffer[port] = min_output_buffer;
+ }
+
+ /*!
* \brief Confirm that ninputs and noutputs is an acceptable combination.
*
* \param ninputs number of input streams connected
diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.i b/gnuradio-core/src/lib/runtime/gr_basic_block.i
index e43cc114c..7713f2fe1 100644
--- a/gnuradio-core/src/lib/runtime/gr_basic_block.i
+++ b/gnuradio-core/src/lib/runtime/gr_basic_block.i
@@ -42,6 +42,12 @@ public:
long unique_id() const;
gr_basic_block_sptr to_basic_block();
bool check_topology (int ninputs, int noutputs);
+ long max_output_buffer(int i);
+ void set_max_output_buffer(long max_output_buffer);
+ void set_max_output_buffer(int port, long max_output_buffer);
+ long min_output_buffer(int i);
+ void set_min_output_buffer(long min_output_buffer);
+ void set_min_output_buffer(int port, long min_output_buffer);
};
%rename(block_ncurrently_allocated) gr_basic_block_ncurrently_allocated;
diff --git a/gnuradio-core/src/lib/runtime/gr_block.cc b/gnuradio-core/src/lib/runtime/gr_block.cc
index 9a5255a93..7e01c0ba8 100644
--- a/gnuradio-core/src/lib/runtime/gr_block.cc
+++ b/gnuradio-core/src/lib/runtime/gr_block.cc
@@ -40,6 +40,8 @@ gr_block::gr_block (const std::string &name,
d_relative_rate (1.0),
d_history(1),
d_fixed_rate(false),
+ d_max_noutput_items_set(false),
+ d_max_noutput_items(0),
d_tag_propagation_policy(TPP_ALL_TO_ALL)
{
}
@@ -208,6 +210,35 @@ gr_block::set_tag_propagation_policy(tag_propagation_policy_t p)
d_tag_propagation_policy = p;
}
+
+int
+gr_block::max_noutput_items()
+{
+ return d_max_noutput_items;
+}
+
+void
+gr_block::set_max_noutput_items(int m)
+{
+ if(m <= 0)
+ throw std::runtime_error("gr_block::set_max_noutput_items: value for max_noutput_items must be greater than 0.\n");
+
+ d_max_noutput_items = m;
+ d_max_noutput_items_set = true;
+}
+
+void
+gr_block::unset_max_noutput_items()
+{
+ d_max_noutput_items_set = false;
+}
+
+bool
+gr_block::is_set_max_noutput_items()
+{
+ return d_max_noutput_items_set;
+}
+
std::ostream&
operator << (std::ostream& os, const gr_block *m)
{
diff --git a/gnuradio-core/src/lib/runtime/gr_block.h b/gnuradio-core/src/lib/runtime/gr_block.h
index 71ac8eee6..c89138bb3 100644
--- a/gnuradio-core/src/lib/runtime/gr_block.h
+++ b/gnuradio-core/src/lib/runtime/gr_block.h
@@ -251,6 +251,43 @@ class GR_CORE_API gr_block : public gr_basic_block {
*/
void set_tag_propagation_policy(tag_propagation_policy_t p);
+ /*!
+ * \brief Return the maximum number of output items this block will
+ * handle during a call to work.
+ */
+ int max_noutput_items();
+
+ /*!
+ * \brief Set the maximum number of ouput items htis block will
+ * handle during a call to work.
+ *
+ * \param m the maximum noutput_items this block will handle.
+ */
+ void set_max_noutput_items(int m);
+
+ /*!
+ * \brief Clear the switch for using the max_noutput_items value of this block.
+ *
+ * When is_set_max_noutput_items() returns 'true', the scheduler
+ * will use the value returned by max_noutput_items() to limit the
+ * size of the number of items possible for this block's work
+ * function. If is_set_max_notput_items() returns 'false', then the
+ * scheduler ignores the internal value and uses the value set
+ * globally in the top_block.
+ *
+ * Use this value to clear the 'is_set' flag so the scheduler will
+ * ignore this. Use the set_max_noutput_items(m) call to both set a
+ * new value for max_noutput_items and to reenable its use in the
+ * scheduler.
+ */
+ void unset_max_noutput_items();
+
+ /*!
+ * \brief Ask the block if the flag is or is not set to use the
+ * internal value of max_noutput_items during a call to work.
+ */
+ bool is_set_max_noutput_items();
+
// ----------------------------------------------------------------------------
private:
@@ -263,6 +300,8 @@ class GR_CORE_API gr_block : public gr_basic_block {
gr_block_detail_sptr d_detail; // implementation details
unsigned d_history;
bool d_fixed_rate;
+ bool d_max_noutput_items_set; // if d_max_noutput_items is valid
+ int d_max_noutput_items; // value of max_noutput_items for this block
tag_propagation_policy_t d_tag_propagation_policy; // policy for moving tags downstream
protected:
diff --git a/gnuradio-core/src/lib/runtime/gr_block.i b/gnuradio-core/src/lib/runtime/gr_block.i
index 4cc260bfe..e9341e8cb 100644
--- a/gnuradio-core/src/lib/runtime/gr_block.i
+++ b/gnuradio-core/src/lib/runtime/gr_block.i
@@ -52,6 +52,12 @@ class gr_block : public gr_basic_block {
uint64_t nitems_read(unsigned int which_input);
uint64_t nitems_written(unsigned int which_output);
+ // Methods to manage the block's max_noutput_items size.
+ int max_noutput_items();
+ void set_max_noutput_items(int m);
+ void unset_max_noutput_items();
+ bool is_set_max_noutput_items();
+
// internal use
gr_block_detail_sptr detail () const { return d_detail; }
void set_detail (gr_block_detail_sptr detail) { d_detail = detail; }
diff --git a/gnuradio-core/src/lib/runtime/gr_block_executor.cc b/gnuradio-core/src/lib/runtime/gr_block_executor.cc
index 6fea14613..375b58f56 100644
--- a/gnuradio-core/src/lib/runtime/gr_block_executor.cc
+++ b/gnuradio-core/src/lib/runtime/gr_block_executor.cc
@@ -206,7 +206,7 @@ gr_block_executor::run_one_iteration()
// determine the minimum available output space
noutput_items = min_available_space (d, m->output_multiple ());
- noutput_items = std::min(noutput_items, d_max_noutput_items);
+ noutput_items = std::min(noutput_items, max_noutput_items);
LOG(*d_log << " source\n noutput_items = " << noutput_items << std::endl);
if (noutput_items == -1) // we're done
goto were_done;
@@ -251,7 +251,7 @@ gr_block_executor::run_one_iteration()
// take a swag at how much output we can sink
noutput_items = (int) (max_items_avail * m->relative_rate ());
noutput_items = round_down (noutput_items, m->output_multiple ());
- noutput_items = std::min(noutput_items, d_max_noutput_items);
+ noutput_items = std::min(noutput_items, max_noutput_items);
LOG(*d_log << " max_items_avail = " << max_items_avail << std::endl);
LOG(*d_log << " noutput_items = " << noutput_items << std::endl);
@@ -449,6 +449,7 @@ gr_block_executor::run_one_iteration()
// We didn't produce any output even though we called general_work.
// We have (most likely) consumed some input.
+ /*
// If this is a source, it's broken.
if (d->source_p()){
std::cerr << "gr_block_executor: source " << m
@@ -456,6 +457,7 @@ gr_block_executor::run_one_iteration()
// FIXME maybe we ought to raise an exception...
goto were_done;
}
+ */
// Have the caller try again...
return READY_NO_OUTPUT;
diff --git a/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc b/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc
index 9005cd339..b70135b85 100644
--- a/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc
+++ b/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc
@@ -84,10 +84,14 @@ gr_flat_flowgraph::allocate_block_detail(gr_basic_block_sptr block)
std::cout << "Creating block detail for " << block << std::endl;
for (int i = 0; i < noutputs; i++) {
+ block->expand_minmax_buffer(i);
gr_buffer_sptr buffer = allocate_buffer(block, i);
if (GR_FLAT_FLOWGRAPH_DEBUG)
std::cout << "Allocated buffer for output " << block << ":" << i << std::endl;
detail->set_output(i, buffer);
+
+ // Update the block's max_output_buffer based on what was actually allocated.
+ block->set_max_output_buffer(i, buffer->bufsize());
}
return detail;
@@ -114,6 +118,21 @@ gr_flat_flowgraph::allocate_buffer(gr_basic_block_sptr block, int port)
// ensure we have a buffer at least twice their decimation factor*output_multiple
gr_basic_block_vector_t blocks = calc_downstream_blocks(block, port);
+ // limit buffer size if indicated
+ if(block->max_output_buffer(port) > 0) {
+// std::cout << "constraining output items to " << block->max_output_buffer(port) << "\n";
+ nitems = std::min((long)nitems, (long)block->max_output_buffer(port));
+ nitems -= nitems%grblock->output_multiple();
+ if( nitems < 1 )
+ throw std::runtime_error("problems allocating a buffer with the given max output buffer constraint!");
+ }
+ else if(block->min_output_buffer(port) > 0) {
+ nitems = std::max((long)nitems, (long)block->min_output_buffer(port));
+ nitems -= nitems%grblock->output_multiple();
+ if( nitems < 1 )
+ throw std::runtime_error("problems allocating a buffer with the given min output buffer constraint!");
+ }
+
for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
gr_block_sptr dgrblock = cast_to_block_sptr(*p);
if (!dgrblock)
@@ -125,6 +144,7 @@ gr_flat_flowgraph::allocate_buffer(gr_basic_block_sptr block, int port)
nitems = std::max(nitems, static_cast<int>(2*(decimation*multiple+history)));
}
+// std::cout << "gr_make_buffer(" << nitems << ", " << item_size << ", " << grblock << "\n";
return gr_make_buffer(nitems, item_size, grblock);
}
diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc b/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc
index 131ddd19c..2824eb1b3 100644
--- a/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc
+++ b/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc
@@ -74,6 +74,11 @@ gr_scheduler_tpb::gr_scheduler_tpb(gr_flat_flowgraph_sptr ffg, int max_noutput_i
for (size_t i = 0; i < blocks.size(); i++){
std::stringstream name;
name << "thread-per-block[" << i << "]: " << blocks[i];
+
+ // If set, use internal value instead of global value
+ if(blocks[i]->is_set_max_noutput_items())
+ max_noutput_items = blocks[i]->max_noutput_items();
+
d_threads.create_thread(
gruel::thread_body_wrapper<tpb_container>(tpb_container(blocks[i], max_noutput_items),
name.str()));
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_top_block.cc b/gnuradio-core/src/lib/runtime/qa_gr_top_block.cc
index cc7b7c720..a0b4755a8 100644
--- a/gnuradio-core/src/lib/runtime/qa_gr_top_block.cc
+++ b/gnuradio-core/src/lib/runtime/qa_gr_top_block.cc
@@ -27,6 +27,7 @@
#include <qa_gr_top_block.h>
#include <gr_top_block.h>
#include <gr_head.h>
+#include <gr_nop.h>
#include <gr_null_source.h>
#include <gr_null_sink.h>
#include <iostream>
@@ -119,3 +120,145 @@ void qa_gr_top_block::t4_reconfigure()
// Wait for flowgraph to end on its own
tb->wait();
}
+
+
+void qa_gr_top_block::t5_max_noutputs()
+{
+ if (VERBOSE) std::cout << "qa_gr_top_block::t5()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr head = gr_make_head(sizeof(int), 100000);
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ // Start infinite flowgraph
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, dst, 0);
+ tb->start(100);
+ tb->wait();
+}
+
+void qa_gr_top_block::t6_reconfig_max_noutputs()
+{
+ if (VERBOSE) std::cout << "qa_gr_top_block::t6()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr head = gr_make_head(sizeof(int), 100000);
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ // Start infinite flowgraph
+ tb->connect(src, 0, dst, 0);
+ tb->start(100);
+
+ // Reconfigure with gr_head in the middle
+ tb->lock();
+ tb->disconnect(src, 0, dst, 0);
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, dst, 0);
+ tb->set_max_noutput_items(1000);
+ head->set_max_noutput_items(500);
+ tb->unlock();
+
+ // Wait for flowgraph to end on its own
+ tb->wait();
+}
+
+void qa_gr_top_block::t7_max_noutputs_per_block()
+{
+ if (VERBOSE) std::cout << "qa_gr_top_block::t7()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr head = gr_make_head(sizeof(int), 100000);
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ head->set_max_noutput_items(100);
+
+ // Start infinite flowgraph
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, dst, 0);
+ tb->start();
+ tb->wait();
+}
+
+void qa_gr_top_block::t8_reconfig_max_noutputs_per_block()
+{
+ if (VERBOSE) std::cout << "qa_gr_top_block::t8()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr head = gr_make_head(sizeof(int), 100000);
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ head->set_max_noutput_items(99);
+
+ // Start infinite flowgraph
+ tb->connect(src, 0, dst, 0);
+ tb->start(201);
+
+ // Reconfigure with gr_head in the middle
+ tb->lock();
+ tb->disconnect(src, 0, dst, 0);
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, dst, 0);
+ tb->set_max_noutput_items(1023);
+ head->set_max_noutput_items(513);
+ tb->unlock();
+
+ // Wait for flowgraph to end on its own
+ tb->wait();
+}
+
+void qa_gr_top_block::t9_max_output_buffer()
+{
+ if (VERBOSE) std::cout << "qa_gr_top_block::t9()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr head = gr_make_head(sizeof(int), 100000);
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ head->set_max_output_buffer(1024);
+
+ // Start infinite flowgraph
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, dst, 0);
+ tb->start();
+ tb->wait();
+}
+
+void qa_gr_top_block::t10_reconfig_max_output_buffer()
+{
+ if (VERBOSE) std::cout << "qa_gr_top_block::t10()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr head = gr_make_head(sizeof(int), 100000);
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ head->set_max_output_buffer(1000);
+
+ // Start infinite flowgraph
+ tb->connect(src, 0, dst, 0);
+ tb->start(201);
+
+ // Reconfigure with gr_head in the middle
+ tb->lock();
+ gr_block_sptr nop = gr_make_nop(sizeof(int));
+ nop->set_max_output_buffer(4000);
+ tb->disconnect(src, 0, dst, 0);
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, nop, 0);
+ tb->connect(nop, 0, dst, 0);
+ tb->unlock();
+
+ // Wait for flowgraph to end on its own
+ tb->wait();
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_top_block.h b/gnuradio-core/src/lib/runtime/qa_gr_top_block.h
index b223633e5..bb891abca 100644
--- a/gnuradio-core/src/lib/runtime/qa_gr_top_block.h
+++ b/gnuradio-core/src/lib/runtime/qa_gr_top_block.h
@@ -36,6 +36,8 @@ class qa_gr_top_block : public CppUnit::TestCase
CPPUNIT_TEST(t2_start_stop_wait);
CPPUNIT_TEST(t3_lock_unlock);
CPPUNIT_TEST(t4_reconfigure); // triggers 'join never returns' bug
+ CPPUNIT_TEST(t5_max_noutputs);
+ CPPUNIT_TEST(t6_reconfig_max_noutputs);
CPPUNIT_TEST_SUITE_END();
@@ -46,6 +48,12 @@ private:
void t2_start_stop_wait();
void t3_lock_unlock();
void t4_reconfigure();
+ void t5_max_noutputs();
+ void t6_reconfig_max_noutputs();
+ void t7_max_noutputs_per_block();
+ void t8_reconfig_max_noutputs_per_block();
+ void t9_max_output_buffer();
+ void t10_reconfig_max_output_buffer();
};
#endif /* INCLUDED_QA_GR_TOP_BLOCK_H */