mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 03:53:10 +02:00
initial support to get CongestionControl down to Connection
This commit is contained in:
parent
988bd226ca
commit
0e0968f748
6 changed files with 50 additions and 27 deletions
|
@ -15,10 +15,9 @@
|
|||
|
||||
using namespace udt;
|
||||
|
||||
void UdtCC::init() {
|
||||
_rcInterval = _synInterval;
|
||||
void DefaultCC::init() {
|
||||
_lastRCTime = usecTimestampNow();
|
||||
setAckTimer(_rcInterval);
|
||||
setAckTimer(synInterval());
|
||||
|
||||
_lastAck = _sendCurrSeqNum;
|
||||
_lastDecSeq = SequenceNumber{ SequenceNumber::MAX };
|
||||
|
@ -27,7 +26,7 @@ void UdtCC::init() {
|
|||
_packetSendPeriod = 1.0;
|
||||
}
|
||||
|
||||
void UdtCC::onACK(SequenceNumber ackNum) {
|
||||
void DefaultCC::onACK(SequenceNumber ackNum) {
|
||||
int64_t B = 0;
|
||||
double inc = 0;
|
||||
// Note: 1/24/2012
|
||||
|
@ -37,7 +36,7 @@ void UdtCC::onACK(SequenceNumber ackNum) {
|
|||
const double min_inc = 0.01;
|
||||
|
||||
uint64_t currtime = usecTimestampNow();
|
||||
if (currtime - _lastRCTime < (uint64_t)_rcInterval) {
|
||||
if (currtime - _lastRCTime < (uint64_t)synInterval()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -52,11 +51,11 @@ void UdtCC::onACK(SequenceNumber ackNum) {
|
|||
if (_recvieveRate > 0) {
|
||||
_packetSendPeriod = 1000000.0 / _recvieveRate;
|
||||
} else {
|
||||
_packetSendPeriod = (_rtt + _rcInterval) / _congestionWindowSize;
|
||||
_packetSendPeriod = (_rtt + synInterval()) / _congestionWindowSize;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_congestionWindowSize = _recvieveRate / 1000000.0 * (_rtt + _rcInterval) + 16;
|
||||
_congestionWindowSize = _recvieveRate / 1000000.0 * (_rtt + synInterval()) + 16;
|
||||
}
|
||||
|
||||
// During Slow Start, no rate increase
|
||||
|
@ -86,10 +85,10 @@ void UdtCC::onACK(SequenceNumber ackNum) {
|
|||
}
|
||||
}
|
||||
|
||||
_packetSendPeriod = (_packetSendPeriod * _rcInterval) / (_packetSendPeriod * inc + _rcInterval);
|
||||
_packetSendPeriod = (_packetSendPeriod * synInterval()) / (_packetSendPeriod * inc + synInterval());
|
||||
}
|
||||
|
||||
void UdtCC::onLoss(const std::vector<SequenceNumber>& losslist) {
|
||||
void DefaultCC::onLoss(const std::vector<SequenceNumber>& losslist) {
|
||||
//Slow Start stopped, if it hasn't yet
|
||||
if (_slowStart) {
|
||||
_slowStart = false;
|
||||
|
@ -101,7 +100,7 @@ void UdtCC::onLoss(const std::vector<SequenceNumber>& losslist) {
|
|||
// If no receiving rate is observed, we have to compute the sending
|
||||
// rate according to the current window size, and decrease it
|
||||
// using the method below.
|
||||
_packetSendPeriod = _congestionWindowSize / (_rtt + _rcInterval);
|
||||
_packetSendPeriod = _congestionWindowSize / (_rtt + synInterval());
|
||||
}
|
||||
|
||||
_loss = true;
|
||||
|
@ -128,13 +127,13 @@ void UdtCC::onLoss(const std::vector<SequenceNumber>& losslist) {
|
|||
}
|
||||
}
|
||||
|
||||
void UdtCC::onTimeout() {
|
||||
void DefaultCC::onTimeout() {
|
||||
if (_slowStart) {
|
||||
_slowStart = false;
|
||||
if (_recvieveRate > 0) {
|
||||
_packetSendPeriod = 1000000.0 / _recvieveRate;
|
||||
} else {
|
||||
_packetSendPeriod = _congestionWindowSize / (_rtt + _rcInterval);
|
||||
_packetSendPeriod = _congestionWindowSize / (_rtt + synInterval());
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
|
|
|
@ -17,15 +17,19 @@
|
|||
#include "SequenceNumber.h"
|
||||
|
||||
namespace udt {
|
||||
|
||||
static const int32_t DEFAULT_SYN_INTERVAL = 10000; // 10 ms
|
||||
|
||||
class Packet;
|
||||
|
||||
class CongestionControl {
|
||||
public:
|
||||
static const int32_t DEFAULT_SYN_INTERVAL = 10000; // 10 ms
|
||||
|
||||
CongestionControl() {}
|
||||
CongestionControl() {};
|
||||
CongestionControl(int synInterval) : _synInterval(synInterval) {}
|
||||
virtual ~CongestionControl() {}
|
||||
|
||||
int synInterval() const { return _synInterval; }
|
||||
|
||||
virtual void init() {}
|
||||
virtual void close() {}
|
||||
|
@ -35,12 +39,10 @@ public:
|
|||
virtual void onPacketReceived(const Packet& packet) {}
|
||||
|
||||
protected:
|
||||
void setAckTimer(int syn) { _ackPeriod = (syn > _synInterval) ? _synInterval : syn; }
|
||||
void setAckInterval(int interval) { _ackInterval = interval; }
|
||||
void setAckTimer(int period) { _ackPeriod = (period > _synInterval) ? _synInterval : period; }
|
||||
void setAckInterval(int ackInterval) { _ackInterval = ackInterval; }
|
||||
void setRto(int rto) { _userDefinedRto = true; _rto = rto; }
|
||||
|
||||
int32_t _synInterval = DEFAULT_SYN_INTERVAL; // UDT constant parameter, SYN
|
||||
|
||||
double _packetSendPeriod = 1.0; // Packet sending period, in microseconds
|
||||
double _congestionWindowSize = 16.0; // Congestion window size, in packets
|
||||
|
||||
|
@ -66,6 +68,8 @@ private:
|
|||
int _ackPeriod = 0; // Periodical timer to send an ACK, in milliseconds
|
||||
int _ackInterval = 0; // How many packets to send one ACK, in packets
|
||||
|
||||
int _synInterval { DEFAULT_SYN_INTERVAL };
|
||||
|
||||
bool _userDefinedRto = false; // if the RTO value is defined by users
|
||||
int _rto = -1; // RTO value, microseconds
|
||||
};
|
||||
|
@ -75,6 +79,8 @@ class CongestionControlVirtualFactory {
|
|||
public:
|
||||
virtual ~CongestionControlVirtualFactory() {}
|
||||
|
||||
static int synInterval() { return DEFAULT_SYN_INTERVAL; }
|
||||
|
||||
virtual std::unique_ptr<CongestionControl> create() = 0;
|
||||
};
|
||||
|
||||
|
@ -82,13 +88,12 @@ template <class T> class CongestionControlFactory: public CongestionControlVirtu
|
|||
{
|
||||
public:
|
||||
virtual ~CongestionControlFactory() {}
|
||||
|
||||
virtual std::unique_ptr<CongestionControl> create() { return std::unique_ptr<T>(new T()); }
|
||||
};
|
||||
|
||||
class UdtCC: public CongestionControl {
|
||||
class DefaultCC: public CongestionControl {
|
||||
public:
|
||||
UdtCC() {}
|
||||
DefaultCC() {}
|
||||
|
||||
public:
|
||||
virtual void init();
|
||||
|
@ -97,7 +102,6 @@ public:
|
|||
virtual void onTimeout();
|
||||
|
||||
private:
|
||||
int _rcInterval = 0; // UDT Rate control interval
|
||||
uint64_t _lastRCTime = 0; // last rate increase time
|
||||
bool _slowStart = true; // if in slow start phase
|
||||
SequenceNumber _lastAck; // last ACKed seq num
|
||||
|
@ -112,4 +116,4 @@ private:
|
|||
|
||||
}
|
||||
|
||||
#endif // hifi_CongestionControl_h
|
||||
#endif // hifi_CongestionControl_h
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <NumericalConstants.h>
|
||||
|
||||
#include "../HifiSockAddr.h"
|
||||
#include "CongestionControl.h"
|
||||
#include "ControlPacket.h"
|
||||
#include "Packet.h"
|
||||
#include "Socket.h"
|
||||
|
@ -24,10 +25,12 @@ using namespace udt;
|
|||
using namespace std;
|
||||
using namespace std::chrono;
|
||||
|
||||
Connection::Connection(Socket* parentSocket, HifiSockAddr destination) :
|
||||
Connection::Connection(Socket* parentSocket, HifiSockAddr destination, unique_ptr<CongestionControl> congestionControl) :
|
||||
_parentSocket(parentSocket),
|
||||
_destination(destination)
|
||||
_destination(destination),
|
||||
_congestionControl(move(congestionControl))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Connection::~Connection() {
|
||||
|
@ -343,6 +346,7 @@ void Connection::processACK(std::unique_ptr<ControlPacket> controlPacket) {
|
|||
}
|
||||
|
||||
// fire the onACK callback for congestion control
|
||||
_congestionControl->onAck(ack);
|
||||
|
||||
// update the total count of received ACKs
|
||||
++_totalReceivedACKs;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
namespace udt {
|
||||
|
||||
class CongestionControl;
|
||||
class ControlPacket;
|
||||
class Packet;
|
||||
class Socket;
|
||||
|
@ -32,7 +33,7 @@ public:
|
|||
using SequenceNumberTimePair = std::pair<SequenceNumber, std::chrono::high_resolution_clock::time_point>;
|
||||
using SentACKMap = std::unordered_map<SequenceNumber, SequenceNumberTimePair>;
|
||||
|
||||
Connection(Socket* parentSocket, HifiSockAddr destination);
|
||||
Connection(Socket* parentSocket, HifiSockAddr destination, std::unique_ptr<CongestionControl> congestionControl);
|
||||
~Connection();
|
||||
|
||||
void sendReliablePacket(std::unique_ptr<Packet> packet);
|
||||
|
@ -89,6 +90,8 @@ private:
|
|||
|
||||
std::unique_ptr<SendQueue> _sendQueue;
|
||||
|
||||
std::unique_ptr<CongestionControl> _congestionControl;
|
||||
|
||||
// Control Packet stat collection
|
||||
int _totalReceivedACKs { 0 };
|
||||
int _totalSentACKs { 0 };
|
||||
|
|
|
@ -79,7 +79,7 @@ qint64 Socket::writePacket(std::unique_ptr<Packet> packet, const HifiSockAddr& s
|
|||
if (packet->isReliable()) {
|
||||
auto it = _connectionsHash.find(sockAddr);
|
||||
if (it == _connectionsHash.end()) {
|
||||
it = _connectionsHash.insert(it, std::make_pair(sockAddr, new Connection(this, sockAddr)));
|
||||
it = _connectionsHash.insert(it, std::make_pair(sockAddr, new Connection(this, sockAddr, _ccFactory->create())));
|
||||
}
|
||||
it->second->sendReliablePacket(std::move(packet));
|
||||
return 0;
|
||||
|
@ -154,3 +154,11 @@ void Socket::rateControlSync() {
|
|||
_synTimer.start(_synInterval);
|
||||
}
|
||||
}
|
||||
|
||||
void Socket::setCongestionControlFactory(std::unique_ptr<CongestionControlVirtualFactory> ccFactory) {
|
||||
// swap the current unique_ptr for the new factory
|
||||
_ccFactory.swap(ccFactory);
|
||||
|
||||
// update the _synInterval to the value from the factory
|
||||
_synInterval = _ccFactory->synInterval();
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <QtNetwork/QUdpSocket>
|
||||
|
||||
#include "../HifiSockAddr.h"
|
||||
#include "CongestionControl.h"
|
||||
#include "Connection.h"
|
||||
|
||||
namespace udt {
|
||||
|
@ -59,6 +60,8 @@ public:
|
|||
|
||||
void addUnfilteredHandler(const HifiSockAddr& senderSockAddr, BasePacketHandler handler)
|
||||
{ _unfilteredHandlers[senderSockAddr] = handler; }
|
||||
|
||||
void setCongestionControlFactory(std::unique_ptr<CongestionControlVirtualFactory> ccFactory);
|
||||
|
||||
private slots:
|
||||
void readPendingDatagrams();
|
||||
|
@ -78,6 +81,8 @@ private:
|
|||
|
||||
int32_t _synInterval = 10; // 10ms
|
||||
QTimer _synTimer;
|
||||
|
||||
std::unique_ptr<CongestionControlVirtualFactory> _ccFactory { new CongestionControlFactory<DefaultCC>() };
|
||||
};
|
||||
|
||||
} // namespace udt
|
||||
|
|
Loading…
Reference in a new issue