From 9de552757427d5be9e2464f733da1f4c093b2a3a Mon Sep 17 00:00:00 2001 From: Thomas Tsou Date: Mon, 21 Mar 2011 11:06:05 -0400 Subject: [PATCH] uhd: enable priority scheduling on receive loop Though the receive loop ultimately drives the GSM clock, it does not have any priority because it runs as a separate thread from the trasmit loop. The transmit has priority because it starts the UHD device, where priority scheduling is enabled. The result is frequent underruns, which occur regardless of buffer size tuning. To address this, break out and expose the priority setting so that it can be called from the radioInterface at the start of a new thread. Tested on a modest Intel Core 2 Duo tablet running Linux 2.6.33.7.2-rt30, this reduced underruns down to near zero. Signed-off-by: Thomas Tsou --- public-trunk/Transceiver/Device.h | 1 + public-trunk/Transceiver/UHDDevice.cpp | 10 ++++++++-- public-trunk/Transceiver/USRPDevice.h | 3 +++ public-trunk/Transceiver/radioInterface.cpp | 7 +++++++ public-trunk/Transceiver/radioInterface.h | 3 +++ 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/public-trunk/Transceiver/Device.h b/public-trunk/Transceiver/Device.h index 5a47bb0..6e22378 100644 --- a/public-trunk/Transceiver/Device.h +++ b/public-trunk/Transceiver/Device.h @@ -39,6 +39,7 @@ public: virtual bool open() = 0; virtual bool start() = 0; virtual bool stop() = 0; + virtual void setPriority() = 0; /** Read samples from the USRP. @param buf preallocated buf to contain read result diff --git a/public-trunk/Transceiver/UHDDevice.cpp b/public-trunk/Transceiver/UHDDevice.cpp index 998a02f..9ac3af5 100644 --- a/public-trunk/Transceiver/UHDDevice.cpp +++ b/public-trunk/Transceiver/UHDDevice.cpp @@ -135,6 +135,7 @@ public: bool open(); bool start(); bool stop(); + void setPriority(); int readSamples(short *buf, int len, bool *overrun, TIMESTAMP timestamp, bool *underrun, unsigned *RSSI); @@ -286,8 +287,7 @@ bool UHDDevice::start() return false; } - // Enable priority scheduling - uhd::set_thread_priority_safe(); + setPriority(); // Start asynchronous event (underrun check) loop asyncEventServiceLoopThread.start( @@ -322,6 +322,12 @@ bool UHDDevice::stop() } +void UHDDevice::setPriority() +{ + uhd::set_thread_priority_safe(); + return; +} + int UHDDevice::readSamples(short *buf, int len, bool *overrun, TIMESTAMP timestamp, bool *underrun, unsigned *RSSI) { diff --git a/public-trunk/Transceiver/USRPDevice.h b/public-trunk/Transceiver/USRPDevice.h index e53eced..aa4e6da 100644 --- a/public-trunk/Transceiver/USRPDevice.h +++ b/public-trunk/Transceiver/USRPDevice.h @@ -185,6 +185,9 @@ private: /** Stop the USRP */ bool stop(); + /** Set priority not supported */ + void setPriority() { return; } + /** Read samples from the USRP. @param buf preallocated buf to contain read result diff --git a/public-trunk/Transceiver/radioInterface.cpp b/public-trunk/Transceiver/radioInterface.cpp index 796bd4e..021df31 100644 --- a/public-trunk/Transceiver/radioInterface.cpp +++ b/public-trunk/Transceiver/radioInterface.cpp @@ -276,6 +276,11 @@ bool RadioInterface::tuneRx(double freq) return usrp->setRxFreq(freq); } +void RadioInterface::setPriority() +{ + usrp->setPriority(); + return; +} void RadioInterface::start() { @@ -305,6 +310,8 @@ void *TransmitRadioServiceLoopAdapter(RadioInterface *radioInterface) void *ReceiveRadioServiceLoopAdapter(RadioInterface *radioInterface) { + radioInterface->setPriority(); + while (1) { radioInterface->driveReceiveRadio(); pthread_testcancel(); diff --git a/public-trunk/Transceiver/radioInterface.h b/public-trunk/Transceiver/radioInterface.h index 3c272ba..ad9687b 100644 --- a/public-trunk/Transceiver/radioInterface.h +++ b/public-trunk/Transceiver/radioInterface.h @@ -189,6 +189,9 @@ public: /** set receive frequency */ bool tuneRx(double freq); + /** set thread priority */ + void setPriority(); + protected: /** drive transmission of GSM bursts */