[hxserver] CR: RDT RTT Probe interval

[hxserver] CR: RDT RTT Probe interval

Damon Lanphear damonlan at real.com
Thu Nov 20 18:13:24 PST 2003


Suggested 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


More information about the Helix-server-dev mailing list
 

Site Map   |   Terms of Use   |   Privacy Policy   |   Contact Us

Copyright © 1995-2007 RealNetworks, Inc. All rights reserved. RealNetworks and Helix are trademarks of RealNetworks.
All other trademarks or registered trademarks are the property of their respective holders.