From 1579bab2e5840e8f7e7918b7cabf250ca4fd259a Mon Sep 17 00:00:00 2001 From: eb Date: Sat, 15 Aug 2009 17:39:10 +0000 Subject: [PATCH] gr_blocks may now produce different number of output items on each output stream. Merged eb/varying -r11178:11595 into trunk. Needs QA and examples. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@11597 221aa14e-8319-0410-a670-987f0aec2ac5 --- gnuradio-core/src/lib/runtime/gr_block.cc | 8 +++++++- gnuradio-core/src/lib/runtime/gr_block.h | 19 ++++++++++++++++--- .../src/lib/runtime/gr_block_detail.cc | 18 +++++++++++++++--- .../src/lib/runtime/gr_block_detail.h | 9 ++++++++- .../src/lib/runtime/gr_block_executor.cc | 13 ++++++++----- 5 files changed, 54 insertions(+), 13 deletions(-) diff --git a/gnuradio-core/src/lib/runtime/gr_block.cc b/gnuradio-core/src/lib/runtime/gr_block.cc index b8b1bd9c..8915f336 100644 --- a/gnuradio-core/src/lib/runtime/gr_block.cc +++ b/gnuradio-core/src/lib/runtime/gr_block.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2009 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -99,6 +99,12 @@ gr_block::consume_each (int how_many_items) d_detail->consume_each (how_many_items); } +void +gr_block::produce (int which_output, int how_many_items) +{ + d_detail->produce (which_output, how_many_items); +} + int gr_block::fixed_rate_ninput_to_noutput(int ninput) { diff --git a/gnuradio-core/src/lib/runtime/gr_block.h b/gnuradio-core/src/lib/runtime/gr_block.h index 354695c0..b6f724dd 100644 --- a/gnuradio-core/src/lib/runtime/gr_block.h +++ b/gnuradio-core/src/lib/runtime/gr_block.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2007 Free Software Foundation, Inc. + * Copyright 2004,2007,2009 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -57,6 +57,12 @@ class gr_block : public gr_basic_block { public: + //! Magic return values from general_work + enum { + WORK_CALLED_PRODUCE = -2, + WORK_DONE = -1 + }; + virtual ~gr_block (); /*! @@ -70,7 +76,7 @@ class gr_block : public gr_basic_block { void set_history (unsigned history) { d_history = history; } /*! - * \brief return true if this block has a fixed input to output rate + * \brief Return true if this block has a fixed input to output rate. * * If true, then fixed_rate_in_to_out and fixed_rate_out_to_in may be called. */ @@ -149,6 +155,13 @@ class gr_block : public gr_basic_block { */ void consume_each (int how_many_items); + /*! + * \brief Tell the scheduler \p how_many_items were produced on output stream \p which_output. + * + * If the block's general_work method calls produce, \p general_work must return WORK_CALLED_PRODUCE. + */ + void produce (int which_output, int how_many_items); + /*! * \brief Set the approximate output rate / input rate * @@ -191,7 +204,7 @@ class gr_block : public gr_basic_block { int d_output_multiple; double d_relative_rate; // approx output_rate / input_rate - gr_block_detail_sptr d_detail; // implementation details + gr_block_detail_sptr d_detail; // implementation details unsigned d_history; bool d_fixed_rate; diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.cc b/gnuradio-core/src/lib/runtime/gr_block_detail.cc index ae1ea256..f36a6c21 100644 --- a/gnuradio-core/src/lib/runtime/gr_block_detail.cc +++ b/gnuradio-core/src/lib/runtime/gr_block_detail.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2009 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -36,7 +36,8 @@ gr_block_detail_ncurrently_allocated () } gr_block_detail::gr_block_detail (unsigned int ninputs, unsigned int noutputs) - : d_ninputs (ninputs), d_noutputs (noutputs), + : d_produce_or(0), + d_ninputs (ninputs), d_noutputs (noutputs), d_input (ninputs), d_output (noutputs), d_done (false) { @@ -99,10 +100,21 @@ gr_block_detail::consume_each (int how_many_items) d_input[i]->update_read_pointer (how_many_items); } +void +gr_block_detail::produce (int which_output, int how_many_items) +{ + if (how_many_items > 0){ + d_output[which_output]->update_write_pointer (how_many_items); + d_produce_or |= how_many_items; + } +} + void gr_block_detail::produce_each (int how_many_items) { - if (how_many_items > 0) + if (how_many_items > 0){ for (int i = 0; i < noutputs (); i++) d_output[i]->update_write_pointer (how_many_items); + d_produce_or |= how_many_items; + } } diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.h b/gnuradio-core/src/lib/runtime/gr_block_detail.h index 2856c402..f32a875e 100644 --- a/gnuradio-core/src/lib/runtime/gr_block_detail.h +++ b/gnuradio-core/src/lib/runtime/gr_block_detail.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2009 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -73,13 +73,20 @@ class gr_block_detail { */ void consume_each (int how_many_items); + /*! + * \brief Tell the scheduler \p how_many_items were produced on output stream \p which_output. + */ + void produce (int which_output, int how_many_items); + /*! * \brief Tell the scheduler \p how_many_items were produced on each output stream. */ void produce_each (int how_many_items); + gr_tpb_detail d_tpb; // used by thread-per-block scheduler + int d_produce_or; // ---------------------------------------------------------------------------- diff --git a/gnuradio-core/src/lib/runtime/gr_block_executor.cc b/gnuradio-core/src/lib/runtime/gr_block_executor.cc index e8d30b96..2c21a0b0 100644 --- a/gnuradio-core/src/lib/runtime/gr_block_executor.cc +++ b/gnuradio-core/src/lib/runtime/gr_block_executor.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2008 Free Software Foundation, Inc. + * Copyright 2004,2008,2009 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -290,6 +290,7 @@ gr_block_executor::run_one_iteration() setup_call_to_work: + d->d_produce_or = 0; for (int i = 0; i < d->noutputs (); i++) d_output_items[i] = d->output(i)->write_pointer(); @@ -299,11 +300,13 @@ gr_block_executor::run_one_iteration() LOG(*d_log << " general_work: noutput_items = " << noutput_items << " result = " << n << std::endl); - if (n == -1) // block is done + if (n == gr_block::WORK_DONE) goto were_done; - d->produce_each (n); // advance write pointers - if (n > 0) + if (n != gr_block::WORK_CALLED_PRODUCE) + d->produce_each (n); // advance write pointers + + if (d->d_produce_or > 0) // block produced something return READY; // We didn't produce any output even though we called general_work. @@ -312,7 +315,7 @@ gr_block_executor::run_one_iteration() // If this is a source, it's broken. if (d->source_p()){ std::cerr << "gr_block_executor: source " << m - << " returned 0 from work. We're marking it DONE.\n"; + << " produced no output. We're marking it DONE.\n"; // FIXME maybe we ought to raise an exception... goto were_done; } -- 2.39.5