From bf517899a7a63278d4ed22d5485c37d61d47bb58 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 22 Jul 2013 23:30:09 +0100
Subject: Add AverageUDPProcessTime stat to try and get a handle on how long
we're taking on the initial processing of a UDP packet.
If we're not receiving packets with multiple threads (m_asyncPacketHandling) then this is critical since it will limit the number of incoming UDP requests that the region can handle and affects packet loss.
If m_asyncPacketHandling then this is less critical though a long process will increase the scope for threads to race.
This is an experimental stat which may be changed.
---
.../ClientStack/Linden/UDP/OpenSimUDPBase.cs | 39 ++++++++++++++++++++++
1 file changed, 39 insertions(+)
(limited to 'OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index a919141..46a3261 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -78,6 +78,26 @@ namespace OpenMetaverse
public bool IsRunningOutbound { get; private set; }
///
+ /// Number of receives over which to establish a receive time average.
+ ///
+ private readonly static int s_receiveTimeSamples = 500;
+
+ ///
+ /// Current number of samples taken to establish a receive time average.
+ ///
+ private int m_currentReceiveTimeSamples;
+
+ ///
+ /// Cumulative receive time for the sample so far.
+ ///
+ private int m_receiveTicksInCurrentSamplePeriod;
+
+ ///
+ /// The average time taken for each require receive in the last sample.
+ ///
+ public float AverageReceiveTicksForLastSamplePeriod { get; private set; }
+
+ ///
/// Default constructor
///
/// Local IP address to bind the server to
@@ -286,6 +306,8 @@ namespace OpenMetaverse
try
{
+ int startTick = Util.EnvironmentTickCount();
+
// get the length of data actually read from the socket, store it with the
// buffer
buffer.DataLength = m_udpSocket.EndReceiveFrom(iar, ref buffer.RemoteEndPoint);
@@ -293,6 +315,23 @@ namespace OpenMetaverse
// call the abstract method PacketReceived(), passing the buffer that
// has just been filled from the socket read.
PacketReceived(buffer);
+
+ // If more than one thread can be calling AsyncEndReceive() at once (e.g. if m_asyncPacketHandler)
+ // then a particular stat may be inaccurate due to a race condition. We won't worry about this
+ // since this should be rare and won't cause a runtime problem.
+ if (m_currentReceiveTimeSamples >= s_receiveTimeSamples)
+ {
+ AverageReceiveTicksForLastSamplePeriod
+ = (float)m_receiveTicksInCurrentSamplePeriod / s_receiveTimeSamples;
+
+ m_receiveTicksInCurrentSamplePeriod = 0;
+ m_currentReceiveTimeSamples = 0;
+ }
+ else
+ {
+ m_receiveTicksInCurrentSamplePeriod += Util.EnvironmentTickCountSubtract(startTick);
+ m_currentReceiveTimeSamples++;
+ }
}
catch (SocketException) { }
catch (ObjectDisposedException) { }
--
cgit v1.1