Critical sections between datareader operations

2 posts / 0 new
Last post
Last seen: 1 year 8 months ago
Joined: 01/27/2014
Posts: 22
Critical sections between datareader operations


We got a datareader receiving every 100 milliseconds (it's a mean value) batches of 100 samples each of the samples are 60 bytes in size. The datareader max_samples is 1000.

A thread takes samples into the datareader 100 by 100, using loaning function.

We observe that most of the time the "take" operation takes less than 200 microsecond but sometime (rarely) the "take" operation can takes as much as 3-6 milliseconds to return the loaned buffer.

We also observe that this sporadic effect can be reduced by reducing the size of the batch (ex: 10 samples by batch)

Is there a critical section between the "take" operation using the loaning option (which take samples in the receive queue) and the "reception" processus of a datareader (which put samples in the receive queue) ?

If yes, is there ways to reduce the effect of this critical section ?

Thank you in advance.

Last seen: 5 years 4 months ago
Joined: 01/31/2011
Posts: 37


To answer your question - there is a critical section (in our documentation, it's called an ExclusiveArea) that protects access to the internals of the DataReader, including its data queue.  Any operation that could modify the state of the DataReader is protected by a mutex.  This includes operations like take/read, return_loan, and the arrival of new data.  Only one thread can be in this ExclusiveArea at a time.

Are you using a waitset or a listener to "take" data from the DataReader's queue?  If you are using a listener, then you are already in the critical section of the DataReader while within the on_data_available() callback.  The listener is called from the context of the RTI receive thread, which is responsible for putting new data into the reader's queue.  If you are using a waitset and accessing the data from your own thread, then your thread is competing with the RTI receive thread when you return the loan.  Your thread will block if trying to return the loan while the receive thread is in the ExclusiveArea of the DataReader.

There is no straightforward mechanism to reduce the effect of this critical section if you are using a waitset.  For example, if you are using a deterministic scheduler you can make sure your data processing thread has a higher priority than the RTI receive thread, so that the RTI receive thread is not scheduled until your processing thread has yielded the CPU.  However, in practice, this has to be carefully implemented as you could also starve the RTI receive thread if not given a chance to run.

Another option would be to copy rather than loan, so that your data processing thread no longer has any conflicts with the RTI receive threads.

One other thing to be aware of - the ExclusiveArea is not associated with the DataReader, but rather the DDS::Subscriber.  That is, each DataReader created from the DDS::Subscriber will share the same ExclusiveArea.  One way to provide more concurrency is to make sure each DataReader is created from a separate DDS::Subscriber, since this would create a separate ExclusiveArea for each DataReader.