aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Tsou <ttsou@vt.edu>2012-03-17 16:47:01 -0400
committerAlexander Chemeris <Alexander.Chemeris@gmail.com>2013-06-24 01:51:02 +0400
commita6ca73ca67b2a66f46be4bafd5ebf397a3c0a2af (patch)
tree5b54e01e15699b685c993744a677e51d79aa68fc
parent5a37840dfa2a0c02fcb3784afd6969f615b27166 (diff)
multi-arfcn, trx: allocate threads on heap and fix thread release
The underlying pthread of the Thread object isn't created until Thread::start(). If the Thread object is contructed, but not started, then the destructor will fail with a variety of unpredictable errors such as the following or double free() in certain cases. Program received signal SIGSEGV, Segmentation fault. __GI___libc_free (mem=0x3811abed3e946178) at malloc.c:2972 2972 if (chunk_is_mmapped(p)) If the Thread object is stack allocated, but start() isn't called, destructor is guaranteed to run and will fail. The previous approach was to dynamically allocate threads, but not free them, thus avoiding memory errors, but creating memory leaks. To get around this limitation, dynamically allocate Thread objects and initialize with NULL. Then allocate immediately prior to start such that pthread allocation is tied to the Thread object constructor. Deallocation can check that the Thread pointer is valid through NULL or other tracking methods. Signed-off-by: Thomas Tsou <ttsou@vt.edu>
-rw-r--r--Transceiver52M/DriveLoop.cpp7
-rw-r--r--Transceiver52M/Transceiver.cpp18
-rw-r--r--Transceiver52M/radioInterface.cpp17
-rw-r--r--Transceiver52M/radioInterface.h2
4 files changed, 28 insertions, 16 deletions
diff --git a/Transceiver52M/DriveLoop.cpp b/Transceiver52M/DriveLoop.cpp
index c080c12..7e250f8 100644
--- a/Transceiver52M/DriveLoop.cpp
+++ b/Transceiver52M/DriveLoop.cpp
@@ -29,8 +29,7 @@ DriveLoop::DriveLoop(int wSamplesPerSymbol,
GSM::Time wTransmitLatency,
RadioInterface *wRadioInterface)
{
- mRadioDriveLoopThread = new Thread(32768);
-
+ mRadioDriveLoopThread = NULL;
mSamplesPerSymbol = wSamplesPerSymbol;
mRadioInterface = wRadioInterface;
@@ -70,6 +69,9 @@ DriveLoop::DriveLoop(int wSamplesPerSymbol,
DriveLoop::~DriveLoop()
{
+ if (mRadioDriveLoopThread)
+ delete mRadioDriveLoopThread;
+
delete gsmPulse;
sigProcLibDestroy();
}
@@ -77,6 +79,7 @@ DriveLoop::~DriveLoop()
void DriveLoop::start()
{
mOn = true;
+ mRadioDriveLoopThread = new Thread(32768);
mRadioDriveLoopThread->start((void * (*)(void*))RadioDriveLoopAdapter, (void*) this);
}
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp
index 6cfcf32..7b60cd2 100644
--- a/Transceiver52M/Transceiver.cpp
+++ b/Transceiver52M/Transceiver.cpp
@@ -60,10 +60,9 @@ Transceiver::Transceiver(int wBasePort,
mDriveLoop(wDriveLoop), mTransmitPriorityQueue(NULL),
mChannel(wChannel), mTSC(-1)
{
- mFIFOServiceLoopThread = new Thread(32768); ///< thread to push bursts into transmit FIFO
- mControlServiceLoopThread = new Thread(32768); ///< thread to process control messages from GSM core
- mTransmitPriorityQueueServiceLoopThread = new Thread(32768);///< thread to process transmit bursts from GSM core
-
+ mFIFOServiceLoopThread = NULL;
+ mControlServiceLoopThread = NULL;
+ mTransmitPriorityQueueServiceLoopThread = NULL;
mSamplesPerSymbol = wSamplesPerSymbol;
mRadioInterface = wRadioInterface;
@@ -101,6 +100,10 @@ Transceiver::~Transceiver()
{
delete gsmPulse;
mTransmitPriorityQueue->clear();
+
+ delete mFIFOServiceLoopThread;
+ delete mControlServiceLoopThread;
+ delete mTransmitPriorityQueueServiceLoopThread;
}
@@ -304,6 +307,7 @@ void Transceiver::pullFIFO()
void Transceiver::start()
{
+ mControlServiceLoopThread = new Thread(32768);
mControlServiceLoopThread->start((void * (*)(void*))ControlServiceLoopAdapter,(void*) this);
}
@@ -362,11 +366,13 @@ void Transceiver::driveControl()
generateRACHSequence(*gsmPulse,mSamplesPerSymbol);
// Start radio interface threads.
+ mOn = true;
+ mFIFOServiceLoopThread = new Thread(32768);
+ mTransmitPriorityQueueServiceLoopThread = new Thread(32768);
+
mFIFOServiceLoopThread->start((void * (*)(void*))FIFOServiceLoopAdapter,(void*) this);
mTransmitPriorityQueueServiceLoopThread->start((void * (*)(void*))TransmitPriorityQueueServiceLoopAdapter,(void*) this);
writeClockInterface();
-
- mOn = true;
}
}
}
diff --git a/Transceiver52M/radioInterface.cpp b/Transceiver52M/radioInterface.cpp
index c1d43b6..316779f 100644
--- a/Transceiver52M/radioInterface.cpp
+++ b/Transceiver52M/radioInterface.cpp
@@ -75,6 +75,8 @@ RadioInterface::~RadioInterface(void)
mRadio->stop();
close();
+ delete mAlignRadioServiceLoopThread;
+
for (i = 0; i < CHAN_M; i++) {
if (rcvBuffer[i] != NULL)
delete rcvBuffer[i];
@@ -160,17 +162,15 @@ bool RadioInterface::start()
if (mOn)
return false;
- LOG(INFO) << "starting radio interface...";
+ mOn = true;
#ifdef USRP1
- mAlignRadioServiceLoopThread.start((void * (*)(void*))AlignRadioServiceLoopAdapter,
- (void*)this);
+ mAlignRadioServiceLoopThread = new Thread(32768);
+ mAlignRadioServiceLoopThread->start((void * (*)(void*))AlignRadioServiceLoopAdapter,
+ (void*)this);
#endif
writeTimestamp = mRadio->initialWriteTimestamp();
readTimestamp = mRadio->initialReadTimestamp();
mRadio->start();
- LOG(DEBUG) << "Radio started";
- mRadio->updateAlignment(writeTimestamp-10000);
- mRadio->updateAlignment(writeTimestamp-10000);
for (i = 0; i < CHAN_M; i++) {
sendBuffer[i] = new float[8*2*INCHUNK];
@@ -180,7 +180,10 @@ bool RadioInterface::start()
/* Init I/O specific variables if applicable */
init();
- mOn = true;
+ mRadio->start();
+ LOG(DEBUG) << "Radio started";
+ mRadio->updateAlignment(writeTimestamp-10000);
+ mRadio->updateAlignment(writeTimestamp-10000);
return true;
}
diff --git a/Transceiver52M/radioInterface.h b/Transceiver52M/radioInterface.h
index dde1414..99c66b1 100644
--- a/Transceiver52M/radioInterface.h
+++ b/Transceiver52M/radioInterface.h
@@ -36,7 +36,7 @@ class RadioInterface {
protected:
- Thread mAlignRadioServiceLoopThread; ///< thread that synchronizes transmit and receive sections
+ Thread *mAlignRadioServiceLoopThread; ///< thread that synchronizes transmit and receive sections
VectorFIFO mReceiveFIFO[CHAN_M]; ///< FIFO that holds receive bursts