I just pushed up a rebased-version of my custom-buffers branch to my github
(https://github.com/douggeiger/gnuradio/tree/custom-buffers) that I would
like anyone interested in this idea to take a look at.

A couple of notes about where it's at currently, and where I think it needs
to go before it's ready to be integrated into mainline:

 First up: in this branch a block can now indicate via it's io_signature
that it will control it's own output buffers. Technically it can indicate
it wants to control it's own input buffers as well, but at the moment that
will not be respected. Some more on that point later.

 Now, because of the way GNURadio handle's flowgraphs, the memory
allocation for output buffers does *not* take place in the block's
constructor, this is because the connections between blocks is not known at
construction time, and because buffer's are shared: i.e. my_block()'s
output buffers are also the input buffers for any and all blocks that are
connector to by output ports. In particular I'll note that all the buffer
handling code exists withing block_detail, which does not exist until
flat_flowgraph::setup_connections() (which in turn is called by
top_block_impl::start()) or flat_flowgraph::merge_connections() (which is
called by top_block_impl::restart()).

 So - in keeping with the overall design of GNURadio's flowgraph handling
mechanisms, we create a new virtual member function for all blocks: init().
This is a catch-all mechanism for any block to perform any initialization
that can't be done during the block constructor (i.e. anything that needs
to wait until the block_detail is constructed, or really that wants to wait
until the flowgraph connections are known).  Currently this init() function
is called during flat_flowgraph::setup_connections() (i.e. as part of
top_block()->start()) and flat_flowgraph::merge_connections (as earlier:
top_block()->restart()). This call happens shortly after the block_detail
is allocated by flat_flowgraph (coincidentally named
flat_flowgraph::allocate_block_detail()). Inside allocate_block_detail the
new check for the io_signature flag of a block-owned buffer takes place. If
that flag is set, then the call to flat_flowgraph::allocate_buffer() does
not take place, and the allocated buffer does not get passed to the newly
allocated block_detail (via block_detail::set_output()). This means that if
a block is managed it's own buffers, it not only needs to allocate then
(and make sure they comply with the gr::buffer interface), it needs to call
into it's own block_detail and set the output buffers for all of it's
output ports.

 In order to demonstrate how that should be done I have a minimal block
(based off of null_sink) in gr-blocks/lib/qa_gr_block.cc that implements a
custom buffer for it's output port. It shows how the io_signature flags
need to be set, and more importantly in the init() function creates the
buffer (I'm just re-using the make_buffer() function so helpfully provided
by buffer.h - but one can imagine this would call some external memory
allocator - e.g. OpenCL, Android ION, etc. - and wrap it up in a
gr::buffer-derived class), and then provides it to the block_detail via
set_output(). It also does the checking re: buffer size/max_output_buffer
that is done in flat_flowgraph::allocate_block_detail(), but that was
skipped because this block manages it's own output buffers.

 Finally - outstanding items that still need to be handled:

  - As mentioned right now flat_flowgraph is only respecting the
io_signature flags on output ports. Extending these changes to respect
input ports should be (relatively) trivial at this point. However I wanted
to highlight the current functionality as is, with the expectation that
this will be wrapped up somewhat soon. However, the major outstanding
sticking point is:
  - Dealing with connections between blocks that want to manage their own
buffers. Presumably flowgraph designers would never want to do this, but
since it can happen we either need to fail during flowgraph construction
(e.g. through a std::runtime_exception) and give a meaningful message as to
why this isn't allowed, or provide a solution that actually allows for this
to happen (e.g. transparently copy between the buffer's: this obviously has
a performance impact, but we can just blame the flowgraph designer for
doing something sub-optimal here). My expectation at this point is to use
the former solution: i.e. throw an exception and explain this isn't
allowed. Perhaps in the future someone will want something like the later
solution, and can only assume they will be sufficiently motivated to
provide a patch that does exactly that.

 That's about all I have for the time being: as I mentioned - I'd like to
get eyes on this branch now that it is at least passing some minimal QA
checks. I encourage anyone interested in this line of development to take a
look, and more importantly - speak up, I'd like to hear from interested
folks!

 Doug


-- 
Doug Geiger
[email protected]
_______________________________________________
Discuss-gnuradio mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio

Reply via email to