[mac] simplify tracking of pending operations (#7289)

This commit updates how `Mac` tracks the pending operations by using
a bitset `mPendingOperations` replacing the current model using a
set of `bool` variables per operation.
This commit is contained in:
Abtin Keshavarzian
2022-01-06 12:22:01 -08:00
committed by GitHub
parent a3edc4fcab
commit c5e8c6b634
2 changed files with 42 additions and 114 deletions
+35 -99
View File
@@ -74,18 +74,6 @@ const char Mac::sDomainNameInit[] = "DefaultDomain";
Mac::Mac(Instance &aInstance)
: InstanceLocator(aInstance)
, mEnabled(false)
, mPendingActiveScan(false)
, mPendingEnergyScan(false)
, mPendingTransmitBeacon(false)
, mPendingTransmitDataDirect(false)
#if OPENTHREAD_FTD
, mPendingTransmitDataIndirect(false)
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
, mPendingTransmitDataCsl(false)
#endif
#endif
, mPendingTransmitPoll(false)
, mPendingWaitingForData(false)
, mShouldTxPollBeforeData(false)
, mRxOnWhenIdle(false)
, mPromiscuous(false)
@@ -96,6 +84,7 @@ Mac::Mac(Instance &aInstance)
, mDelayingSleep(false)
#endif
, mOperation(kOperationIdle)
, mPendingOperations(0)
, mBeaconSequence(Random::NonCrypto::GetUint8())
, mDataSequence(Random::NonCrypto::GetUint8())
, mBroadcastTransmitCount(0)
@@ -394,10 +383,10 @@ void Mac::SetRxOnWhenIdle(bool aRxOnWhenIdle)
if (mRxOnWhenIdle)
{
if (mPendingWaitingForData)
if (IsPending(kOperationWaitingForData))
{
mTimer.Stop();
mPendingWaitingForData = false;
ClearPending(kOperationWaitingForData);
}
if (mOperation == kOperationWaitingForData)
@@ -536,7 +525,7 @@ void Mac::SetExtendedPanId(const ExtendedPanId &aExtendedPanId)
void Mac::RequestDirectFrameTransmission(void)
{
VerifyOrExit(IsEnabled());
VerifyOrExit(!mPendingTransmitDataDirect && (mOperation != kOperationTransmitDataDirect));
VerifyOrExit(!IsActiveOrPending(kOperationTransmitDataDirect));
StartOperation(kOperationTransmitDataDirect);
@@ -548,7 +537,7 @@ exit:
void Mac::RequestIndirectFrameTransmission(void)
{
VerifyOrExit(IsEnabled());
VerifyOrExit(!mPendingTransmitDataIndirect && (mOperation != kOperationTransmitDataIndirect));
VerifyOrExit(!IsActiveOrPending(kOperationTransmitDataIndirect));
StartOperation(kOperationTransmitDataIndirect);
@@ -576,13 +565,13 @@ Error Mac::RequestDataPollTransmission(void)
Error error = kErrorNone;
VerifyOrExit(IsEnabled(), error = kErrorInvalidState);
VerifyOrExit(!mPendingTransmitPoll && (mOperation != kOperationTransmitPoll), error = kErrorAlready);
VerifyOrExit(!IsActiveOrPending(kOperationTransmitPoll), error = kErrorAlready);
// We ensure data frame and data poll tx requests are handled in the
// order they are requested. So if we have a pending direct data frame
// tx request, it should be sent before the poll frame.
mShouldTxPollBeforeData = !mPendingTransmitDataDirect;
mShouldTxPollBeforeData = !IsPending(kOperationTransmitDataDirect);
StartOperation(kOperationTransmitPoll);
@@ -614,7 +603,7 @@ void Mac::UpdateIdleMode(void)
#endif
}
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
else if (mPendingTransmitDataCsl)
else if (IsPending(kOperationTransmitDataCsl))
{
mTimer.FireAt(mCslTxFireTime);
}
@@ -642,10 +631,17 @@ exit:
return;
}
bool Mac::IsActiveOrPending(Operation aOperation) const
{
return (mOperation == aOperation) || IsPending(aOperation);
}
void Mac::StartOperation(Operation aOperation)
{
if (aOperation != kOperationIdle)
{
SetPending(aOperation);
otLogDebgMac("Request to start operation \"%s\"", OperationToString(aOperation));
#if OPENTHREAD_CONFIG_MAC_STAY_AWAKE_BETWEEN_FRAGMENTS
@@ -659,48 +655,6 @@ void Mac::StartOperation(Operation aOperation)
#endif
}
switch (aOperation)
{
case kOperationIdle:
break;
case kOperationActiveScan:
mPendingActiveScan = true;
break;
case kOperationEnergyScan:
mPendingEnergyScan = true;
break;
case kOperationTransmitBeacon:
mPendingTransmitBeacon = true;
break;
case kOperationTransmitDataDirect:
mPendingTransmitDataDirect = true;
break;
#if OPENTHREAD_FTD
case kOperationTransmitDataIndirect:
mPendingTransmitDataIndirect = true;
break;
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
case kOperationTransmitDataCsl:
mPendingTransmitDataCsl = true;
break;
#endif
#endif
case kOperationTransmitPoll:
mPendingTransmitPoll = true;
break;
case kOperationWaitingForData:
mPendingWaitingForData = true;
break;
}
if (mOperation == kOperationIdle)
{
mOperationTask.Post();
@@ -718,18 +672,7 @@ void Mac::PerformNextOperation(void)
if (!IsEnabled())
{
mPendingWaitingForData = false;
mPendingActiveScan = false;
mPendingEnergyScan = false;
mPendingTransmitBeacon = false;
mPendingTransmitDataDirect = false;
#if OPENTHREAD_FTD
mPendingTransmitDataIndirect = false;
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
mPendingTransmitDataCsl = false;
#endif
#endif
mPendingTransmitPoll = false;
mPendingOperations = 0;
mTimer.Stop();
#if OPENTHREAD_CONFIG_MAC_STAY_AWAKE_BETWEEN_FRAGMENTS
mDelayingSleep = false;
@@ -741,51 +684,43 @@ void Mac::PerformNextOperation(void)
// `WaitingForData` should be checked before any other pending
// operations since radio should remain in receive mode after
// a data poll ack indicating a pending frame from parent.
if (mPendingWaitingForData)
if (IsPending(kOperationWaitingForData))
{
mPendingWaitingForData = false;
mOperation = kOperationWaitingForData;
mOperation = kOperationWaitingForData;
}
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
else if (mPendingTransmitDataCsl && TimerMilli::GetNow() >= mCslTxFireTime)
else if (IsPending(kOperationTransmitDataCsl) && TimerMilli::GetNow() >= mCslTxFireTime)
{
mPendingTransmitDataCsl = false;
mOperation = kOperationTransmitDataCsl;
mOperation = kOperationTransmitDataCsl;
}
#endif
else if (mPendingActiveScan)
else if (IsPending(kOperationActiveScan))
{
mPendingActiveScan = false;
mOperation = kOperationActiveScan;
mOperation = kOperationActiveScan;
}
else if (mPendingEnergyScan)
else if (IsPending(kOperationEnergyScan))
{
mPendingEnergyScan = false;
mOperation = kOperationEnergyScan;
mOperation = kOperationEnergyScan;
}
else if (mPendingTransmitBeacon)
else if (IsPending(kOperationTransmitBeacon))
{
mPendingTransmitBeacon = false;
mOperation = kOperationTransmitBeacon;
mOperation = kOperationTransmitBeacon;
}
#if OPENTHREAD_FTD
else if (mPendingTransmitDataIndirect)
else if (IsPending(kOperationTransmitDataIndirect))
{
mPendingTransmitDataIndirect = false;
mOperation = kOperationTransmitDataIndirect;
mOperation = kOperationTransmitDataIndirect;
}
#endif // OPENTHREAD_FTD
else if (mPendingTransmitPoll && (!mPendingTransmitDataDirect || mShouldTxPollBeforeData))
else if (IsPending(kOperationTransmitPoll) && (!IsPending(kOperationTransmitDataDirect) || mShouldTxPollBeforeData))
{
mPendingTransmitPoll = false;
mOperation = kOperationTransmitPoll;
mOperation = kOperationTransmitPoll;
}
else if (mPendingTransmitDataDirect)
else if (IsPending(kOperationTransmitDataDirect))
{
mPendingTransmitDataDirect = false;
mOperation = kOperationTransmitDataDirect;
mOperation = kOperationTransmitDataDirect;
if (mPendingTransmitPoll)
if (IsPending(kOperationTransmitPoll))
{
// Ensure that a pending "transmit poll" operation request
// is prioritized over any future "transmit data" requests.
@@ -795,6 +730,7 @@ void Mac::PerformNextOperation(void)
if (mOperation != kOperationIdle)
{
ClearPending(mOperation);
otLogDebgMac("Starting operation \"%s\"", OperationToString(mOperation));
mTimer.Stop(); // Stop the timer before any non-idle operation, have the operation itself be responsible to
// start the timer (if it wants to).
@@ -1603,7 +1539,7 @@ void Mac::HandleTimer(void)
#endif
}
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
else if (mPendingTransmitDataCsl)
else if (IsPending(kOperationTransmitDataCsl))
{
PerformNextOperation();
}
+7 -15
View File
@@ -512,13 +512,13 @@ public:
* This method returns if an active scan is in progress.
*
*/
bool IsActiveScanInProgress(void) const { return (mOperation == kOperationActiveScan) || (mPendingActiveScan); }
bool IsActiveScanInProgress(void) const { return IsActiveOrPending(kOperationActiveScan); }
/**
* This method returns if an energy scan is in progress.
*
*/
bool IsEnergyScanInProgress(void) const { return (mOperation == kOperationEnergyScan) || (mPendingEnergyScan); }
bool IsEnergyScanInProgress(void) const { return IsActiveOrPending(kOperationEnergyScan); }
#if OPENTHREAD_FTD
/**
@@ -826,6 +826,10 @@ private:
#endif
void UpdateIdleMode(void);
bool IsPending(Operation aOperation) const { return mPendingOperations & (1U << aOperation); }
bool IsActiveOrPending(Operation aOperation) const;
void SetPending(Operation aOperation) { mPendingOperations |= (1U << aOperation); }
void ClearPending(Operation aOperation) { mPendingOperations &= ~(1U << aOperation); }
void StartOperation(Operation aOperation);
void FinishOperation(void);
void PerformNextOperation(void);
@@ -871,18 +875,6 @@ private:
static const char sDomainNameInit[];
bool mEnabled : 1;
bool mPendingActiveScan : 1;
bool mPendingEnergyScan : 1;
bool mPendingTransmitBeacon : 1;
bool mPendingTransmitDataDirect : 1;
#if OPENTHREAD_FTD
bool mPendingTransmitDataIndirect : 1;
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
bool mPendingTransmitDataCsl : 1;
#endif
#endif
bool mPendingTransmitPoll : 1;
bool mPendingWaitingForData : 1;
bool mShouldTxPollBeforeData : 1;
bool mRxOnWhenIdle : 1;
bool mPromiscuous : 1;
@@ -892,8 +884,8 @@ private:
bool mShouldDelaySleep : 1;
bool mDelayingSleep : 1;
#endif
Operation mOperation;
uint16_t mPendingOperations;
uint8_t mBeaconSequence;
uint8_t mDataSequence;
uint8_t mBroadcastTransmitCount;