WiFi: Make WifiHandler::_CopyFromRXQueue() more efficient by doing less copying and less locking.

This commit is contained in:
rogerman 2018-11-17 19:50:45 -08:00
parent 91526e6324
commit be8d08ae87
2 changed files with 25 additions and 25 deletions

View File

@ -3770,6 +3770,7 @@ WifiHandler::WifiHandler()
_mutexRXPacketQueue = slock_new(); _mutexRXPacketQueue = slock_new();
_rxPacketQueue.clear(); _rxPacketQueue.clear();
_rxCurrentQueuedPacketPosition = 0; _rxCurrentQueuedPacketPosition = 0;
memset(&_rxCurrentPacket, 0, sizeof(RXQueuedPacket));
_softAPStatus = APStatus_Disconnected; _softAPStatus = APStatus_Disconnected;
_softAPSequenceNumber = 0; _softAPSequenceNumber = 0;
@ -3790,13 +3791,13 @@ WifiHandler::WifiHandler()
WifiHandler::~WifiHandler() WifiHandler::~WifiHandler()
{ {
slock_free(this->_mutexRXPacketQueue);
free(this->_workingTXBuffer); free(this->_workingTXBuffer);
this->_workingTXBuffer = NULL; this->_workingTXBuffer = NULL;
delete this->_adhocCommInterface; delete this->_adhocCommInterface;
delete this->_softAPCommInterface; delete this->_softAPCommInterface;
slock_free(this->_mutexRXPacketQueue);
} }
void WifiHandler::_RXEmptyQueue() void WifiHandler::_RXEmptyQueue()
@ -4823,36 +4824,38 @@ void WifiHandler::_CopyFromRXQueue()
{ {
WIFI_IOREG_MAP &io = this->_wifi.io; WIFI_IOREG_MAP &io = this->_wifi.io;
// Retrieve a packet from the RX packet queue if we're not already working on one.
if (this->_rxCurrentQueuedPacketPosition == 0)
{
slock_lock(this->_mutexRXPacketQueue); slock_lock(this->_mutexRXPacketQueue);
if (this->_rxPacketQueue.empty()) if (this->_rxPacketQueue.empty())
{ {
// However, if the queue is empty, then there is no packet to retrieve.
slock_unlock(this->_mutexRXPacketQueue); slock_unlock(this->_mutexRXPacketQueue);
return; return;
} }
RXQueuedPacket &currentRXPacket = this->_rxPacketQueue.front(); this->_rxCurrentPacket = this->_rxPacketQueue.front();
currentRXPacket.latencyCount++; this->_rxPacketQueue.pop_front();
const RXQueuedPacket newRXPacket = currentRXPacket;
slock_unlock(this->_mutexRXPacketQueue); slock_unlock(this->_mutexRXPacketQueue);
const size_t totalPacketLength = (sizeof(RXPacketHeader) + newRXPacket.rxHeader.length > sizeof(RXQueuedPacket)) ? sizeof(RXQueuedPacket) : sizeof(RXPacketHeader) + newRXPacket.rxHeader.length;
if (this->_rxCurrentQueuedPacketPosition == 0)
{
WIFI_triggerIRQ(WifiIRQ06_RXStart); WIFI_triggerIRQ(WifiIRQ06_RXStart);
} }
const size_t totalPacketLength = (this->_rxCurrentPacket.rxHeader.length > MAX_PACKET_SIZE_80211) ? sizeof(RXPacketHeader) + MAX_PACKET_SIZE_80211 : sizeof(RXPacketHeader) + this->_rxCurrentPacket.rxHeader.length;
this->_rxCurrentPacket.latencyCount++;
// If the user selects compatibility mode, then we will emulate the transfer delays // If the user selects compatibility mode, then we will emulate the transfer delays
// involved with copying RX packet data into WiFi RAM. Otherwise, just copy all of // involved with copying RX packet data into WiFi RAM. Otherwise, just copy all of
// the RX packet data into WiFi RAM immediately. // the RX packet data into WiFi RAM immediately.
if (this->_currentEmulationLevel == WifiEmulationLevel_Compatibility) if (this->_currentEmulationLevel == WifiEmulationLevel_Compatibility)
{ {
// Copy the RX packet data into WiFi RAM over time. // Copy the RX packet data into WiFi RAM over time.
if ( (this->_rxCurrentQueuedPacketPosition == 0) || (newRXPacket.latencyCount >= RX_LATENCY_LIMIT) ) if ( (this->_rxCurrentQueuedPacketPosition == 0) || (this->_rxCurrentPacket.latencyCount >= RX_LATENCY_LIMIT) )
{ {
this->_RXWriteOneHalfword(*(u16 *)&newRXPacket.rawFrameData[this->_rxCurrentQueuedPacketPosition]); this->_RXWriteOneHalfword(*(u16 *)&this->_rxCurrentPacket.rawFrameData[this->_rxCurrentQueuedPacketPosition]);
this->_rxCurrentQueuedPacketPosition += 2; this->_rxCurrentQueuedPacketPosition += 2;
} }
} }
@ -4861,17 +4864,13 @@ void WifiHandler::_CopyFromRXQueue()
// Copy the entire RX packet data into WiFi RAM immediately. // Copy the entire RX packet data into WiFi RAM immediately.
while (this->_rxCurrentQueuedPacketPosition < totalPacketLength) while (this->_rxCurrentQueuedPacketPosition < totalPacketLength)
{ {
this->_RXWriteOneHalfword(*(u16 *)&newRXPacket.rawFrameData[this->_rxCurrentQueuedPacketPosition]); this->_RXWriteOneHalfword(*(u16 *)&this->_rxCurrentPacket.rawFrameData[this->_rxCurrentQueuedPacketPosition]);
this->_rxCurrentQueuedPacketPosition += 2; this->_rxCurrentQueuedPacketPosition += 2;
} }
} }
if (this->_rxCurrentQueuedPacketPosition >= totalPacketLength) if (this->_rxCurrentQueuedPacketPosition >= totalPacketLength)
{ {
slock_lock(this->_mutexRXPacketQueue);
this->_rxPacketQueue.pop_front();
slock_unlock(this->_mutexRXPacketQueue);
this->_rxCurrentQueuedPacketPosition = 0; this->_rxCurrentQueuedPacketPosition = 0;
// Adjust the RX cursor address so that it is 4-byte aligned. // Adjust the RX cursor address so that it is 4-byte aligned.

View File

@ -3334,6 +3334,7 @@ protected:
slock_t *_mutexRXPacketQueue; slock_t *_mutexRXPacketQueue;
std::deque<RXQueuedPacket> _rxPacketQueue; std::deque<RXQueuedPacket> _rxPacketQueue;
RXQueuedPacket _rxCurrentPacket;
size_t _rxCurrentQueuedPacketPosition; size_t _rxCurrentQueuedPacketPosition;
EAPStatus _softAPStatus; EAPStatus _softAPStatus;