From 0e0968f7483c8bce5fd12b67704785fa09774877 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 Jul 2015 17:58:49 -0700 Subject: [PATCH] initial support to get CongestionControl down to Connection --- .../networking/src/udt/CongestionControl.cpp | 23 ++++++++-------- .../networking/src/udt/CongestionControl.h | 26 +++++++++++-------- libraries/networking/src/udt/Connection.cpp | 8 ++++-- libraries/networking/src/udt/Connection.h | 5 +++- libraries/networking/src/udt/Socket.cpp | 10 ++++++- libraries/networking/src/udt/Socket.h | 5 ++++ 6 files changed, 50 insertions(+), 27 deletions(-) diff --git a/libraries/networking/src/udt/CongestionControl.cpp b/libraries/networking/src/udt/CongestionControl.cpp index 47a45485fa..5acba518e4 100644 --- a/libraries/networking/src/udt/CongestionControl.cpp +++ b/libraries/networking/src/udt/CongestionControl.cpp @@ -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& losslist) { +void DefaultCC::onLoss(const std::vector& losslist) { //Slow Start stopped, if it hasn't yet if (_slowStart) { _slowStart = false; @@ -101,7 +100,7 @@ void UdtCC::onLoss(const std::vector& 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& 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 { /* diff --git a/libraries/networking/src/udt/CongestionControl.h b/libraries/networking/src/udt/CongestionControl.h index 9f61c7944f..c54405e73d 100644 --- a/libraries/networking/src/udt/CongestionControl.h +++ b/libraries/networking/src/udt/CongestionControl.h @@ -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 create() = 0; }; @@ -82,13 +88,12 @@ template class CongestionControlFactory: public CongestionControlVirtu { public: virtual ~CongestionControlFactory() {} - virtual std::unique_ptr create() { return std::unique_ptr(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 \ No newline at end of file +#endif // hifi_CongestionControl_h diff --git a/libraries/networking/src/udt/Connection.cpp b/libraries/networking/src/udt/Connection.cpp index 9b58dc41a5..0f09e67a72 100644 --- a/libraries/networking/src/udt/Connection.cpp +++ b/libraries/networking/src/udt/Connection.cpp @@ -16,6 +16,7 @@ #include #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) : _parentSocket(parentSocket), - _destination(destination) + _destination(destination), + _congestionControl(move(congestionControl)) { + } Connection::~Connection() { @@ -343,6 +346,7 @@ void Connection::processACK(std::unique_ptr controlPacket) { } // fire the onACK callback for congestion control + _congestionControl->onAck(ack); // update the total count of received ACKs ++_totalReceivedACKs; diff --git a/libraries/networking/src/udt/Connection.h b/libraries/networking/src/udt/Connection.h index 200f8acda8..7cc2563fc5 100644 --- a/libraries/networking/src/udt/Connection.h +++ b/libraries/networking/src/udt/Connection.h @@ -22,6 +22,7 @@ namespace udt { +class CongestionControl; class ControlPacket; class Packet; class Socket; @@ -32,7 +33,7 @@ public: using SequenceNumberTimePair = std::pair; using SentACKMap = std::unordered_map; - Connection(Socket* parentSocket, HifiSockAddr destination); + Connection(Socket* parentSocket, HifiSockAddr destination, std::unique_ptr congestionControl); ~Connection(); void sendReliablePacket(std::unique_ptr packet); @@ -89,6 +90,8 @@ private: std::unique_ptr _sendQueue; + std::unique_ptr _congestionControl; + // Control Packet stat collection int _totalReceivedACKs { 0 }; int _totalSentACKs { 0 }; diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index 15f0febc9b..c2ad40b9f5 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -79,7 +79,7 @@ qint64 Socket::writePacket(std::unique_ptr 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 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(); +} diff --git a/libraries/networking/src/udt/Socket.h b/libraries/networking/src/udt/Socket.h index 9ca4adcc74..497c98b296 100644 --- a/libraries/networking/src/udt/Socket.h +++ b/libraries/networking/src/udt/Socket.h @@ -22,6 +22,7 @@ #include #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 ccFactory); private slots: void readPendingDatagrams(); @@ -78,6 +81,8 @@ private: int32_t _synInterval = 10; // 10ms QTimer _synTimer; + + std::unique_ptr _ccFactory { new CongestionControlFactory() }; }; } // namespace udt