myriadrf / gr-limesdr

gr-limesdr Plugin for GNURadio
Other
142 stars 77 forks source link

Fix memory corruption in dual-channel mode #92

Open jbruno opened 9 months ago

jbruno commented 9 months ago

When running a transmitter and receiver in dual-channel mode on the same radio, there's a synchronization issue that results in memory corruption.

The executive summary of this fix is that it ensures that the init_stream functions on the transmitter and receiver will be completed before any LMS_StartStream functions get called.

From my reading of the LimeSuite code, it appears that the sample packets need to be half the length for 2-channel mode. This logic appears to be handled in the LMS_StartStream function, based on the streams which were initialized, ultimately calling lime::Streamer::ResizeChannelBuffers()

The problem is that if any streams are already started, this resize will not be called again, which makes sense, but the problem is the synchronization in the GNU Radio blocks. The entire routine is enclosed in a static mutex, which also makes sense, but either the transmitter receiver, whichever happens to get its start() called first by the GR scheduler, will run through its entire routine, starting its stream. When this happens, the second start routine will not resize its buffer, because a stream is already running, resulting in memory corruption on FIFO writes.

What I've done here is add another synchronization step, which allows all init_stream functions to be completed before LMS_StartStream gets called, which will allow all FIFO packet sizes to be properly sized.

I'm not in love with the sleep as a synchronization step, because I could see it causing troubles if you have a bunch of radios connected, so I'm open to suggestions, but it's definitely worked fine for me with 2 MIMO-configured radios, as the init_stream function is relatively light.