[USRP-users] Blocking behavior of send() and recv() and keeping timing

Chris Evans chris.evans at azuresummit.com
Wed Apr 29 12:25:15 EDT 2015


Thanks Ian,

So if I understand this correctly, the transmit buffer FIFO fills up much
faster than the common sample rate, then there is back pressure which
causes send() to block for a good long time until the FIFO has drained to
some threshold or empty, then it cycles again. All the while, the
iterations through the receive loop's while() is happening in a roughly
steady fashion because it is dictated by when the receive FIFO fills up
(predictable rate).

There was a mistake in the previous code (tx rate and rx rate were not the
same) which caused there to be fewer RX loop printouts. The output is now...
TX loop incrementing counter to: 38
RX loop sees: 39
TX loop incrementing counter to: 39
RX loop sees: 40
TX loop incrementing counter to: 40
TX loop incrementing counter to: 41
RX loop sees: 42
TX loop incrementing counter to: 42
RX loop sees: 43
TX loop incrementing counter to: 43
RX loop sees: 44
TX loop incrementing counter to: 44
RX loop sees: 45
TX loop incrementing counter to: 45
RX loop sees: 46
TX loop incrementing counter to: 46
RX loop sees: 47
TX loop incrementing counter to: 47
RX loop sees: 48
TX loop incrementing counter to: 48
TX loop incrementing counter to: 49
RX loop sees: 50
RX loop sees: 50
TX loop incrementing counter to: 50
RX loop sees: 51
TX loop incrementing counter to: 51
RX loop sees: 52
TX loop incrementing counter to: 52
RX loop sees: 53
TX loop incrementing counter to: 53
RX loop sees: 54
TX loop incrementing counter to: 54
RX loop sees: 55
TX loop incrementing counter to: 55
RX loop sees: 56
TX loop incrementing counter to: 56
TX loop incrementing counter to: 57
RX loop sees: 58
TX loop incrementing counter to: 58
RX loop sees: 59
TX loop incrementing counter to: 59
RX loop sees: 60
RX loop sees: 60
TX loop incrementing counter to: 60
RX loop sees: 61
TX loop incrementing counter to: 61
TX loop incrementing counter to: 62
RX loop sees: 63
RX loop sees: 63
TX loop incrementing counter to: 63
TX loop incrementing counter to: 64
RX loop sees: 65
TX loop incrementing counter to: 65
RX loop sees: 66

You can now see that for the most part each thread alternates, but there
are times when two RX loops happen before a TX loop comes around again (and
vice versa). I will try using a semaphore to synchronize the threads
further. Thanks again.

On Wed, Apr 29, 2015 at 12:00 PM, Ian Buckley <ianb at ionconcepts.com> wrote:

> Chris,
> Here's what is approximately whats happening I think:
> On the TX thread a command to start immediate transmission is sent, and
> close behind it UHD begins to send the transmit sample data as fast as the
> available CPU allows until the local transmit buffer FIFO in the USRP
> fills. From this point on back-pressure from the B210 cause the flow rate
> to be moderated and approximate the configured sample rate for transmission.
> On the RX thread, the command to receive immediately is received quickly
> but then data needs to accumulate in the local USRP buffers until it is
> enough data to form the configured packet size, at which point it starts to
> flow towards the host immediately at the configured sample rate.
> There are also real world latencies in both paths that contribute to the
> effect.
>
> -Ian
>
> On Apr 29, 2015, at 8:29 AM, Chris Evans via USRP-users <
> usrp-users at lists.ettus.com> wrote:
>
> > All,
> >
> > I am streaming data on a USRP B210. One channel TX, one channel RX --
> each running in their own threads. Something like this:
> >
> > void runTXLoop(uhd::tx_streamer::sptr tx_stream, uhd::tx_metadata_t
> tx_md, uint64_t& sharedCounter)
> > {
> >     while (1) {
> >
> >         // Signal processing and filling tx_buff
> >
> >         tx_stream->send(tx_buff, 2000, tx_md);
> >         tx_md.start_of_burst = false;
> >         tx_md.has_time_spec = false;
> >
> >         std::cout << "TX loop incrementing counter to: " <<
> sharedCounter++ << std::endl;
> >     }
> > }
> >
> > void runRXLoop(uhd::rx_streamer::sptr rx_stream, uhd::rx_metadata_t
> rx_md, uint64_t& sharedCounter)
> > {
> >     while (1) {
> >
> >         rx_stream->recv(rx_buff, 2000, rx_md);
> >
> >         // Signal processing on contents of rx_buff
> >
> >         std::cout << "RX loop sees: " << sharedCounter << std::endl;
> >     }
> > }
> >
> >
> > Becuase transmit and receive are working with the same number of samples
> per buffer and because the streams are running at the same sample rate, I
> would expect for each loop through runTXLoop's while(), there would be
> exactly one loop through runRXLoop's while(). Instead, I see an output
> along the lines of...
> >
> > TX loop incrementing counter to: 0
> > TX loop incrementing counter to: 1
> > TX loop incrementing counter to: 2
> >
> > ...
> >
> > TX loop incrementing counter to: 32
> > TX loop incrementing counter to: 33
> > RX loop sees: 34
> > TX loop incrementing counter to: 34
> > RX loop sees: 35
> > TX loop incrementing counter to: 35
> > RX loop sees: 36
> > TX loop incrementing counter to: 36
> > RX loop sees: 37
> > TX loop incrementing counter to: 37
> > RX loop sees: 38
> > TX loop incrementing counter to: 38
> > RX loop sees: 39
> > TX loop incrementing counter to: 39
> > RX loop sees: 40
> > TX loop incrementing counter to: 40
> > TX loop incrementing counter to: 41
> > TX loop incrementing counter to: 42
> > TX loop incrementing counter to: 43
> > TX loop incrementing counter to: 44
> > TX loop incrementing counter to: 45
> > TX loop incrementing counter to: 46
> > TX loop incrementing counter to: 47
> > TX loop incrementing counter to: 48
> > TX loop incrementing counter to: 49
> > RX loop sees: 50
> > TX loop incrementing counter to: 50
> > TX loop incrementing counter to: 51
> >
> > ...
> >
> > TX loop incrementing counter to: 71
> > TX loop incrementing counter to: 72
> > RX loop sees: 73
> > TX loop incrementing counter to: 73
> >
> > In other words, the TX loop appears to start before the RX loop up until
> sharedCounter is 33, then the expected behavior of alternating print outs,
> and then an unexpected behavior of many tx loops per rx loop.
> >
> > Is it reasonable to use the blocking behavior of send() and recv() to
> keep a shared notion of timing between the two threads?
> >
> > Thanks
> >
> > --
> > Chris Evans
> > Systems Engineer
> > Azure Summit Technology, Inc.
> > 3050 Chain Bridge Road, Suite 600
> > Fairfax, VA 22030
> > 919-428-6243 (cell)
> > _______________________________________________
> > USRP-users mailing list
> > USRP-users at lists.ettus.com
> > http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com
>
>


-- 
Chris Evans
Systems Engineer
Azure Summit Technology, Inc.
3050 Chain Bridge Road, Suite 600
Fairfax, VA 22030
919-428-6243 (cell)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ettus.com/pipermail/usrp-users_lists.ettus.com/attachments/20150429/4644b203/attachment-0002.html>


More information about the USRP-users mailing list