diff options
Diffstat (limited to 'gnuradio-core/src/lib')
-rw-r--r-- | gnuradio-core/src/lib/general/gr_skiphead.cc | 4 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gri_control_loop.cc | 23 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gri_control_loop.h | 39 | ||||
-rw-r--r-- | gnuradio-core/src/lib/io/gr_udp_source.cc | 10 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_basic_block.cc | 4 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_basic_block.h | 74 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_basic_block.i | 6 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_block.cc | 31 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_block.h | 39 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_block.i | 6 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_block_executor.cc | 6 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc | 20 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc | 5 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/qa_gr_top_block.cc | 143 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/qa_gr_top_block.h | 8 |
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 */ |