Mutex protect L1Encoder::getNextWriteTime. It is called from another thread in GSMCCCH to set the channel start time.

This commit is contained in:
pat
2014-10-14 07:40:58 -07:00
committed by Michael Iedema
parent d1bb8df38c
commit b0737ba490
2 changed files with 19 additions and 4 deletions

View File

@@ -243,6 +243,7 @@ void L1Encoder::rollForward()
// This implements GSM 05.02 Clause 7 for the transmit side. // This implements GSM 05.02 Clause 7 for the transmit side.
mPrevWriteTime = mNextWriteTime; mPrevWriteTime = mNextWriteTime;
mTotalFrames++; mTotalFrames++;
ScopedLock lock(mWriteTimeLock,__FILE__,__LINE__); // (pat) Protects getNextWriteTime.
mNextWriteTime.rollForward(mMapping.frameMapping(mTotalFrames),mMapping.repeatLength()); mNextWriteTime.rollForward(mMapping.frameMapping(mTotalFrames),mMapping.repeatLength());
} }
@@ -316,7 +317,6 @@ const L1Decoder* L1Encoder::sibling() const
return mParent->decoder(); return mParent->decoder();
} }
void L1Encoder::resync(bool force) void L1Encoder::resync(bool force)
{ {
// If the encoder's clock is far from the current BTS clock, // If the encoder's clock is far from the current BTS clock,
@@ -328,11 +328,20 @@ void L1Encoder::resync(bool force)
mNextWriteTime = now; mNextWriteTime = now;
mNextWriteTime.TN(mTN); mNextWriteTime.TN(mTN);
mTotalFrames = 0; // (pat 4-2014) Make sure we start at beginning of mapping. mTotalFrames = 0; // (pat 4-2014) Make sure we start at beginning of mapping.
mNextWriteTime.rollForward(mMapping.frameMapping(mTotalFrames),mMapping.repeatLength()); { ScopedLock lock(mWriteTimeLock,__FILE__,__LINE__); // (pat) Protects getNextWriteTime.
mNextWriteTime.rollForward(mMapping.frameMapping(mTotalFrames),mMapping.repeatLength());
}
OBJLOG(DEBUG) <<"L1Encoder RESYNC "<< " next=" << mNextWriteTime << " now=" << now; OBJLOG(DEBUG) <<"L1Encoder RESYNC "<< " next=" << mNextWriteTime << " now=" << now;
} }
} }
Time L1Encoder::getNextWriteTime()
{
resync();
ScopedLock lock(mWriteTimeLock,__FILE__,__LINE__);
return mNextWriteTime;
}
void L1Encoder::waitToSend() const void L1Encoder::waitToSend() const
{ {
@@ -2279,7 +2288,9 @@ void TCHFACCHL1Encoder::dispatch()
// Most channels do not need this, becuase they are entirely data-driven // Most channels do not need this, becuase they are entirely data-driven
// from above. TCH/FACCH, however, must feed the interleaver on time. // from above. TCH/FACCH, however, must feed the interleaver on time.
if (!encActive()) { if (!encActive()) {
mNextWriteTime += 26; { ScopedLock lock(mWriteTimeLock,__FILE__,__LINE__); // (pat) Protects getNextWriteTime.
mNextWriteTime += 26;
}
gBTS.clock().wait(mNextWriteTime); gBTS.clock().wait(mNextWriteTime);
return; return;
} }

View File

@@ -110,6 +110,7 @@ class L1Encoder {
//@} //@}
/**@name Multithread access control and data shared across threads. */ /**@name Multithread access control and data shared across threads. */
// (pat) It is not being used effectively.
//@{ //@{
mutable Mutex mEncLock; mutable Mutex mEncLock;
//@} //@}
@@ -127,6 +128,9 @@ class L1Encoder {
GSM::Time mPrevWriteTime; ///< timestamp of previous generated burst GSM::Time mPrevWriteTime; ///< timestamp of previous generated burst
GSM::Time mNextWriteTime; ///< timestamp of next generated burst GSM::Time mNextWriteTime; ///< timestamp of next generated burst
// (pat 10-2014) Another thread calls getNextWriteTime so we must protect places that write to mNextWriteTime.
mutable Mutex mWriteTimeLock;
volatile bool mRunning; ///< true while the service loop is running volatile bool mRunning; ///< true while the service loop is running
Bool_z mEncActive; ///< true between open() and close() Bool_z mEncActive; ///< true between open() and close()
Bool_z mEncEverActive; // true if the encoder has ever been active. Bool_z mEncEverActive; // true if the encoder has ever been active.
@@ -210,7 +214,7 @@ class L1Encoder {
const L1FEC* parent() const { return mParent; } const L1FEC* parent() const { return mParent; }
L1FEC* parent() { return mParent; } L1FEC* parent() { return mParent; }
GSM::Time getNextWriteTime() { resync(); return mNextWriteTime; } GSM::Time getNextWriteTime();
protected: protected: