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

Ian Buckley ianb at ionconcepts.com
Wed Apr 29 12:33:43 EDT 2015


Exactly. There will be some granularity to TX space becoming available depending on the USRP type, packet size and transport, but basically we try to keep that buffer full when free running.
It would be enlightening if perhaps the while loop ran a finite number of times, you should then see the reverse effect at the end as TX and RX drain out.
-Ian

On Apr 29, 2015, at 9:25 AM, Chris Evans <chris.evans at azuresummit.com> wrote:

> 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/496160de/attachment-0002.html>


More information about the USRP-users mailing list