[hxserver] CR: RDT RTT Probe interval
Damon Lanphear damonlan at real.comSuggested Reviewers:
Go
Tom
Problem:
Congestion control depends on regular feedback from the transport in
order to update state. In the RDT case, the rate of feedback was tied
to the rate of packet transmission. One feedback request was sent for
every N data packets. In cases where there is persistent congestion,
congestion control will reduce the rate dramatically. In such cases
feedback slows to a very low rate. The result is that recovery from a
congestion event takes a VERY long time.
Solution:
Request transport feedback in RDT for at precise regular intervals
throughout the entire duration of the session. A callback class is
introduced that handles the request for RDT RTT and buffer information.
This request is sent at a user configurable interval. The default is
250ms, or 4 times per second. The default rate introduces an overhead
of 224 bps, which is tunable by the user.
Further, transport information requests are only sent of MDP is enabled
for the session AND the RDT feature level is greater than or equal to 3.
Leak and functionality checked on Linux using a variety of RDT capable
clients and MDP configurations.
-------------- next part --------------
? server/protocol/transport/rdt/Makefile
? server/protocol/transport/rdt/Umakefil.upp
? server/protocol/transport/rdt/dbg
? server/protocol/transport/rdt/rel
Index: server/protocol/transport/rdt/rdttran.cpp
===================================================================
RCS file: /cvs/server/protocol/transport/rdt/rdttran.cpp,v
retrieving revision 1.30.2.1
diff -u -w -r1.30.2.1 rdttran.cpp
--- server/protocol/transport/rdt/rdttran.cpp 13 Nov 2003 20:46:26 -0000 1.30.2.1
+++ server/protocol/transport/rdt/rdttran.cpp 21 Nov 2003 00:49:22 -0000
@@ -101,7 +101,7 @@
#define PACKET_QUEUE_SIZE 12
#define RDT_RTT_GAIN 0.1
-#define RDT_DEFAULT_PKTS_PER_RTT_REQ 5
+#define RDT_DEFAULT_RTT_FREQ 250
#define RDT_DEFAULT_PKTS_PER_BUF_REQ 20
/*
@@ -125,6 +125,7 @@
m_ackTimeoutID(0),
m_pACKCallback(0),
m_pSeekCallback(0),
+ m_pTransportInfoCallback (NULL),
m_pBwMgrInput(0),
m_ulAggregateTo (0),
m_ulAggregateHighest (0),
@@ -148,14 +149,13 @@
m_pSource(0),
m_ulBandwidth(0),
m_ulFeatureLevel (ulFeatureLevel),
- m_ulPktCount (0),
m_pSignalBus (NULL),
m_pQoSInfo (NULL),
m_pSessionId (NULL),
m_fRTT (0),
- m_ulPktsPerRTTRequest (RDT_DEFAULT_PKTS_PER_RTT_REQ),
- m_ulPktsPerBufferRequest (RDT_DEFAULT_PKTS_PER_BUF_REQ),
- m_bDone(FALSE)
+ m_bDone(FALSE),
+ m_bFirstPacket (FALSE),
+ m_ulRTTProbeFrequency (RDT_DEFAULT_RTT_FREQ)
{
m_wrapSequenceNumber = TNG_WRAP_SEQ_NO;
@@ -250,6 +250,13 @@
m_pScheduler->Remove(m_pSeekCallback->m_Handle);
}
+ if (m_pTransportInfoCallback)
+ {
+ m_pTransportInfoCallback->Stop();
+ m_pTransportInfoCallback->Release();
+ m_pTransportInfoCallback = NULL;
+ }
+
HX_RELEASE(m_pPacketFilter);
HX_RELEASE(m_pSeekCallback);
@@ -458,27 +465,25 @@
}
- /* Configure congestion control: */
HX_VERIFY(SUCCEEDED(m_pSignalBus->QueryInterface(IID_IHXQoSProfileConfigurator,
(void**)&pConfig)));
- if (SUCCEEDED(pConfig->GetConfigInt(QOS_CFG_TRAN_RDT_RTT, lTemp)))
- {
- m_ulPktsPerRTTRequest = (UINT32)lTemp;
- }
- else
+ /* Only probe for RTT if MDP is active: */
+ if ((SUCCEEDED(pConfig->GetConfigInt(QOS_CFG_MDP, lTemp))) &&
+ (lTemp != 0) &&
+ (m_ulFeatureLevel >= 3))
{
- m_ulPktsPerRTTRequest = RDT_DEFAULT_PKTS_PER_RTT_REQ;
- }
+ m_pTransportInfoCallback = new TransportInfoCallback (this);
+ m_pTransportInfoCallback->AddRef();
- lTemp = 0;
- if (SUCCEEDED(pConfig->GetConfigInt(QOS_CFG_TRAN_RDT_BUFF, lTemp)))
+ if (SUCCEEDED(pConfig->GetConfigInt(QOS_CFG_TRAN_RDT_RTT, lTemp)))
{
- m_ulPktsPerBufferRequest = (UINT32)lTemp;
+ m_ulRTTProbeFrequency = (UINT32)lTemp;
}
else
{
- m_ulPktsPerBufferRequest = RDT_DEFAULT_PKTS_PER_BUF_REQ;
+ m_ulRTTProbeFrequency = RDT_DEFAULT_RTT_FREQ;
+ }
}
HX_RELEASE(pConfig);
@@ -630,6 +635,16 @@
return HXR_OK;
}
+ if (!m_bFirstPacket)
+ {
+ m_bFirstPacket = TRUE;
+
+ if (m_pTransportInfoCallback)
+ {
+ m_pTransportInfoCallback->Start(m_ulRTTProbeFrequency);
+ }
+ }
+
// TimeStamp delivered sources don't currently support BackToBack pkts
if (!pPacket->IsTSD())
{
@@ -986,22 +1001,6 @@
packet = new BYTE[pkt.static_size() + pBuffer->GetSize()];
}
}
- else
- {
- RDTTransportInfoRequestPacket req;
- if(createInfoRequestPacket(&req))
- {
- packet = new BYTE[req.static_size() + pkt.static_size() + pBuffer->GetSize()];
- /*
- * report_offset gets set in pack.
- */
- req.pack(packet, report_offset);
- }
- else
- {
- packet = new BYTE[pkt.static_size() + pBuffer->GetSize()];
- }
- }
UINT32 packetLen = 0;
@@ -1228,22 +1227,6 @@
packet = new BYTE[pkt.static_size() + pBuffer->GetSize()];
}
}
- else
- {
- RDTTransportInfoRequestPacket req;
- if(createInfoRequestPacket(&req))
- {
- packet = new BYTE[req.static_size() + pkt.static_size() + pBuffer->GetSize()];
- /*
- * report_offset gets set in pack.
- */
- req.pack(packet, report_offset);
- }
- else
- {
- packet = new BYTE[pkt.static_size() + pBuffer->GetSize()];
- }
- }
UINT32 packetLen = 0;
@@ -1462,16 +1445,6 @@
rpt.pack(packet, report_offset);
}
}
- else
- {
- if(createInfoRequestPacket(&req))
- {
- /*
- * report_offset gets set in pack.
- */
- req.pack(packet, report_offset);
- }
- }
UINT32 packetLen = 0;
@@ -1708,16 +1681,7 @@
rpt.pack(packet, report_offset);
}
}
- else
- {
- if(createInfoRequestPacket(&req))
- {
- /*
- * report_offset gets set in pack.
- */
- req.pack(packet, report_offset);
- }
- }
+
UINT32 packetLen = 0;
/* pWriteHere indicates that we are aggregating */
@@ -2048,47 +2012,6 @@
m_ulLatencyReportPeriod = ulMs;
}
-
-BOOL
-TNGUDPTransport::createInfoRequestPacket(RDTTransportInfoRequestPacket* pReq)
-{
- HX_ASSERT(m_ulFeatureLevel >= 3);
-
- m_ulPktCount++;
- BOOL bReqRTT = (m_ulPktCount % m_ulPktsPerRTTRequest) ? FALSE : TRUE;
- BOOL bReqBuf = (m_ulPktCount % m_ulPktsPerBufferRequest) ? FALSE : TRUE;
-
- if ((!bReqRTT) && (!bReqBuf))
- {
- return FALSE;
- }
-
- pReq->packet_type = 0xff09;
- pReq->request_rtt_info = bReqRTT;
- pReq->request_buffer_info = bReqBuf;
-
- if (bReqRTT)
- {
- UINT32 now = 0;
-
- if (m_pAccurateClock)
- {
- HXTimeval tv = m_pAccurateClock->GetTimeOfDay();
- now = tv.tv_usec / 1000 + tv.tv_sec * 1000;
- }
- else
- {
- Timeval tv;
- (void)gettimeofday(&tv, 0);
- now = tv.tv_usec / 1000 + tv.tv_sec * 1000;
- }
-
- pReq->request_time_ms = now;
- }
-
- return TRUE;
-}
-
HX_RESULT
TNGUDPTransport::handleTransportInfoReqPacket(IHXBuffer* pBuffer, UINT32* pPos,
UINT32* pLen, UINT32 ulTime)
@@ -3995,6 +3918,149 @@
m_bDone = TRUE;
return HXR_OK;
+}
+
+/*
+ * TransportInfoCallback methods
+ */
+
+TNGUDPTransport::TransportInfoCallback::TransportInfoCallback(TNGUDPTransport* pTransport)
+ : m_pTransport(pTransport)
+ , m_lRefCount (0)
+ , m_ulFrequency(0)
+ , m_Handle (0)
+{
+ HX_ASSERT(m_pTransport);
+ HX_ASSERT(m_pTransport->m_pScheduler);
+
+ if(m_pTransport)
+ {
+ m_pTransport->AddRef();
+ }
+
+ if (m_pTransport->m_pScheduler)
+ {
+ m_pScheduler = m_pTransport->m_pScheduler;
+ m_pScheduler->AddRef();
+ }
+}
+
+TNGUDPTransport::TransportInfoCallback::~TransportInfoCallback()
+{
+ Stop();
+}
+
+void
+TNGUDPTransport::TransportInfoCallback::Start(UINT32 ulFrequency)
+{
+ HX_ASSERT(m_pScheduler);
+
+ if (!m_pScheduler)
+ {
+ return;
+ }
+
+ if (m_Handle)
+ {
+ m_pScheduler->Remove(m_Handle);
+ m_Handle = 0;
+ }
+
+ m_ulFrequency = ulFrequency;
+ m_Handle = m_pScheduler->RelativeEnter((IHXCallback*)this, m_ulFrequency);
+}
+
+void
+TNGUDPTransport::TransportInfoCallback::Stop()
+{
+ if (m_Handle && m_pScheduler)
+ {
+ m_pScheduler->Remove(m_Handle);
+ m_Handle = 0;
+ }
+
+ HX_RELEASE(m_pScheduler);
+ HX_RELEASE(m_pTransport);
+}
+
+STDMETHODIMP
+TNGUDPTransport::TransportInfoCallback::Func()
+{
+ m_Handle = 0;
+
+ HX_ASSERT(m_pTransport);
+ if (!m_pTransport)
+ {
+ return HXR_OK;
+ }
+
+ RDTTransportInfoRequestPacket req;
+ BYTE* packet = new BYTE[req.static_size()];
+ UINT32 packetLen = 0;
+
+ req.packet_type = 0xff09;
+ req.request_rtt_info = 1;
+ req.request_buffer_info = 1;
+
+ UINT32 now = 0;
+
+ if (m_pTransport->m_pAccurateClock)
+ {
+ HXTimeval tv = m_pTransport->m_pAccurateClock->GetTimeOfDay();
+ now = tv.tv_usec / 1000 + tv.tv_sec * 1000;
+ }
+ else
+ {
+ Timeval tv;
+ (void)gettimeofday(&tv, 0);
+ now = tv.tv_usec / 1000 + tv.tv_sec * 1000;
+ }
+
+ req.request_time_ms = now;
+ req.pack(packet, packetLen);
+ // writePacket now owns 'packet', no need to free it in here
+ m_pTransport->writePacket(packet, packetLen);
+
+ m_Handle = m_pScheduler->RelativeEnter((IHXCallback*)this, m_ulFrequency);
+
+ return HXR_OK;
+}
+
+STDMETHODIMP
+TNGUDPTransport::TransportInfoCallback::QueryInterface(REFIID riid, void** ppvObj)
+{
+ if (IsEqualIID(riid, IID_IUnknown))
+ {
+ AddRef();
+ *ppvObj = this;
+ return HXR_OK;
+ }
+ else if (IsEqualIID(riid, IID_IHXCallback))
+ {
+ AddRef();
+ *ppvObj = (IHXCallback*)this;
+ return HXR_OK;
+ }
+ *ppvObj = NULL;
+ return HXR_NOINTERFACE;
+}
+
+STDMETHODIMP_(ULONG32)
+TNGUDPTransport::TransportInfoCallback::AddRef()
+{
+ return InterlockedIncrement(&m_lRefCount);
+}
+
+STDMETHODIMP_(ULONG32)
+TNGUDPTransport::TransportInfoCallback::Release()
+{
+ if (InterlockedDecrement(&m_lRefCount) > 0)
+ {
+ return m_lRefCount;
+ }
+
+ delete this;
+ return 0;
}
/*
Index: server/protocol/transport/rdt/pub/rdttran.h
===================================================================
RCS file: /cvs/server/protocol/transport/rdt/pub/rdttran.h,v
retrieving revision 1.13
diff -u -w -r1.13 rdttran.h
--- server/protocol/transport/rdt/pub/rdttran.h 16 Oct 2003 00:16:52 -0000 1.13
+++ server/protocol/transport/rdt/pub/rdttran.h 21 Nov 2003 00:49:23 -0000
@@ -249,6 +249,42 @@
};
friend class SeekCallback;
+ class TransportInfoCallback : public IHXCallback
+ {
+ public:
+ TransportInfoCallback (TNGUDPTransport* pTransport);
+
+ ~TransportInfoCallback ();
+
+ /*
+ * IUnknown methods
+ */
+ STDMETHOD(QueryInterface) (THIS_
+ REFIID riid,
+ void** ppvObj);
+
+ STDMETHOD_(ULONG32,AddRef) (THIS);
+
+ STDMETHOD_(ULONG32,Release) (THIS);
+
+ /*
+ * IHXCallback methods
+ */
+ STDMETHOD(Func) (THIS);
+
+ void Start(UINT32 ulFrequency);
+ void Stop();
+
+ private:
+ friend class TNGUDPTransport;
+ TNGUDPTransport* m_pTransport;
+ IHXScheduler* m_pScheduler;
+ LONG32 m_lRefCount;
+ CallbackHandle m_Handle;
+ UINT32 m_ulFrequency;
+ };
+ friend class TransportInfoCallback;
+
class UDPOutputCallback : public IHXCallback
{
public:
@@ -309,7 +345,6 @@
UINT32 m_ulATime;
} BwDetectionData;
- BOOL createInfoRequestPacket(RDTTransportInfoRequestPacket* pReq);
BOOL createLatencyReportPacket(TNGLatencyReportPacket* pRpt);
void startScheduler ();
HX_RESULT sendACKPacket ();
@@ -356,6 +391,7 @@
CallbackHandle m_ackTimeoutID;
ACKCallback* m_pACKCallback;
SeekCallback* m_pSeekCallback;
+ TransportInfoCallback* m_pTransportInfoCallback;
BOOL m_bCallbackPending;
#ifdef DEBUG
BOOL m_drop_packets;
@@ -388,9 +424,7 @@
ServerPacket** m_pPacketQueue;
UINT32 m_ulBandwidth;
UINT32 m_ulFeatureLevel;
- UINT32 m_ulPktCount;
- UINT32 m_ulPktsPerRTTRequest;
- UINT32 m_ulPktsPerBufferRequest;
+ UINT32 m_ulRTTProbeFrequency;
/* Media Delivery Pipeline: */
double m_fRTT;
@@ -399,6 +433,7 @@
IHXQoSTransportAdaptationInfo* m_pQoSInfo;
IHXBuffer* m_pSessionId;
BOOL m_bDone;
+ BOOL m_bFirstPacket;
};
inline IHXUDPSocket*
? server/qos/core/Makefile
? server/qos/core/Umakefil.upp
? server/qos/core/dbg
? server/qos/core/rel
? server/qos/session/Makefile
? server/qos/session/Umakefil.upp
? server/qos/session/dbg
? server/qos/session/rel
? server/qos/transport/Makefile
? server/qos/transport/Umakefil.upp
? server/qos/transport/dbg
? server/qos/transport/rel
Index: server/qos/core/pub/qos_cfg_names.h
===================================================================
RCS file: /cvs/server/qos/core/pub/qos_cfg_names.h,v
retrieving revision 1.16
diff -u -w -r1.16 qos_cfg_names.h
--- server/qos/core/pub/qos_cfg_names.h 31 Oct 2003 01:21:54 -0000 1.16
+++ server/qos/core/pub/qos_cfg_names.h 21 Nov 2003 00:51:52 -0000
@@ -51,7 +51,7 @@
#define QOS_CFG_TRAN_RS_RATIO "Transport.RtcpRSratio" /* % * 10000*/
/* Transport.RDT: */
-#define QOS_CFG_TRAN_RDT_RTT "Transport.RDT.RTTPacketRatio" /* packets */
+#define QOS_CFG_TRAN_RDT_RTT "Transport.RDT.RTTProbeFrequency" /* msec */
#define QOS_CFG_TRAN_RDT_BUFF "Transport.RDT.BufferInfoRatio" /* packets */
/* Transport.CongestionControl: */
-------------- next part --------------
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe at helix-server.helixcommunity.org
For additional commands, e-mail: dev-help at helix-server.helixcommunity.org