Merge branch 'master' of github.com:highfidelity/hifi into black-bis

This commit is contained in:
sam gateau 2018-11-01 16:57:13 -07:00
commit e5a96f265d
7 changed files with 187 additions and 121 deletions

View file

@ -498,8 +498,8 @@ void Avatar::relayJointDataToChildren() {
glm::quat jointRotation; glm::quat jointRotation;
glm::vec3 jointTranslation; glm::vec3 jointTranslation;
if (avatarJointIndex < 0) { if (avatarJointIndex < 0) {
jointRotation = modelEntity->getAbsoluteJointRotationInObjectFrame(jointIndex); jointRotation = modelEntity->getLocalJointRotation(jointIndex);
jointTranslation = modelEntity->getAbsoluteJointTranslationInObjectFrame(jointIndex); jointTranslation = modelEntity->getLocalJointTranslation(jointIndex);
map.push_back(-1); map.push_back(-1);
} else { } else {
int jointIndex = getJointIndex(jointName); int jointIndex = getJointIndex(jointName);
@ -522,8 +522,8 @@ void Avatar::relayJointDataToChildren() {
jointRotation = getJointRotation(avatarJointIndex); jointRotation = getJointRotation(avatarJointIndex);
jointTranslation = getJointTranslation(avatarJointIndex); jointTranslation = getJointTranslation(avatarJointIndex);
} else { } else {
jointRotation = modelEntity->getAbsoluteJointRotationInObjectFrame(jointIndex); jointRotation = modelEntity->getLocalJointRotation(jointIndex);
jointTranslation = modelEntity->getAbsoluteJointTranslationInObjectFrame(jointIndex); jointTranslation = modelEntity->getLocalJointTranslation(jointIndex);
} }
modelEntity->setLocalJointRotation(jointIndex, jointRotation); modelEntity->setLocalJointRotation(jointIndex, jointRotation);
modelEntity->setLocalJointTranslation(jointIndex, jointTranslation); modelEntity->setLocalJointTranslation(jointIndex, jointTranslation);

View file

@ -45,8 +45,10 @@ public:
virtual void onTimeout() {} virtual void onTimeout() {}
virtual void onPacketSent(int wireSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint) {} virtual void onPacketSent(int wireSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint) {}
virtual void onPacketReSent(int wireSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint) {}
virtual int estimatedTimeout() const = 0; virtual int estimatedTimeout() const = 0;
protected: protected:
void setMSS(int mss) { _mss = mss; } void setMSS(int mss) { _mss = mss; }
virtual void setInitialSendSequenceNumber(SequenceNumber seqNum) = 0; virtual void setInitialSendSequenceNumber(SequenceNumber seqNum) = 0;

View file

@ -195,7 +195,7 @@ void Connection::recordSentPackets(int wireSize, int payloadSize,
void Connection::recordRetransmission(int wireSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint) { void Connection::recordRetransmission(int wireSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint) {
_stats.record(ConnectionStats::Stats::Retransmission); _stats.record(ConnectionStats::Stats::Retransmission);
_congestionControl->onPacketSent(wireSize, seqNum, timePoint); _congestionControl->onPacketReSent(wireSize, seqNum, timePoint);
} }
void Connection::sendACK() { void Connection::sendACK() {
@ -327,18 +327,18 @@ void Connection::processACK(ControlPacketPointer controlPacket) {
return; return;
} }
if (ack <= _lastReceivedACK) { if (ack < _lastReceivedACK) {
// this is an out of order ACK, bail // this is an out of order ACK, bail
// or
// processing an already received ACK, bail
return; return;
} }
if (ack > _lastReceivedACK) {
// this is not a repeated ACK, so update our member and tell the send queue
_lastReceivedACK = ack; _lastReceivedACK = ack;
// ACK the send queue so it knows what was received // ACK the send queue so it knows what was received
getSendQueue().ack(ack); getSendQueue().ack(ack);
}
// give this ACK to the congestion control and update the send queue parameters // give this ACK to the congestion control and update the send queue parameters
updateCongestionControlAndSendQueue([this, ack, &controlPacket] { updateCongestionControlAndSendQueue([this, ack, &controlPacket] {

View file

@ -481,6 +481,7 @@ bool SendQueue::isInactive(bool attemptedToSendPacket) {
auto cvStatus = _emptyCondition.wait_for(locker, EMPTY_QUEUES_INACTIVE_TIMEOUT); auto cvStatus = _emptyCondition.wait_for(locker, EMPTY_QUEUES_INACTIVE_TIMEOUT);
if (cvStatus == std::cv_status::timeout && (_packets.isEmpty() || isFlowWindowFull()) && _naks.isEmpty()) { if (cvStatus == std::cv_status::timeout && (_packets.isEmpty() || isFlowWindowFull()) && _naks.isEmpty()) {
#ifdef UDT_CONNECTION_DEBUG #ifdef UDT_CONNECTION_DEBUG
qCDebug(networking) << "SendQueue to" << _destination << "has been empty for" qCDebug(networking) << "SendQueue to" << _destination << "has been empty for"
<< EMPTY_QUEUES_INACTIVE_TIMEOUT.count() << EMPTY_QUEUES_INACTIVE_TIMEOUT.count()

View file

@ -27,16 +27,9 @@ TCPVegasCC::TCPVegasCC() {
_baseRTT = std::numeric_limits<int>::max(); _baseRTT = std::numeric_limits<int>::max();
} }
bool TCPVegasCC::onACK(SequenceNumber ack, p_high_resolution_clock::time_point receiveTime) { bool TCPVegasCC::calculateRTT(p_high_resolution_clock::time_point sendTime, p_high_resolution_clock::time_point receiveTime) {
auto it = _sentPacketTimes.find(ack);
auto previousAck = _lastACK;
_lastACK = ack;
if (it != _sentPacketTimes.end()) {
// calculate the RTT (receive time - time ACK sent) // calculate the RTT (receive time - time ACK sent)
int lastRTT = duration_cast<microseconds>(receiveTime - it->second).count(); int lastRTT = duration_cast<microseconds>(receiveTime - sendTime).count();
const int MAX_RTT_SAMPLE_MICROSECONDS = 10000000; const int MAX_RTT_SAMPLE_MICROSECONDS = 10000000;
@ -74,36 +67,84 @@ bool TCPVegasCC::onACK(SequenceNumber ack, p_high_resolution_clock::time_point r
+ abs(lastRTT - _ewmaRTT)) / RTT_ESTIMATION_VARIANCE_ALPHA; + abs(lastRTT - _ewmaRTT)) / RTT_ESTIMATION_VARIANCE_ALPHA;
} }
// add 1 to the number of ACKs during this RTT
++_numACKs;
// keep track of the lowest RTT during connection // keep track of the lowest RTT during connection
_baseRTT = std::min(_baseRTT, lastRTT); _baseRTT = std::min(_baseRTT, lastRTT);
// find the min RTT during the last RTT // find the min RTT during the last RTT
_currentMinRTT = std::min(_currentMinRTT, lastRTT); _currentMinRTT = std::min(_currentMinRTT, lastRTT);
// add 1 to the number of RTT samples collected during this RTT window
++_numRTTs;
return true;
}
bool TCPVegasCC::onACK(SequenceNumber ack, p_high_resolution_clock::time_point receiveTime) {
auto previousAck = _lastACK;
_lastACK = ack;
bool wasDuplicateACK = (ack == previousAck);
auto it = std::find_if(_sentPacketDatas.begin(), _sentPacketDatas.end(), [ack](SentPacketData& packetTime){
return packetTime.sequenceNumber == ack;
});
if (!wasDuplicateACK && it != _sentPacketDatas.end()) {
// check if we can unambigiously calculate an RTT from this ACK
// for that to be the case,
// any of the packets this ACK covers (from the current ACK back to our previous ACK)
// must not have been re-sent
bool canBeUsedForRTT = std::none_of(_sentPacketDatas.begin(), _sentPacketDatas.end(),
[ack, previousAck](SentPacketData& sentPacketData)
{
return sentPacketData.sequenceNumber > previousAck
&& sentPacketData.sequenceNumber <= ack
&& sentPacketData.wasResent;
});
auto sendTime = it->timePoint;
// remove all sent packet times up to this sequence number
it = _sentPacketDatas.erase(_sentPacketDatas.begin(), it + 1);
// if we can use this ACK for an RTT calculation then do so
// returning false if we calculate an invalid RTT
if (canBeUsedForRTT && !calculateRTT(sendTime, receiveTime)) {
return false;
}
}
auto sinceLastAdjustment = duration_cast<microseconds>(p_high_resolution_clock::now() - _lastAdjustmentTime).count(); auto sinceLastAdjustment = duration_cast<microseconds>(p_high_resolution_clock::now() - _lastAdjustmentTime).count();
if (sinceLastAdjustment >= _ewmaRTT) { if (sinceLastAdjustment >= _ewmaRTT) {
performCongestionAvoidance(ack); performCongestionAvoidance(ack);
} }
// remove this sent packet time from the hash
_sentPacketTimes.erase(it);
}
++_numACKSinceFastRetransmit; ++_numACKSinceFastRetransmit;
// perform the fast re-transmit check if this is a duplicate ACK or if this is the first or second ACK // perform the fast re-transmit check if this is a duplicate ACK or if this is the first or second ACK
// after a previous fast re-transmit // after a previous fast re-transmit
if (ack == previousAck || _numACKSinceFastRetransmit < 3) { if (wasDuplicateACK || _numACKSinceFastRetransmit < 3) {
return needsFastRetransmit(ack, wasDuplicateACK);
} else {
_duplicateACKCount = 0;
}
// ACK processed, no fast re-transmit required
return false;
}
bool TCPVegasCC::needsFastRetransmit(SequenceNumber ack, bool wasDuplicateACK) {
// we may need to re-send ackNum + 1 if it has been more than our estimated timeout since it was sent // we may need to re-send ackNum + 1 if it has been more than our estimated timeout since it was sent
auto it = _sentPacketTimes.find(ack + 1); auto nextIt = std::find_if(_sentPacketDatas.begin(), _sentPacketDatas.end(), [ack](SentPacketData& packetTime){
if (it != _sentPacketTimes.end()) { return packetTime.sequenceNumber == ack + 1;
});
if (nextIt != _sentPacketDatas.end()) {
auto now = p_high_resolution_clock::now(); auto now = p_high_resolution_clock::now();
auto sinceSend = duration_cast<microseconds>(now - it->second).count(); auto sinceSend = duration_cast<microseconds>(now - nextIt->timePoint).count();
if (sinceSend >= estimatedTimeout()) { if (sinceSend >= estimatedTimeout()) {
// break out of slow start, we've decided this is loss // break out of slow start, we've decided this is loss
@ -122,7 +163,7 @@ bool TCPVegasCC::onACK(SequenceNumber ack, p_high_resolution_clock::time_point r
++_duplicateACKCount; ++_duplicateACKCount;
if (ack == previousAck && _duplicateACKCount == RENO_FAST_RETRANSMIT_DUPLICATE_COUNT) { if (wasDuplicateACK && _duplicateACKCount == RENO_FAST_RETRANSMIT_DUPLICATE_COUNT) {
// break out of slow start, we just hit loss // break out of slow start, we just hit loss
_slowStart = false; _slowStart = false;
@ -133,11 +174,7 @@ bool TCPVegasCC::onACK(SequenceNumber ack, p_high_resolution_clock::time_point r
// return true so the caller knows we needed a fast re-transmit // return true so the caller knows we needed a fast re-transmit
return true; return true;
} }
} else {
_duplicateACKCount = 0;
}
// ACK processed, no fast re-transmit required
return false; return false;
} }
@ -158,7 +195,7 @@ void TCPVegasCC::performCongestionAvoidance(udt::SequenceNumber ack) {
int64_t windowSizeDiff = (int64_t) _congestionWindowSize * (rtt - _baseRTT) / _baseRTT; int64_t windowSizeDiff = (int64_t) _congestionWindowSize * (rtt - _baseRTT) / _baseRTT;
if (_numACKs <= 2) { if (_numRTTs <= 2) {
performRenoCongestionAvoidance(ack); performRenoCongestionAvoidance(ack);
} else { } else {
if (_slowStart) { if (_slowStart) {
@ -209,7 +246,7 @@ void TCPVegasCC::performCongestionAvoidance(udt::SequenceNumber ack) {
_currentMinRTT = std::numeric_limits<int>::max(); _currentMinRTT = std::numeric_limits<int>::max();
// reset our count of collected RTT samples // reset our count of collected RTT samples
_numACKs = 0; _numRTTs = 0;
} }
@ -230,29 +267,29 @@ void TCPVegasCC::performRenoCongestionAvoidance(SequenceNumber ack) {
return; return;
} }
int numAcked = _numACKs; int numRTTCollected = _numRTTs;
if (_slowStart) { if (_slowStart) {
// while in slow start we grow the congestion window by the number of ACKed packets // while in slow start we grow the congestion window by the number of ACKed packets
// allowing it to grow as high as the slow start threshold // allowing it to grow as high as the slow start threshold
int congestionWindow = _congestionWindowSize + numAcked; int congestionWindow = _congestionWindowSize + numRTTCollected;
if (congestionWindow > udt::MAX_PACKETS_IN_FLIGHT) { if (congestionWindow > udt::MAX_PACKETS_IN_FLIGHT) {
// we're done with slow start, set the congestion window to the slow start threshold // we're done with slow start, set the congestion window to the slow start threshold
_congestionWindowSize = udt::MAX_PACKETS_IN_FLIGHT; _congestionWindowSize = udt::MAX_PACKETS_IN_FLIGHT;
// figure out how many left over ACKs we should apply using the regular reno congestion avoidance // figure out how many left over ACKs we should apply using the regular reno congestion avoidance
numAcked = congestionWindow - udt::MAX_PACKETS_IN_FLIGHT; numRTTCollected = congestionWindow - udt::MAX_PACKETS_IN_FLIGHT;
} else { } else {
_congestionWindowSize = congestionWindow; _congestionWindowSize = congestionWindow;
numAcked = 0; numRTTCollected = 0;
} }
} }
// grab the size of the window prior to reno additive increase // grab the size of the window prior to reno additive increase
int preAIWindowSize = _congestionWindowSize; int preAIWindowSize = _congestionWindowSize;
if (numAcked > 0) { if (numRTTCollected > 0) {
// Once we are out of slow start, we use additive increase to grow the window slowly. // Once we are out of slow start, we use additive increase to grow the window slowly.
// We grow the congestion window by a single packet everytime the entire congestion window is sent. // We grow the congestion window by a single packet everytime the entire congestion window is sent.
@ -263,7 +300,7 @@ void TCPVegasCC::performRenoCongestionAvoidance(SequenceNumber ack) {
} }
// increase the window size by (1 / window size) for every ACK received // increase the window size by (1 / window size) for every ACK received
_ackAICount += numAcked; _ackAICount += numRTTCollected;
if (_ackAICount >= preAIWindowSize) { if (_ackAICount >= preAIWindowSize) {
// when _ackAICount % preAIWindowSize == 0 then _ackAICount is 0 // when _ackAICount % preAIWindowSize == 0 then _ackAICount is 0
// when _ackAICount % preAIWindowSize != 0 then _ackAICount is _ackAICount - (_ackAICount % preAIWindowSize) // when _ackAICount % preAIWindowSize != 0 then _ackAICount is _ackAICount - (_ackAICount % preAIWindowSize)
@ -277,8 +314,19 @@ void TCPVegasCC::performRenoCongestionAvoidance(SequenceNumber ack) {
} }
void TCPVegasCC::onPacketSent(int wireSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint) { void TCPVegasCC::onPacketSent(int wireSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint) {
if (_sentPacketTimes.find(seqNum) == _sentPacketTimes.end()) { _sentPacketDatas.emplace_back(seqNum, timePoint);
_sentPacketTimes[seqNum] = timePoint; }
void TCPVegasCC::onPacketReSent(int wireSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint) {
// look for our information for this sent packet
auto it = std::find_if(_sentPacketDatas.begin(), _sentPacketDatas.end(), [seqNum](SentPacketData& sentPacketInfo){
return sentPacketInfo.sequenceNumber == seqNum;
});
// if we found information for this packet (it hasn't been erased because it hasn't yet been ACKed)
// then mark it as re-sent so we know it cannot be used for RTT calculations
if (it != _sentPacketDatas.end()) {
it->wasResent = true;
} }
} }

View file

@ -30,6 +30,7 @@ public:
virtual void onTimeout() override {}; virtual void onTimeout() override {};
virtual void onPacketSent(int wireSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint) override; virtual void onPacketSent(int wireSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint) override;
virtual void onPacketReSent(int wireSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint) override;
virtual int estimatedTimeout() const override; virtual int estimatedTimeout() const override;
@ -37,11 +38,23 @@ protected:
virtual void performCongestionAvoidance(SequenceNumber ack); virtual void performCongestionAvoidance(SequenceNumber ack);
virtual void setInitialSendSequenceNumber(SequenceNumber seqNum) override { _lastACK = seqNum - 1; } virtual void setInitialSendSequenceNumber(SequenceNumber seqNum) override { _lastACK = seqNum - 1; }
private: private:
bool calculateRTT(p_high_resolution_clock::time_point sendTime, p_high_resolution_clock::time_point receiveTime);
bool needsFastRetransmit(SequenceNumber ack, bool wasDuplicateACK);
bool isCongestionWindowLimited(); bool isCongestionWindowLimited();
void performRenoCongestionAvoidance(SequenceNumber ack); void performRenoCongestionAvoidance(SequenceNumber ack);
using PacketTimeList = std::map<SequenceNumber, p_high_resolution_clock::time_point>; struct SentPacketData {
PacketTimeList _sentPacketTimes; // Map of sequence numbers to sent time SentPacketData(SequenceNumber seqNum, p_high_resolution_clock::time_point tPoint)
: sequenceNumber(seqNum), timePoint(tPoint) {};
SequenceNumber sequenceNumber;
p_high_resolution_clock::time_point timePoint;
bool wasResent { false };
};
using PacketTimeList = std::vector<SentPacketData>;
PacketTimeList _sentPacketDatas; // association of sequence numbers to sent time, for RTT calc
p_high_resolution_clock::time_point _lastAdjustmentTime; // Time of last congestion control adjustment p_high_resolution_clock::time_point _lastAdjustmentTime; // Time of last congestion control adjustment
@ -56,7 +69,7 @@ private:
int _ewmaRTT { -1 }; // Exponential weighted moving average RTT int _ewmaRTT { -1 }; // Exponential weighted moving average RTT
int _rttVariance { 0 }; // Variance in collected RTT values int _rttVariance { 0 }; // Variance in collected RTT values
int _numACKs { 0 }; // Number of ACKs received during the last RTT (since last performed congestion avoidance) int _numRTTs { 0 }; // Number of RTTs calculated during the last RTT (since last performed congestion avoidance)
int _ackAICount { 0 }; // Counter for number of ACKs received for Reno additive increase int _ackAICount { 0 }; // Counter for number of ACKs received for Reno additive increase
int _duplicateACKCount { 0 }; // Counter for duplicate ACKs received int _duplicateACKCount { 0 }; // Counter for duplicate ACKs received

View file

@ -74,11 +74,13 @@ void SpatiallyNestable::setParentID(const QUuid& parentID) {
} }
}); });
if (!_parentKnowsMe) {
bool success = false; bool success = false;
auto parent = getParentPointer(success); auto parent = getParentPointer(success);
if (success && parent) { if (success && parent) {
parent->updateQueryAACube(); parent->updateQueryAACube();
} }
}
} }
Transform SpatiallyNestable::getParentTransform(bool& success, int depth) const { Transform SpatiallyNestable::getParentTransform(bool& success, int depth) const {