diff options
author | Thomas Tsou <ttsou@vt.edu> | 2012-03-17 16:47:01 -0400 |
---|---|---|
committer | Alexander Chemeris <Alexander.Chemeris@gmail.com> | 2013-06-24 01:51:02 +0400 |
commit | a6ca73ca67b2a66f46be4bafd5ebf397a3c0a2af (patch) | |
tree | 5b54e01e15699b685c993744a677e51d79aa68fc | |
parent | 5a37840dfa2a0c02fcb3784afd6969f615b27166 (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.cpp | 7 | ||||
-rw-r--r-- | Transceiver52M/Transceiver.cpp | 18 | ||||
-rw-r--r-- | Transceiver52M/radioInterface.cpp | 17 | ||||
-rw-r--r-- | Transceiver52M/radioInterface.h | 2 |
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 |