|Subject:||[Discuss-gnuradio] Flow Graph Flow Control (was: Re: Code Reuse Question)|
|Date:||Thu, 12 May 2016 23:53:22 +0200|
|User-agent:||Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.6.0|
blocks can't side effect each other except through really strictly controlled, well-defined ways... and that was still very clear and dominant to the user under GR 3.4, I agree – then we "softened" that concept by adding stream tags, message passing, and if you look at things like the ofdm_rx.grc, you'll notice that there's extensive use of shared state through using the same equalizer object for payload and header and so on.
So, there's two conflicting opinions I have about that
* it's obviously a good thing we have all those mechanisms. An SDR framework without any chance to communicate in-band side information (tags) or asynchronous commands / info (msgs) is bound to be hell to use. Same goes for shared equalizer, coder, constellation objects. It's absolutely necessary, and it's of great use without being too confusing. Not that documentation couldn't be better… but that's kinda my fault by now, I think.
* The whole python variables/callback/GRC-generated code thing is great for ad-hoc GUI things, but it has led to numerous cases of people being in confusion on how to make blocks "talk" to each other. It's unclean, and maybe we should look into how we can reduce usage of that in favour of replacing it either by explicit application of e.g. message passing, or implicit RPC (which we'd still have to come up with a consistent method for).
This includes not being able to modify their upstream block's output buffer, as potentially many other blocks are also reading that upstream output buffer. (There are no "input buffers" in GNU Radio, only input ports that maintain a read point to upstream-owned memory.)Totally agreeing with you on that "don't mess with someone else's output buffer" contract – I should have been more careful with my words here.
OK. Time for lucid dreaming:
Src +--> Head ---> Sink0 \------------> Sink1
In essence, the idea would be to have the src output buffer acting as head's output buffer, but with another (non-writing, just write pointer handling) buffer writer attached to it (and Sink0's read pointers using that one), making sure that downstream read pointers can't pass limits that the head block defines. That would naturally be something like min(src_write_pointer, head_pseudo_write_pointer). Alongside with that would actually go something like the same flow/execution control influence (because we can basically emulate something like that half-way by having a "limiting" reader attached to the upstream block, so that that block's write pointer can't advance even if the sink1's read pointer indicates sink1 has consumed what src produced) a "proper" block has.
From a behavioral point of view, this would be like having the read pointer of sink0 directly attached to src's output buffer. Now, the trick is that for "normal" connections, the limit of how far that read pointer can advance is given by the position of src's write pointer. Now, if head had its own pseudo-write pointer that might sit somewhere behind (up to) src's write pointer, consider how nicely we could implement all non-modifying operations that up to now would need a copy – peak taggers, the infamously misunderstood throttle block (which we suddenly could really rewrite to let samples through at a fixed rate – simply advancing the the pseudo-write pointer every hundred µs by one, for example), event counters, channel estimators.
Hm. Maybe after Grcon; thinking about this, this doesn't need any special buffer handling.
On 12.05.2016 22:32, Johnathan Corgan wrote:
|[Prev in Thread]||Current Thread||[Next in Thread]|