Bugfix: Introduced RateAccuracy setting for Drone to conserve CPU at the cost of accuracy

Fixes #151
This commit is contained in:
Srivats P 2015-10-12 18:11:30 +05:30
parent fdbae1f1bf
commit 06182a435c
7 changed files with 92 additions and 5 deletions

View File

@ -43,6 +43,7 @@ AbstractPort::AbstractPort(int id, const char *device)
data_.set_is_exclusive_control(false); data_.set_is_exclusive_control(false);
isSendQueueDirty_ = false; isSendQueueDirty_ = false;
rateAccuracy_ = kHighAccuracy;
linkState_ = OstProto::LinkStateUnknown; linkState_ = OstProto::LinkStateUnknown;
minPacketSetSize_ = 1; minPacketSetSize_ = 1;
@ -144,6 +145,17 @@ void AbstractPort::addNote(QString note)
data_.set_notes(notes.toStdString()); data_.set_notes(notes.toStdString());
} }
AbstractPort::Accuracy AbstractPort::rateAccuracy()
{
return rateAccuracy_;
}
bool AbstractPort::setRateAccuracy(Accuracy accuracy)
{
rateAccuracy_ = accuracy;
return true;
}
void AbstractPort::updatePacketList() void AbstractPort::updatePacketList()
{ {
switch(data_.transmit_mode()) switch(data_.transmit_mode())

View File

@ -49,6 +49,13 @@ public:
quint64 txBps; quint64 txBps;
}; };
enum Accuracy
{
kHighAccuracy,
kMediumAccuracy,
kLowAccuracy,
};
AbstractPort(int id, const char *device); AbstractPort(int id, const char *device);
virtual ~AbstractPort(); virtual ~AbstractPort();
@ -75,6 +82,9 @@ public:
bool isDirty() { return isSendQueueDirty_; } bool isDirty() { return isSendQueueDirty_; }
void setDirty() { isSendQueueDirty_ = true; } void setDirty() { isSendQueueDirty_ = true; }
Accuracy rateAccuracy();
virtual bool setRateAccuracy(Accuracy accuracy);
virtual void clearPacketList() = 0; virtual void clearPacketList() = 0;
virtual void loopNextPacketSet(qint64 size, qint64 repeats, virtual void loopNextPacketSet(qint64 size, qint64 repeats,
long repeatDelaySec, long repeatDelayNsec) = 0; long repeatDelaySec, long repeatDelayNsec) = 0;
@ -106,6 +116,7 @@ protected:
OstProto::Port data_; OstProto::Port data_;
OstProto::LinkState linkState_; OstProto::LinkState linkState_;
ulong minPacketSetSize_; ulong minPacketSetSize_;
Accuracy rateAccuracy_;
quint64 maxStatsValue_; quint64 maxStatsValue_;
struct PortStats stats_; struct PortStats stats_;

View File

