Dear Marcus,

Thanks for thorough explanation.

Let me summarize the information, as below.
Correct me if I am wrong.

1).  For sink block derived from gr::sync_block, its work() function should
return noutput_items,
      even though sink block doesn't produce any output.
      This is a norm.

2).  We could opt to let the above work() function returns 0 instead of
noutput_items.
      In this case it should call consume_each(noutput_items) before the
return.
      All other remain the same, this should work.

3).  Can we derive a sink block from gr::block ?
      In this case we must explicitly call consume_each(noutput_items) in
its general_work() function.
      Should the general_work() return 0, or return noutput_items, or
either one will do?
      The forecast() is defined to include
          ninput_items_required[0] = noutput_items;

Question 1:
Sink block doesn't produce any output, hence,  noutput_items=0.
If this noutput_items has a non-zero value, what does this value means, how
is it calculated?

Question 2:
Referring to
http://gnuradio.org/redmine/projects/gnuradio/wiki/OutOfTreeModules#Sources-and-sinks
it says that "Sources and sinks are derived from gr::sync_block".
Why should sink block be categorised as sync block?
Sync block is defined as block that has the same number of input items and
output items,
but sink block doesn't fulfill this condition (sink block has no output).

Regards,
activecat


Note:
My flow graph is very simple. It consists of only two blocks, namely a
source block and a sink block.
The source block sends out a series of integer numbers.
The sink block receives the integers, and print it out (std::cout).
Below is the code of the sink block.
Filename: gr-activecat/lib/integer_sink_impl.cc

namespace gr {
  namespace activecat {

    integer_sink::sptr  integer_sink::make()
    { return gnuradio::get_initial_sptr (new integer_sink_impl()); }

    // private constructor
    integer_sink_impl::integer_sink_impl()
      : gr_sync_block("integer_sink",
              gr_make_io_signature( 1, 1, sizeof(int) ),
              gr_make_io_signature( 0, 0, 0 ))
    { }

    // virtual destructor
    integer_sink_impl::~integer_sink_impl()
    { }

    int
    integer_sink_impl::work( int noutput_items,
              gr_vector_const_void_star &input_items,
              gr_vector_void_star &output_items)
    {
        const int *in = (const int *) input_items[0];
        std::cout << "integer_sink receives: ";
        for (int i=0; i < noutput_items; i++)
            std::cout << in[i] << ", ";
        std::cout << std::endl;
        return noutput_items;  // Don't return 0, else the flowgraph won't
stop even after the source block's work() fucntion return -1
    }

  } /* namespace activecat */
} /* namespace gr */



On Mon, Feb 3, 2014 at 7:04 AM, Marcus Müller <mar...@hostalia.de> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Hi Activecat!
>
>
> On 02.02.2014 03:30, Activecat wrote:
> > Thanks. This solves the problem completely.
> :) Cool.
> >
> > In summary, to stop the flowgraph when the source is empty, we need
> > to: 1).  The source block's work() method returns "WORK_DONE"  (
> > which is -1 ) 2).  The sink block's work() method returns
> > "noutput_items"
> Well, 2. is not really true.
> To explain the mechanism (to understand better, maybe read about sync,
> fixed ratio and general_work blocks in the wiki):
>
> In normal operation, when a block downstream is finished with one
> iteration of work, the scheduler knows how much items on its input
> buffer have been consumed, determining the free space for the upstream
> work(), since that work's output is the same as the formers input
> buffer, to avoid unnecessary copying.
>
> So, if an upstream block says "hey, I'm done forever" (WORK_DONE),
> then the scheduler knows that there is nothing new to do for the
> downstream block.
> It therefore continues to process the samples that are still in
> buffers, until there are no blocks that could produce any output since
> there is not enough input anymore.
>
> So, in summary:
> 1) yes,
> 2) the downstream blocks are used as long as there is still work to do.
> Which of course will end fastest when they consume all their input items.
>
> > Additional Questions: 1). In general, shouldn't a sink block's
> > work() method always return 0 instead of "noutput_items"? (Sink
> > block doesn't produce any output, isn't the number of output
> > produced is zero?)
> You should define your sink's output IO signature to have an itemsize
> of zero on all zero output streams. Since sinks are usually sync
> blocks, there are as many output as input samples; if the former are
> of size 0, then there are no buffers to shuffle around, though you can
> still tell the runtime that you produced X samples, consuming X.
>
> alternatively, return 0 and call "consume_each(X)" before.
> >
> > 2). In practical cases, under what circumstances we should let the
> > source block's work() method return 0?
> Never, unless you really can't produce nothing. If your block is sync,
> your flowgraph will start to stall.
> > When it returns 0, the sceduler will still continue to call the
> > source block's work() method repeatly.
> That sounds only right to me if downstream blocks don't consume all
> available buffer at once. The flowgraph will usually stop if a block
> consumes 0 input items, since the runtime then assumes the block can't
> process anymore.
> >
> > 3). Under what scenario we will need to use the stop() method ? (In
> > python script we see stop() method quit often, but it seems never
> > needed in c++ code)
> Wrong perspective: In Flowgraph code you often see start() stop()
> since it is used to manage flowgraphs from a higher view.
>
> inside work functions, you should never call stop(). Just say you're
> WORK_DONE, since you can't say anything about the work in progress at
> the rest of the flowgraph. Let the runtime manage shutting down the FG.
>
> If your FG doesn't contain message passing blocks (not even inside
> hier blocks), the python main program will stop when it's done, I'm
> fairly certain. Can you share more about your flowgraph?
>
> Greetings
> Marcus
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1
> Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
>
> iQEcBAEBAgAGBQJS7s8MAAoJEAFxB7BbsDrLDasIAKYsY5a8MWMQxFISgedcKYMw
> g4zmcyJM7Uo449GRCh3XZf7f7tkc8+hZldi2w24ECHmEkpnFDBZZxww1alyBzBpu
> t9TPjrFtNdAaWfZcA7L9C8EGX27BUYrxf62uk04r4gEfBw0x7GPg2qWjr2JqYEJP
> +piqpu+QFLWNi0iZH9v+OR40N1k0de4FQ9TtT2GjQnGsHCS6u0cIhv7pfZPyTDA9
> jyhGTYmF9dIAq1gfo7Gl4BErtczHXPYu6JqEvg6bD+whUUWIuH+GT73ohxQVA0VF
> T8uSh/Awhu1W0OO52ZMrvgBnlmB3j0/Ibe3rYSRlsmra86EROKD2zL3UJY92jLA=
> =oZ7k
> -----END PGP SIGNATURE-----
>
_______________________________________________
Discuss-gnuradio mailing list
Discuss-gnuradio@gnu.org
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio

Reply via email to