mirror of
https://github.com/RangeNetworks/openbts.git
synced 2025-10-23 07:42:01 +00:00
Mutex protect L1Encoder::getNextWriteTime. It is called from another thread in GSMCCCH to set the channel start time.
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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:
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user