@ -167,6 +167,15 @@ void PcapPort::updateNotes()
arg(notes).toStdString()); arg(notes).toStdString());
} }
bool PcapPort::setRateAccuracy(AbstractPort::Accuracy accuracy)
{
if (transmitter_->setRateAccuracy(accuracy)) {
AbstractPort::setRateAccuracy(accuracy);
return true;
}
return false;
}
PcapPort::PortMonitor::PortMonitor(const char *device, Direction direction, PcapPort::PortMonitor::PortMonitor(const char *device, Direction direction,
AbstractPort::PortStats *stats) AbstractPort::PortStats *stats)
{ {
@ -352,6 +361,26 @@ PcapPort::PortTransmitter::~PortTransmitter()
pcap_close(handle_); pcap_close(handle_);
} }
bool PcapPort::PortTransmitter::setRateAccuracy(
AbstractPort::Accuracy accuracy)
{
switch (accuracy) {
case kHighAccuracy:
udelayFn_ = udelay;
qWarning("%s: rate accuracy set to High - busy wait", __FUNCTION__);
break;
case kLowAccuracy:
udelayFn_ = QThread::usleep;
qWarning("%s: rate accuracy set to Low - usleep", __FUNCTION__);
break;
default:
qWarning("%s: unsupported rate accuracy value %d", __FUNCTION__,
accuracy);
return false;
}
return true;
}
void PcapPort::PortTransmitter::clearPacketList() void PcapPort::PortTransmitter::clearPacketList()
{ {
Q_ASSERT(!isRunning()); Q_ASSERT(!isRunning());
@ -554,7 +583,7 @@ _restart:
long usecs = seq->usecDelay_ + overHead; long usecs = seq->usecDelay_ + overHead;
if (usecs > 0) if (usecs > 0)
{ {
udelay(usecs); (*udelayFn_)(usecs);
overHead = 0; overHead = 0;
} }
else else
@ -580,7 +609,7 @@ _restart:
if (usecs > 0) if (usecs > 0)
{ {
udelay(usecs); (*udelayFn_)(usecs);
overHead = 0; overHead = 0;
} }
else else
@ -656,7 +685,7 @@ int PcapPort::PortTransmitter::sendQueueTransmit(pcap_t *p,
usec += overHead; usec += overHead;
if (usec > 0) if (usec > 0)
{ {
udelay(usec); (*udelayFn_)(usec);
overHead = 0; overHead = 0;
} }
else else
@ -685,7 +714,7 @@ int PcapPort::PortTransmitter::sendQueueTransmit(pcap_t *p,
return 0; return 0;
} }
void PcapPort::PortTransmitter::udelay(long usec) void PcapPort::PortTransmitter::udelay(unsigned long usec)
{ {
#if defined(Q_OS_WIN32) #if defined(Q_OS_WIN32)
LARGE_INTEGER tgtTicks; LARGE_INTEGER tgtTicks;

View File

@ -38,6 +38,8 @@ public:
virtual bool hasExclusiveControl() { return false; } virtual bool hasExclusiveControl() { return false; }
virtual bool setExclusiveControl(bool /*exclusive*/) { return false; } virtual bool setExclusiveControl(bool /*exclusive*/) { return false; }
virtual bool setRateAccuracy(AbstractPort::Accuracy accuracy);
virtual void clearPacketList() { virtual void clearPacketList() {
transmitter_->clearPacketList(); transmitter_->clearPacketList();
setPacketListLoopMode(false, 0, 0); setPacketListLoopMode(false, 0, 0);
@ -102,6 +104,9 @@ protected:
public: public:
PortTransmitter(const char *device); PortTransmitter(const char *device);
~PortTransmitter(); ~PortTransmitter();
bool setRateAccuracy(AbstractPort::Accuracy accuracy);
void clearPacketList(); void clearPacketList();
void loopNextPacketSet(qint64 size, qint64 repeats, void loopNextPacketSet(qint64 size, qint64 repeats,
long repeatDelaySec, long repeatDelayNsec); long repeatDelaySec, long repeatDelayNsec);
@ -172,7 +177,7 @@ protected:
long usecDelay_; long usecDelay_;
}; };
void udelay(long usec); static void udelay(unsigned 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);
@ -186,6 +191,8 @@ protected:
int returnToQIdx_; int returnToQIdx_;
quint64 loopDelay_; quint64 loopDelay_;
void (*udelayFn_)(unsigned long);
bool usingInternalStats_; bool usingInternalStats_;
AbstractPort::PortStats *stats_; AbstractPort::PortStats *stats_;
bool usingInternalHandle_; bool usingInternalHandle_;

View File

@ -36,12 +36,15 @@ PortManager::PortManager()
pcap_if_t *deviceList; pcap_if_t *deviceList;
pcap_if_t *device; pcap_if_t *device;
char errbuf[PCAP_ERRBUF_SIZE]; char errbuf[PCAP_ERRBUF_SIZE];
AbstractPort::Accuracy txRateAccuracy;
qDebug("Retrieving the device list from the local machine\n"); qDebug("Retrieving the device list from the local machine\n");
if (pcap_findalldevs(&deviceList, errbuf) == -1) if (pcap_findalldevs(&deviceList, errbuf) == -1)
qDebug("Error in pcap_findalldevs_ex: %s\n", errbuf); qDebug("Error in pcap_findalldevs_ex: %s\n", errbuf);
txRateAccuracy = rateAccuracy();
for(device = deviceList, i = 0; device != NULL; device = device->next, i++) for(device = deviceList, i = 0; device != NULL; device = device->next, i++)
{ {
AbstractPort *port; AbstractPort *port;
@ -81,6 +84,9 @@ PortManager::PortManager()
continue; continue;
} }
if (!port->setRateAccuracy(txRateAccuracy))
qWarning("failed to set rateAccuracy (%d)", txRateAccuracy);
portList_.append(port); portList_.append(port);
} }
@ -106,6 +112,21 @@ PortManager* PortManager::instance()
return instance_; return instance_;
} }
AbstractPort::Accuracy PortManager::rateAccuracy()
{
QString rateAccuracy = appSettings->value(kRateAccuracyKey,
kRateAccuracyDefaultValue).toString();
if (rateAccuracy == "High")
return AbstractPort::kHighAccuracy;
else if (rateAccuracy == "Low")
return AbstractPort::kLowAccuracy;
else
qWarning("Unsupported RateAccuracy setting - %s",
qPrintable(rateAccuracy));
return AbstractPort::kHighAccuracy;
}
bool PortManager::filterAcceptsPort(const char *name) bool PortManager::filterAcceptsPort(const char *name)
{ {
QRegExp pattern; QRegExp pattern;

View File

@ -35,6 +35,7 @@ public:
static PortManager* instance(); static PortManager* instance();
private: private:
AbstractPort::Accuracy rateAccuracy();
bool filterAcceptsPort(const char *name); bool filterAcceptsPort(const char *name);
private: private:

View File

@ -25,6 +25,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
extern QSettings *appSettings; extern QSettings *appSettings;
//
// General Section Keys
//
const QString kRateAccuracyKey("RateAccuracy");
const QString kRateAccuracyDefaultValue("High");
// //
// PortList Section Keys // PortList Section Keys
// //