On Fri, Jun 28, 2013 at 6:48 AM, Bastian B.
<[email protected]
wrote:
so it is the intended behavior that the work function is called all over
the time (and immediately returns)? I just checked for the pdu to tagged
stream block and its called ~500k times per second.
This is a known issue specific to the design of streaming source blocks
that depend on async message input port(s) for their content. It will
be
addressed after the 3.7.0 release. Basically, we need to provide a
mechanism to allow a block to tell the scheduler to add reception of an
async port message as one of the conditions to be satisfied before
calling
work().
In general on this issue, the desired block design is to handle all
incoming async message port traffic using registered message handlers.
The
message handler(s) can then optionally generate futher outgoing async
messages on output message ports and/or set block internal state as
needed. Once the scheduler has dispatched all pending async messages to
the block’s message handlers, if the block has a work() function,
conditions will be evaluated whether to call it. If called, the work
function can then deal with streaming port I/O and any state updates
created by the prior message handler execution.
Since the GNU Radio scheduler is actually distributed among all the
blocks/threads, each block has its own scheduler that wakes up when
events
occur, evaluates whether to call block message handlers and work()
function, sends notifications to other blocks based on the return from
work(), and goes back to sleep waiting for another event to occur.
Blocking in either a message handler or in the work() function is very
strongly discouraged, as this prevents the scheduler for that block from
running and may result in deadlocks.
In some cases, usually in source blocks, making blocking system calls is
unavoidable, and we “get away” with doing so by using a timeout with a
small value and returning. This is suboptimal for CPU usage but does
allow
the scheduler machinery to run. (The pdu_to_tagged_stream block cannot
even
do this right now.)
Longer term, the plan is to add scheduler provided functions to call so
block work() functions can ask the scheduler to “call me again when this
happens” and the scheduler can handle the blocking/response in a way the
gets along with everything else.
TL;DR We’re working on it