From 4338f4e1d7c841ba447eb2d7481daaa009182bc7 Mon Sep 17 00:00:00 2001 From: Teravus Ovares (Dan Olivares) Date: Sun, 29 Nov 2009 05:06:25 -0500 Subject: * Patch from Misterblue to fix Environment.TickCount for statistics purposes. Resolves the wrap-around of the 32 bit uint. * Teravus moved the Environment methods to the Util class --- OpenSim/Framework/Util.cs | 26 ++++- .../Region/ClientStack/LindenUDP/LLUDPClient.cs | 5 +- OpenSim/Region/Framework/Scenes/Scene.cs | 118 ++++++++++----------- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 60 +++++++---- .../Region/Framework/Scenes/SimStatsReporter.cs | 5 +- 5 files changed, 132 insertions(+), 82 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 87ba5a8..a459f8d 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1389,6 +1389,30 @@ namespace OpenSim.Framework return null; } - #endregion FireAndForget Threading Pattern + #endregion FireAndForget Threading Pattern + /// + /// Environment.TickCount is an int but it counts all 32 bits so it goes positive + /// and negative every 24.9 days. This trims down TickCount so it doesn't wrap + /// for the callers. + /// This trims it to a 12 day interval so don't let your frame time get too long. + /// + /// + public static Int32 EnvironmentTickCount() + { + return Environment.TickCount & EnvironmentTickCountMask; + } + const Int32 EnvironmentTickCountMask = 0x3fffffff; + + /// + /// Environment.TickCount is an int but it counts all 32 bits so it goes positive + /// and negative every 24.9 days. Subtracts the passed value (previously fetched by + /// 'EnvironmentTickCount()') and accounts for any wrapping. + /// + /// subtraction of passed prevValue from current Environment.TickCount + public static Int32 EnvironmentTickCountSubtract(Int32 prevValue) + { + Int32 diff = EnvironmentTickCount() - prevValue; + return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1); + } } } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index 9856a1c..1e5f15a 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Threading; using log4net; using OpenSim.Framework; using OpenMetaverse; @@ -429,7 +430,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Send the packet m_udpServer.SendPacketFinal(nextPacket); m_nextPackets[i] = null; - packetSent = true; + packetSent = true; + this.PacketsSent++; } } else @@ -446,6 +448,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Send the packet m_udpServer.SendPacketFinal(packet); packetSent = true; + this.PacketsSent++; } else { diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index fbabb5c..a3f3d8f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -310,7 +310,7 @@ namespace OpenSim.Region.Framework.Scenes private Thread HeartbeatThread; private volatile bool shuttingdown; - private int m_lastUpdate = Environment.TickCount; + private int m_lastUpdate; private bool m_firstHeartbeat = true; private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; @@ -526,6 +526,7 @@ namespace OpenSim.Region.Framework.Scenes m_regionHandle = m_regInfo.RegionHandle; m_regionName = m_regInfo.RegionName; m_datastore = m_regInfo.DataStore; + m_lastUpdate = Util.EnvironmentTickCount(); m_physicalPrim = physicalPrim; m_seeIntoRegionFromNeighbor = SeeIntoRegionFromNeighbor; @@ -735,6 +736,8 @@ namespace OpenSim.Region.Framework.Scenes m_regInfo = regInfo; m_eventManager = new EventManager(); + + m_lastUpdate = Util.EnvironmentTickCount(); } #endregion @@ -1089,7 +1092,7 @@ namespace OpenSim.Region.Framework.Scenes HeartbeatThread.Abort(); HeartbeatThread = null; } - m_lastUpdate = Environment.TickCount; + m_lastUpdate = Util.EnvironmentTickCount(); HeartbeatThread = Watchdog.StartThread(Heartbeat, "Heartbeat for region " + RegionInfo.RegionName, ThreadPriority.Normal, false); } @@ -1130,7 +1133,7 @@ namespace OpenSim.Region.Framework.Scenes { Update(); - m_lastUpdate = Environment.TickCount; + m_lastUpdate = Util.EnvironmentTickCount(); m_firstHeartbeat = false; } catch (ThreadAbortException) @@ -1156,10 +1159,11 @@ namespace OpenSim.Region.Framework.Scenes while (!shuttingdown) { TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate; - physicsFPS = 0f; - - maintc = otherMS = Environment.TickCount; + physicsFPS = 0f; + + maintc = Util.EnvironmentTickCount(); int tmpFrameMS = maintc; + tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0; // Increment the frame counter ++m_frame; @@ -1179,74 +1183,65 @@ namespace OpenSim.Region.Framework.Scenes if (m_frame % m_update_presences == 0) m_sceneGraph.UpdatePresences(); - int TempPhysicsMS2 = Environment.TickCount; + int tmpPhysicsMS2 = Util.EnvironmentTickCount(); if ((m_frame % m_update_physics == 0) && m_physics_enabled) m_sceneGraph.UpdatePreparePhysics(); - TempPhysicsMS2 = Environment.TickCount - TempPhysicsMS2; - physicsMS2 = TempPhysicsMS2; + physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2); if (m_frame % m_update_entitymovement == 0) - m_sceneGraph.UpdateScenePresenceMovement(); - - int TempPhysicsMS = Environment.TickCount; + m_sceneGraph.UpdateScenePresenceMovement(); + + int tmpPhysicsMS = Util.EnvironmentTickCount(); if (m_frame % m_update_physics == 0) { if (m_physics_enabled) physicsFPS = m_sceneGraph.UpdatePhysics(Math.Max(SinceLastFrame.TotalSeconds, m_timespan)); if (SynchronizeScene != null) SynchronizeScene(this); - } - TempPhysicsMS = Environment.TickCount - TempPhysicsMS; - physicsMS = TempPhysicsMS; + } + physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS); // Delete temp-on-rez stuff if (m_frame % m_update_backup == 0) - { - int tozMS = Environment.TickCount; - CleanTempObjects(); - tozMS -= Environment.TickCount; - tempOnRezMS = tozMS; + { + int tmpTempOnRezMS = Util.EnvironmentTickCount(); + CleanTempObjects(); + tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS); } if (RegionStatus != RegionStatus.SlaveScene) { if (m_frame % m_update_events == 0) - { - int evMS = Environment.TickCount; - UpdateEvents(); - evMS -= Environment.TickCount; - eventMS = evMS; + { + int evMS = Util.EnvironmentTickCount(); + UpdateEvents(); + eventMS = Util.EnvironmentTickCountSubtract(evMS); ; } if (m_frame % m_update_backup == 0) - { - int backMS = Environment.TickCount; - UpdateStorageBackup(); - backMS -= Environment.TickCount; - backupMS = backMS; + { + int backMS = Util.EnvironmentTickCount(); + UpdateStorageBackup(); + backupMS = Util.EnvironmentTickCountSubtract(backMS); } if (m_frame % m_update_terrain == 0) - { - int terMS = Environment.TickCount; - UpdateTerrain(); - terMS -= Environment.TickCount; - terrainMS = terMS; + { + int terMS = Util.EnvironmentTickCount(); + UpdateTerrain(); + terrainMS = Util.EnvironmentTickCountSubtract(terMS); } if (m_frame % m_update_land == 0) - { - int ldMS = Environment.TickCount; - UpdateLand(); - ldMS -= Environment.TickCount; - landMS = ldMS; - } - - int tickCount = Environment.TickCount; - otherMS = tickCount - otherMS; - tmpFrameMS -= tickCount; - frameMS = tmpFrameMS; - lastCompletedFrame = tickCount; + { + int ldMS = Util.EnvironmentTickCount(); + UpdateLand(); + landMS = Util.EnvironmentTickCountSubtract(ldMS); + } + + frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS); + otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS; + lastCompletedFrame = Util.EnvironmentTickCount(); // if (m_frame%m_update_avatars == 0) // UpdateInWorldTime(); @@ -1298,9 +1293,9 @@ namespace OpenSim.Region.Framework.Scenes finally { m_lastupdate = DateTime.UtcNow; - } - - maintc = Environment.TickCount - maintc; + } + + maintc = Util.EnvironmentTickCountSubtract(maintc); maintc = (int)(m_timespan * 1000) - maintc; if ((maintc < (m_timespan * 1000)) && maintc > 0) @@ -1311,6 +1306,7 @@ namespace OpenSim.Region.Framework.Scenes } } + public void AddGroupTarget(SceneObjectGroup grp) { @@ -2585,9 +2581,9 @@ namespace OpenSim.Region.Framework.Scenes sp.IsChildAgent = false; Util.FireAndForget(delegate(object o) { sp.RezAttachments(); }); } - } - - m_LastLogin = Environment.TickCount; + } + + m_LastLogin = Util.EnvironmentTickCount(); EventManager.TriggerOnNewClient(client); } @@ -4654,16 +4650,16 @@ namespace OpenSim.Region.Framework.Scenes // 3 = We have seen a new user enter within the past 4 minutes // which can be seen as positive confirmation of sim health // - int health=1; // Start at 1, means we're up - - if ((Environment.TickCount - m_lastUpdate) < 1000) + int health=1; // Start at 1, means we're up + + if ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000) health+=1; else return health; // A login in the last 4 mins? We can't be doing too badly - // - if ((Environment.TickCount - m_LastLogin) < 240000) + // + if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000) health++; else return health; @@ -4859,9 +4855,9 @@ namespace OpenSim.Region.Framework.Scenes private void CheckHeartbeat() { if (m_firstHeartbeat) - return; - - if (System.Environment.TickCount - m_lastUpdate > 2000) + return; + + if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000) StartTimer(); } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 5604e3d..bcad335 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -755,13 +755,37 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendPrimUpdates() { - m_perfMonMS = Environment.TickCount; + m_perfMonMS = EnvironmentTickCount(); m_sceneViewer.SendPrimUpdates(); - m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); + m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); } + /// + /// Environment.TickCount is an int but it counts all 32 bits so it goes positive + /// and negative every 24.9 days. This trims down TickCount so it doesn't wrap + /// for the callers. + /// This trims it to a 12 day interval so don't let your frame time get too long. + /// + /// + const Int32 EnvironmentTickCountMask = 0x3fffffff; + private static Int32 EnvironmentTickCount() { + return Environment.TickCount & EnvironmentTickCountMask; + } + + /// + /// Environment.TickCount is an int but it counts all 32 bits so it goes positive + /// and negative every 24.9 days. Subtracts the passed value (previously fetched by + /// 'EnvironmentTickCount()') and accounts for any wrapping. + /// + /// subtraction of passed prevValue from current Environment.TickCount + private static Int32 EnvironmentTickCountSubtract(Int32 prevValue) { + Int32 diff = EnvironmentTickCount() - prevValue; + return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1); + } + + #region Status Methods /// @@ -1148,7 +1172,7 @@ namespace OpenSim.Region.Framework.Scenes // return; //} - m_perfMonMS = Environment.TickCount; + m_perfMonMS = EnvironmentTickCount(); ++m_movementUpdateCount; if (m_movementUpdateCount < 1) @@ -1464,7 +1488,7 @@ namespace OpenSim.Region.Framework.Scenes m_scene.EventManager.TriggerOnClientMovement(this); - m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); + m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); } public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) @@ -1924,7 +1948,7 @@ namespace OpenSim.Region.Framework.Scenes return; } - m_perfMonMS = Environment.TickCount; + m_perfMonMS = EnvironmentTickCount(); Rotation = rotation; Vector3 direc = vec * rotation; @@ -1966,7 +1990,7 @@ namespace OpenSim.Region.Framework.Scenes // TODO: Add the force instead of only setting it to support multiple forces per frame? m_forceToApply = direc; - m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); + m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); } #endregion @@ -2032,7 +2056,7 @@ namespace OpenSim.Region.Framework.Scenes // server. if (remoteClient.IsActive) { - m_perfMonMS = Environment.TickCount; + m_perfMonMS = EnvironmentTickCount(); PhysicsActor actor = m_physicsActor; Vector3 velocity = (actor != null) ? actor.Velocity : Vector3.Zero; @@ -2045,7 +2069,7 @@ namespace OpenSim.Region.Framework.Scenes remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, pos, velocity, Vector3.Zero, m_bodyRot, CollisionPlane, m_uuid, null, GetUpdatePriority(remoteClient))); - m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); + m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); m_scene.StatsReporter.AddAgentUpdates(1); } } @@ -2055,11 +2079,11 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendTerseUpdateToAllClients() { - m_perfMonMS = Environment.TickCount; + m_perfMonMS = EnvironmentTickCount(); m_scene.ForEachClient(SendTerseUpdateToClient); - m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); + m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); } public void SendCoarseLocations() @@ -2079,7 +2103,7 @@ namespace OpenSim.Region.Framework.Scenes public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p) { - m_perfMonMS = Environment.TickCount; + m_perfMonMS = EnvironmentTickCount(); List CoarseLocations = new List(); List AvatarUUIDs = new List(); @@ -2115,7 +2139,7 @@ namespace OpenSim.Region.Framework.Scenes m_controllingClient.SendCoarseLocationUpdate(AvatarUUIDs, CoarseLocations); - m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); + m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); } public void CoarseLocationChange() @@ -2152,7 +2176,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendInitialFullUpdateToAllClients() { - m_perfMonMS = Environment.TickCount; + m_perfMonMS = EnvironmentTickCount(); ScenePresence[] avatars = m_scene.GetScenePresences(); @@ -2178,14 +2202,14 @@ namespace OpenSim.Region.Framework.Scenes } m_scene.StatsReporter.AddAgentUpdates(avatars.Length); - m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); + m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); //Animator.SendAnimPack(); } public void SendFullUpdateToAllClients() { - m_perfMonMS = Environment.TickCount; + m_perfMonMS = EnvironmentTickCount(); // only send update from root agents to other clients; children are only "listening posts" List avatars = m_scene.GetAvatars(); @@ -2195,7 +2219,7 @@ namespace OpenSim.Region.Framework.Scenes } m_scene.StatsReporter.AddAgentUpdates(avatars.Count); - m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); + m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); Animator.SendAnimPack(); } @@ -2237,7 +2261,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendAppearanceToAllOtherAgents() { - m_perfMonMS = Environment.TickCount; + m_perfMonMS = EnvironmentTickCount(); m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) { @@ -2247,7 +2271,7 @@ namespace OpenSim.Region.Framework.Scenes } }); - m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); + m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); } /// diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs index 3b5455f..f92f440 100644 --- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs +++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs @@ -193,6 +193,9 @@ namespace OpenSim.Region.Framework.Scenes // / 10 divides the value by the number of times the sim heartbeat runs (10fps) // Then we divide the whole amount by the amount of seconds pass in between stats updates. + // 'statsUpdateFactor' is how often stats packets are sent in seconds. Used below to change + // values to X-per-second values. + for (int i = 0; i<21;i++) { sb[i] = new SimStatsPacket.StatBlock(); @@ -237,7 +240,7 @@ namespace OpenSim.Region.Framework.Scenes sb[12].StatID = (uint)Stats.OtherMS; sb[12].StatValue = m_otherMS / statsUpdateFactor; - sb[13].StatID = (uint)Stats.InPacketsPerSecond; + sb[13].StatID = (uint)Stats.InPacketsPerSecond; sb[13].StatValue = (m_inPacketsPerSecond / statsUpdateFactor); sb[14].StatID = (uint)Stats.OutPacketsPerSecond; -- cgit v1.1