[USRP-users] Timeout while streaming error while implementing receiving samples in different thread

Marcus Müller marcus.mueller at ettus.com
Wed Apr 29 03:48:34 EDT 2015


Hi Kamal Kumar Jeldi,

that's a pretty good architecture, having a receiver thread and consumer
threads!

it's really hard to tell you why timeouts occur without knowing the
whole application, but I think I can make some educated guesses.
By the way: I don't know `std::concurrent_queue`, is it possibly a
`tbb::concurrent_queue`?

Then: "Timeout while streaming." is not a UHD error message. It appears
in two examples, but it doesn't come from the UHD library -- so it's
part of your code! pretty hard to know why you print that.

To explain when the rx_samples_to_file example prints that message:
you can specify a timeout for recv(), which means that recv only waits
for the specified time for samples coming from the USRP; this can fail
in three cases:

1. when your USRP isn't streaming samples yet (for example, you used a
time spec in your stream_cmd that you use to tell the USRP to start
streaming, or you forget to issue that stream_cmd at all). I'd say this
is the most probable reason, but I don't know the part of the
application where you set things up.
2. when, for some reason, your operating system is busy doing other
stuff, and UHD just sits there and waits for the data packet (in your
case, USB packet) for longer than the timeout. Typically, this shouldn't
happen, because the next thing you get is a "O", meaning that your USRP
had to drop a sample packet, because it was not received before the next
packet was there ("O"verflow).
3. Your timeout is shorter than (samples_per_buffer/sampling_rate +
latency), which means there's no way for the USRP to give you that
buffer in time.

Since your timeout is 3.0, we can rule out 3. So my recommendation here
is trying to find out at which point you specify that you want to start
streaming (look for `issue_stream_cmd`), and have a look at that. Maybe
just `this_thread::sleep(10)` in your receiver thread before you
`recv()` -- if you don't get "O"s, then you haven't successfully told
the USRP to start streaming samples at all!

So another thing that struck me is that you're allocating a buffer every
time you want to receive -- don't do that!
Allocating memory is rather complex, and might involve (in your case,
pretty quickly involves) asking your operating system to map new memory
pages into your process' memory -- first of all, that will take some
time, because your operating system has to go through a table, and look
for free memory pages, add them to another table, and map them to your
memory linearly, and then give you the pointer.
But more importantly: this might easily fail, for example if you forget
to `delete` the vectors in your sample-consuming thread.
I'd recommend having two queues: One for "unused" buffers, which you, at
the start of your program, fill with 5 or so, and the one you already
have. I your receiver thread, you pop one of the unused buffers to
`recv()` into, and push that onto your DataQueue. In your receiver
thread, you get elements from DataQueue, process the samples within, and
push the processed buffer back onto the "unused" queue.

It's worth noting that having read through the documentation page of
tbb::concurrent_queue[1], there's no blocking pop() call, which means
you might need a side-channel (like, another condition) to notify the
consumer thread that there are samples to be processed. I'm pretty sure
you've omitted notifying the processing thread(s) for the sake of
readability.

Best regards,
Marcus

[1]
https://www.threadingbuildingblocks.org/docs/help/reference/containers_overview/concurrent_queue_cls.htm
On 04/29/2015 08:33 AM, kamal kumar jeldi via USRP-users wrote:
> /P.S: This question might be more of related to C++ programming. But
> the methodology works fine on normal compilation but does not work
> after integrating with UHD./
>
> Hi All,
>
> I am using B210 USRP Board. I am trying to implement two threads ( one
> for recieving samples and another for processing received samples from
> other thread ) using concurrent_queue which stores pointers to
> std::vector< std::complex<T> >. Here is the declaration:
>
> std::concurrent_queue< std::vector< std::complex<T> > * > DataQueue;
>
> concurrent_queue is implemented thread safe using mutex and
> conditional variables
>
> The recieving thread( one of two threads) receives samples issues
> /recv /command and receives the samples. So, in order to insert a
> pointer to new received data, I need a new reference to each samples
> data for each iteration hence I came up with this semantics,
>
> while(till_condition_satisfies)
> {
>      std::vector < std::complex<T> > *buff = new std::vector<
> std::complex<T> >( samples_per_buffer);
>      std::vector< std::complex<T> > &r = *buff   //just de-referencing
> the pointer
>      size_t num_rx_samps = rx_stream->recv(&r.front(),rx_samps_num,
> md, 3.0, enable_size_map);
>     
>       DataQueue.push(buff);
>
>       //error checking code goes here
> }
>
> The processing thread, just locks this globally defined DataQueue and
> pops one pointer and unlocks the queue. Processing part on this popped
> pointer.
>
> In the main thread, I am starting the thread using std::thread library
> from C++11 standards as,
>
> #define DataAcquisition_args() \
>     usrp, format, wirefmt, spb, total_num_samps, extra_samples,
> total_time, bw_summary, stats, null, enable_size_map,
> continue_on_bad_packet
>
> std::thread
> DataAcquisitionThread(DataAcquisition_func<double>,DataAcquisition_args());
>
> I have compiled the code with necessary libraries and compiler
> switches. The code compiles perfectly to produce the executable. but
> when the program is executed, It shows the following error,
> *
> Timeout while streaming*.
>
> Am I making anything wrong while sending parameters to
> DataAcquistionThread...??? Where am i going wrong..??
>
>
> Please help me.. Thanks in advance...
>  
>
>
> _______________________________________________
> USRP-users mailing list
> USRP-users at lists.ettus.com
> http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ettus.com/pipermail/usrp-users_lists.ettus.com/attachments/20150429/7bfbd68a/attachment-0002.html>


More information about the USRP-users mailing list