Refactored send queue data structure and associated processing
This commit is contained in:
parent
18e7b9b49c
commit
204e6efc2a
@ -570,7 +570,8 @@ bool AbstractProtocol::isProtocolFrameSizeVariable() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the number of frames required for the protocol to vary its fields
|
Returns the minimum number of frames required for the protocol to
|
||||||
|
vary its fields
|
||||||
|
|
||||||
This is the lowest common multiple (LCM) of the counts of all the varying
|
This is the lowest common multiple (LCM) of the counts of all the varying
|
||||||
fields in the protocol. Use the AbstractProtocol::lcm() static utility
|
fields in the protocol. Use the AbstractProtocol::lcm() static utility
|
||||||
|
@ -454,6 +454,10 @@ int StreamBase::frameVariableCount() const
|
|||||||
proto = iter->next();
|
proto = iter->next();
|
||||||
count = proto->protocolFrameVariableCount();
|
count = proto->protocolFrameVariableCount();
|
||||||
|
|
||||||
|
// correct count for mis-behaving protocols
|
||||||
|
if (count <= 0)
|
||||||
|
count = 1;
|
||||||
|
|
||||||
frameCount = AbstractProtocol::lcm(frameCount, count);
|
frameCount = AbstractProtocol::lcm(frameCount, count);
|
||||||
}
|
}
|
||||||
delete iter;
|
delete iter;
|
||||||
|
@ -161,6 +161,9 @@ void AbstractPort::updatePacketListSequential()
|
|||||||
long ipg1 = 0, ipg2 = 0;
|
long ipg1 = 0, ipg2 = 0;
|
||||||
long np1 = 0, np2 = 0;
|
long np1 = 0, np2 = 0;
|
||||||
|
|
||||||
|
// We derive n, x, y such that
|
||||||
|
// n * x + y = total number of packets to be sent
|
||||||
|
|
||||||
switch (streamList_[i]->sendUnit())
|
switch (streamList_[i]->sendUnit())
|
||||||
{
|
{
|
||||||
case OstProto::StreamControl::e_su_bursts:
|
case OstProto::StreamControl::e_su_bursts:
|
||||||
@ -209,6 +212,8 @@ void AbstractPort::updatePacketListSequential()
|
|||||||
|
|
||||||
if (n > 1)
|
if (n > 1)
|
||||||
loopNextPacketSet(x, n);
|
loopNextPacketSet(x, n);
|
||||||
|
else if (n == 0)
|
||||||
|
x = 0;
|
||||||
|
|
||||||
for (int j = 0; j < (x+y); j++)
|
for (int j = 0; j < (x+y); j++)
|
||||||
{
|
{
|
||||||
|
@ -289,30 +289,28 @@ PcapPort::PortTransmitter::~PortTransmitter()
|
|||||||
void PcapPort::PortTransmitter::clearPacketList()
|
void PcapPort::PortTransmitter::clearPacketList()
|
||||||
{
|
{
|
||||||
Q_ASSERT(!isRunning());
|
Q_ASSERT(!isRunning());
|
||||||
// \todo lock for sendQueueList
|
// \todo lock for packetSequenceList
|
||||||
while(sendQueueList_.size())
|
while(packetSequenceList_.size())
|
||||||
{
|
delete packetSequenceList_.takeFirst();
|
||||||
pcap_send_queue *sq = sendQueueList_.takeFirst();
|
|
||||||
pcap_sendqueue_destroy(sq);
|
currentPacketSequence_ = NULL;
|
||||||
}
|
repeatSequenceStart_ = -1;
|
||||||
sendQueueRepeat_.clear();
|
repeatSize_ = 0;
|
||||||
sendQueueGoto_.clear();
|
packetCount_ = 0;
|
||||||
currentSendQueue_ = NULL;
|
|
||||||
currentPacketSetQIdx_ = -1;
|
|
||||||
currentPacketSetSize_ = -1;
|
|
||||||
currentPacketSetRepeat_ = 1;
|
|
||||||
currentPacketSetCount_ = 0;
|
|
||||||
setPacketListLoopMode(false, 0, 0);
|
setPacketListLoopMode(false, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PcapPort::PortTransmitter::loopNextPacketSet(qint64 size, qint64 repeats)
|
void PcapPort::PortTransmitter::loopNextPacketSet(qint64 size, qint64 repeats)
|
||||||
{
|
{
|
||||||
// Trigger a new sendQ alloc on next packet
|
currentPacketSequence_ = new PacketSequence;
|
||||||
currentSendQueue_ = NULL;
|
currentPacketSequence_->repeatCount_ = repeats;
|
||||||
currentPacketSetQIdx_ = sendQueueList_.size();
|
|
||||||
currentPacketSetSize_ = size;
|
repeatSequenceStart_ = packetSequenceList_.size();
|
||||||
currentPacketSetRepeat_ = repeats;
|
repeatSize_ = size;
|
||||||
currentPacketSetCount_ = 0;
|
packetCount_ = 0;
|
||||||
|
|
||||||
|
packetSequenceList_.append(currentPacketSequence_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PcapPort::PortTransmitter::appendToPacketList(long sec, long nsec,
|
bool PcapPort::PortTransmitter::appendToPacketList(long sec, long nsec,
|
||||||
@ -325,48 +323,51 @@ bool PcapPort::PortTransmitter::appendToPacketList(long sec, long nsec,
|
|||||||
pktHdr.ts.tv_sec = sec;
|
pktHdr.ts.tv_sec = sec;
|
||||||
pktHdr.ts.tv_usec = nsec/1000;
|
pktHdr.ts.tv_usec = nsec/1000;
|
||||||
|
|
||||||
if ((currentSendQueue_ == NULL) ||
|
if (currentPacketSequence_ == NULL ||
|
||||||
(currentSendQueue_->len + 2*sizeof(pcap_pkthdr) + length)
|
!currentPacketSequence_->hasFreeSpace(2*sizeof(pcap_pkthdr)+length))
|
||||||
> currentSendQueue_->maxlen)
|
|
||||||
{
|
{
|
||||||
// Add a zero len packet at end of currentSendQueue_ for
|
// Add a zero len packet at end of currentSendQueue_ for
|
||||||
// inter-sendQ timing
|
// inter-sendQ timing
|
||||||
if (sendQueueList_.size())
|
if (packetSequenceList_.size())
|
||||||
{
|
{
|
||||||
pcap_pkthdr hdr = pktHdr;
|
pcap_pkthdr hdr = pktHdr;
|
||||||
hdr.caplen = 0;
|
hdr.caplen = 0;
|
||||||
pcap_sendqueue_queue(sendQueueList_.last(), &hdr, (u_char*)packet);
|
pcap_sendqueue_queue(packetSequenceList_.last()->sendQueue_,
|
||||||
|
&hdr, (u_char*)packet);
|
||||||
}
|
}
|
||||||
//! \todo (LOW): calculate sendqueue size
|
//! \todo (LOW): calculate sendqueue size
|
||||||
currentSendQueue_ = pcap_sendqueue_alloc(1*1024*1024);
|
currentPacketSequence_ = new PacketSequence;
|
||||||
|
|
||||||
sendQueueList_.append(currentSendQueue_);
|
packetSequenceList_.append(currentPacketSequence_);
|
||||||
sendQueueRepeat_.append(1);
|
|
||||||
sendQueueGoto_.append(-1);
|
|
||||||
|
|
||||||
// Validate that the pkt will fit inside the new currentSendQueue_
|
// Validate that the pkt will fit inside the new currentSendQueue_
|
||||||
Q_ASSERT((length + sizeof(pcap_pkthdr)) < currentSendQueue_->maxlen);
|
Q_ASSERT(currentPacketSequence_->hasFreeSpace(
|
||||||
|
sizeof(pcap_pkthdr) + length));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcap_sendqueue_queue(currentSendQueue_, &pktHdr, (u_char*) packet) < 0)
|
if (pcap_sendqueue_queue(currentPacketSequence_->sendQueue_, &pktHdr,
|
||||||
op = false;
|
(u_char*) packet) < 0)
|
||||||
|
|
||||||
currentPacketSetCount_++;
|
|
||||||
if (currentPacketSetCount_ == currentPacketSetSize_)
|
|
||||||
{
|
{
|
||||||
qDebug("i=%d, currentPacketSetQIdx_ = %d, currentPacketSetRepeat_ = %d",
|
op = false;
|
||||||
sendQueueRepeat_.size(),
|
|
||||||
currentPacketSetQIdx_,
|
|
||||||
currentPacketSetRepeat_);
|
|
||||||
// End current sendQ
|
|
||||||
sendQueueGoto_.last() = currentPacketSetQIdx_;
|
|
||||||
sendQueueRepeat_.last() = currentPacketSetRepeat_;
|
|
||||||
currentPacketSetSize_ = -1;
|
|
||||||
|
|
||||||
// Trigger a new sendQ allocation
|
|
||||||
currentSendQueue_ = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
packetCount_++;
|
||||||
|
if (repeatSize_ > 0 && packetCount_ == repeatSize_)
|
||||||
|
{
|
||||||
|
qDebug("repeatSequenceStart_=%d, repeatSize_ = %llu",
|
||||||
|
repeatSequenceStart_, repeatSize_);
|
||||||
|
|
||||||
|
// Set the packetSequence repeatSize
|
||||||
|
Q_ASSERT(repeatSequenceStart_ >= 0);
|
||||||
|
Q_ASSERT(repeatSequenceStart_ < packetSequenceList_.size());
|
||||||
|
packetSequenceList_[repeatSequenceStart_]->repeatSize_ =
|
||||||
|
packetSequenceList_.size() - repeatSequenceStart_;
|
||||||
|
|
||||||
|
repeatSize_ = 0;
|
||||||
|
|
||||||
|
// End current pktSeq and trigger a new pktSeq allocation for next pkt
|
||||||
|
currentPacketSequence_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
@ -407,34 +408,30 @@ void PcapPort::PortTransmitter::run()
|
|||||||
int i;
|
int i;
|
||||||
long overHead = 0;
|
long overHead = 0;
|
||||||
|
|
||||||
qDebug("sendQueueList_.size = %d", sendQueueList_.size());
|
qDebug("packetSequenceList_.size = %d", packetSequenceList_.size());
|
||||||
if (sendQueueList_.size() <= 0)
|
if (packetSequenceList_.size() <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for(i = 0; i < sendQueueList_.size(); i++) {
|
for(i = 0; i < packetSequenceList_.size(); i++) {
|
||||||
qDebug("sendQ[%d]: rpt = %d, goto = %d", i,
|
qDebug("sendQ[%d]: rptCnt = %d, rptSz = %d", i,
|
||||||
sendQueueRepeat_.at(i), sendQueueGoto_.at(i));
|
packetSequenceList_.at(i)->repeatCount_,
|
||||||
|
packetSequenceList_.at(i)->repeatSize_);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < sendQueueList_.size(); i++)
|
for(i = 0; i < packetSequenceList_.size(); i++)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
|
|
||||||
_restart:
|
_restart:
|
||||||
int idx = sendQueueGoto_.at(i);
|
int rptSz = packetSequenceList_.at(i)->repeatSize_;
|
||||||
int rpt = sendQueueRepeat_.at(i);
|
int rptCnt = packetSequenceList_.at(i)->repeatCount_;
|
||||||
int sqi = i;
|
|
||||||
|
|
||||||
for (int n = 0; n < rpt; n++)
|
for (int j = 0; j < rptCnt; j++)
|
||||||
{
|
{
|
||||||
Q_ASSERT(sqi <= i);
|
for (int k = 0; k < rptSz; k++)
|
||||||
|
{
|
||||||
#if 0
|
int ret = sendQueueTransmit(handle_,
|
||||||
if ((n & 0x3F) == 0)
|
packetSequenceList_.at(i+k)->sendQueue_,
|
||||||
qDebug("i = %d, n = %d/%d, sqi = %d\n", i, n, rpt, sqi);
|
overHead, kSyncTransmit);
|
||||||
#endif
|
|
||||||
ret = sendQueueTransmit(handle_, sendQueueList_.at(sqi), overHead,
|
|
||||||
kSyncTransmit);
|
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
@ -443,8 +440,7 @@ _restart:
|
|||||||
stop_ = false;
|
stop_ = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
sqi = (sqi == i) ? idx : sqi+1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,21 +111,43 @@ protected:
|
|||||||
void run();
|
void run();
|
||||||
void stop();
|
void stop();
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
class PacketSequence
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PacketSequence() {
|
||||||
|
sendQueue_ = pcap_sendqueue_alloc(1*1024*1024);
|
||||||
|
repeatCount_ = 1;
|
||||||
|
repeatSize_ = 1;
|
||||||
|
}
|
||||||
|
~PacketSequence() {
|
||||||
|
pcap_sendqueue_destroy(sendQueue_);
|
||||||
|
}
|
||||||
|
bool hasFreeSpace(int size) {
|
||||||
|
if ((sendQueue_->len + size) <= sendQueue_->maxlen)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pcap_send_queue *sendQueue_;
|
||||||
|
int repeatCount_;
|
||||||
|
int repeatSize_;
|
||||||
|
};
|
||||||
|
|
||||||
void udelay(long usec);
|
void udelay(long usec);
|
||||||
int sendQueueTransmit(pcap_t *p, pcap_send_queue *queue, long &overHead,
|
int sendQueueTransmit(pcap_t *p, pcap_send_queue *queue, long &overHead,
|
||||||
int sync);
|
int sync);
|
||||||
|
|
||||||
quint64 ticksFreq_;
|
quint64 ticksFreq_;
|
||||||
int currentPacketSetQIdx_;
|
QList<PacketSequence*> packetSequenceList_;
|
||||||
int currentPacketSetSize_;
|
PacketSequence *currentPacketSequence_;
|
||||||
int currentPacketSetRepeat_;
|
int repeatSequenceStart_;
|
||||||
int currentPacketSetCount_;
|
quint64 repeatSize_;
|
||||||
pcap_send_queue* currentSendQueue_;
|
quint64 packetCount_;
|
||||||
QList<pcap_send_queue*> sendQueueList_;
|
|
||||||
QList<int> sendQueueRepeat_;
|
|
||||||
QList<int> sendQueueGoto_;
|
|
||||||
int returnToQIdx_;
|
int returnToQIdx_;
|
||||||
long loopDelay_;
|
long loopDelay_;
|
||||||
|
|
||||||
bool usingInternalStats_;
|
bool usingInternalStats_;
|
||||||
AbstractPort::PortStats *stats_;
|
AbstractPort::PortStats *stats_;
|
||||||
bool usingInternalHandle_;
|
bool usingInternalHandle_;
|
||||||
|
Loading…
Reference in New Issue
Block a user