How is processor time given to blocks?

I am fairly new to gnuradio and am working on some of my own blocks. I
am
trying to understand how the blocks are given control of the cpu. I am
using
the grc interface. I currently think that each block runs till it is
done
then gives control to the next block, then when all blocks have run the
process starts over. However I set some flags that have caused me to
question that understanding. A better explanation of how the system
works
would be much appreciated.

Thanks, Sean

On Wed, Jul 21, 2010 at 10:15:29AM -0700, Sean Jordan wrote:

I am fairly new to gnuradio and am working on some of my own blocks. I am
trying to understand how the blocks are given control of the cpu. I am using
the grc interface. I currently think that each block runs till it is done
then gives control to the next block, then when all blocks have run the
process starts over. However I set some flags that have caused me to
question that understanding. A better explanation of how the system works
would be much appreciated.

Thanks, Sean

This is somewhat simplified, but reasonably close:

With the thread-per-block scheduler, blocks are “available to
run” whenever there is input available on its inputs and output
space available in the downstream buffer.

When the block actually runs is dependent on the underlying OS
scheduler. In user space, everything is controlled with condition
variables and their associated mutexes. With the thread-per-block
scheduler there is almost always more than 1 block running
simultaneously.

Eric

On Wed, Jul 21, 2010 at 10:37 AM, Eric B. [email protected] wrote:

Thanks, Sean

This is somewhat simplified, but reasonably close:

With the thread-per-block scheduler, blocks are “available to
run” whenever there is input available on its inputs and output
space available in the downstream buffer.

When the block actually runs is dependent on the underlying OS
scheduler. In user space, everything is controlled with condition
variables and their associated mutexes. With the thread-per-block
scheduler there is almost always more than 1 block running
simultaneously.

Eric

Thanks, with this in mind, I need in my application for only one block
to be
running at a time. Is there any way for that to be specified?

Sean

On Wed, Jul 21, 2010 at 10:43:52AM -0700, Sean Jordan wrote:

would be much appreciated.
scheduler. In user space, everything is controlled with condition
variables and their associated mutexes. With the thread-per-block
scheduler there is almost always more than 1 block running
simultaneously.

Eric

Thanks, with this in mind, I need in my application for only one block to be
running at a time. Is there any way for that to be specified?

No.

Why would you want only a single block running at a time?
Needless to say, you want to avoid shared state.

Eric

Eric

For running only at one time- My first block picks out “chunks” of data
and
passes these on to the next blocks. These “chucks” only come along once
in a
while. The blocks after only need to run when these “chucks” are found.
I am
passing a flag (1 or 0) at the beginning of the output to tell the next
block whether or not to run. Once a “chunk” is found, each block must
process the data after the previous block in order. Multiple blocks
running
at the same time seems to mess with my flags, causing my end data to be
incorrect. Perhaps there is a better way to to this than Run/Don’t run
flags.

-Sean

at the same time seems to mess with my flags, causing my end data to be
instead of “work”.

Your downstream block will only run when it has input available, which
will only occur when your first block generates output. No flag is
required.

Blocks are conceptually connected by single-writer multiple-reader FIFOs.

Eric

Thanks. That helped a lot, however the code seems to be looping in one
of
the secondary blocks before proceeding to the next blocks or going back
to
the first block. I cannot figure out what is causing this. I think it
may
have to do with ninput_items or noutput_items but am not sure. From what
I
can tell, ninput_items should be the number returned by general_work in
the
previous block, however how does one use that number when it is a vector
and
what is its purpose?

Sean

On Wed, Jul 21, 2010 at 12:58:25PM -0700, Sean Jordan wrote:

Eric
flags.

-Sean

You can easily do what you described without trying to “damage the
scheduler” :slight_smile:

Your first block should only produce output when it “feels like it”.
To do this, it should derive from gr_block and implement “general_work”
instead of “work”.

At the end of your general_work method, call consume or consume_each
to tell the scheduler how much input you consumed. Your return value
from general_work is the number of output items that you produced.

Please see
http://www.gnu.org/software/gnuradio/doc/howto-write-a-block.html

It’s a bit out of date with regard to the build system, but is accurate
for what you are trying to do. See the howto_square_ff example.

Your downstream block will only run when it has input available, which
will only occur when your first block generates output. No flag is
required.

Blocks are conceptually connected by single-writer multiple-reader
FIFOs.

Eric

On Wed, Jul 21, 2010 at 04:00:58PM -0700, Sean Jordan wrote:

http://www.gnu.org/software/gnuradio/doc/howto-write-a-block.html
Eric

Thanks. That helped a lot, however the code seems to be looping in one of
the secondary blocks before proceeding to the next blocks or going back to
the first block. I cannot figure out what is causing this.

Write a piece of QA code to test your block with known inputs and
expected outputs. There are tons of examples in
gnuradio-core/src/python/gnuradio/gr/qa_*.py

I think it may
have to do with ninput_items or noutput_items but am not sure. From what I
can tell, ninput_items should be the number returned by general_work in the
previous block,

however how does one use that number when it is a vector and what is its purpose?

ninput_items tells you many items are available on each of your input
streams. ninput_items[0] is the number of items of input available on
input stream 0…

You may not need to look at it depending on your needs. Unless you
override “forecast”, the default version will tell the scheduler that
you need 1 input for each output item to be produced.

The relationship between forecast and general_work is explained in the
howto-write-a-block doc mentioned above.

You should treat each block as a black box, unrelated to the blocks
upstream or downstream from it. If you’re thinking that they are
related, or are trying to second guess the scheduler wrt noutput_items
or the amount of input available when your general_work function is
called, you’re headed for trouble.

Eric

You should treat each block as a black box, unrelated to the blocks
upstream or downstream from it. If you’re thinking that they are
related, or are trying to second guess the scheduler wrt noutput_items
or the amount of input available when your general_work function is
called, you’re headed for trouble.

Eric

That clarifies things. Thanks for explaining that.

Sean