diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | 61 |
1 files changed, 50 insertions, 11 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs index fc9406b..2a3d14f 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | |||
@@ -31,6 +31,7 @@ using System.Reflection; | |||
31 | using OpenMetaverse; | 31 | using OpenMetaverse; |
32 | using OpenMetaverse.Packets; | 32 | using OpenMetaverse.Packets; |
33 | using log4net; | 33 | using log4net; |
34 | using OpenSim.Framework.Monitoring; | ||
34 | 35 | ||
35 | namespace OpenSim.Region.ClientStack.LindenUDP | 36 | namespace OpenSim.Region.ClientStack.LindenUDP |
36 | { | 37 | { |
@@ -43,17 +44,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
43 | private bool packetPoolEnabled = true; | 44 | private bool packetPoolEnabled = true; |
44 | private bool dataBlockPoolEnabled = true; | 45 | private bool dataBlockPoolEnabled = true; |
45 | 46 | ||
47 | private PercentageStat m_packetsReusedStat = new PercentageStat( | ||
48 | "PacketsReused", | ||
49 | "Packets reused", | ||
50 | "clientstack", | ||
51 | "packetpool", | ||
52 | StatVerbosity.Debug, | ||
53 | "Number of packets reused out of all requests to the packet pool"); | ||
54 | |||
55 | private PercentageStat m_blocksReusedStat = new PercentageStat( | ||
56 | "BlocksReused", | ||
57 | "Blocks reused", | ||
58 | "clientstack", | ||
59 | "packetpool", | ||
60 | StatVerbosity.Debug, | ||
61 | "Number of data blocks reused out of all requests to the packet pool"); | ||
62 | |||
46 | /// <summary> | 63 | /// <summary> |
47 | /// Pool of packets available for reuse. | 64 | /// Pool of packets available for reuse. |
48 | /// </summary> | 65 | /// </summary> |
49 | private readonly Dictionary<PacketType, Stack<Packet>> pool = new Dictionary<PacketType, Stack<Packet>>(); | 66 | private readonly Dictionary<PacketType, Stack<Packet>> pool = new Dictionary<PacketType, Stack<Packet>>(); |
50 | 67 | ||
51 | private static Dictionary<Type, Stack<Object>> DataBlocks = | 68 | private static Dictionary<Type, Stack<Object>> DataBlocks = new Dictionary<Type, Stack<Object>>(); |
52 | new Dictionary<Type, Stack<Object>>(); | ||
53 | |||
54 | static PacketPool() | ||
55 | { | ||
56 | } | ||
57 | 69 | ||
58 | public static PacketPool Instance | 70 | public static PacketPool Instance |
59 | { | 71 | { |
@@ -72,8 +84,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
72 | get { return dataBlockPoolEnabled; } | 84 | get { return dataBlockPoolEnabled; } |
73 | } | 85 | } |
74 | 86 | ||
87 | private PacketPool() | ||
88 | { | ||
89 | StatsManager.RegisterStat(m_packetsReusedStat); | ||
90 | StatsManager.RegisterStat(m_blocksReusedStat); | ||
91 | } | ||
92 | |||
93 | /// <summary> | ||
94 | /// Gets a packet of the given type. | ||
95 | /// </summary> | ||
96 | /// <param name='type'></param> | ||
97 | /// <returns>Guaranteed to always return a packet, whether from the pool or newly constructed.</returns> | ||
75 | public Packet GetPacket(PacketType type) | 98 | public Packet GetPacket(PacketType type) |
76 | { | 99 | { |
100 | m_packetsReusedStat.Consequent++; | ||
101 | |||
77 | Packet packet; | 102 | Packet packet; |
78 | 103 | ||
79 | if (!packetPoolEnabled) | 104 | if (!packetPoolEnabled) |
@@ -83,13 +108,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
83 | { | 108 | { |
84 | if (!pool.ContainsKey(type) || pool[type] == null || (pool[type]).Count == 0) | 109 | if (!pool.ContainsKey(type) || pool[type] == null || (pool[type]).Count == 0) |
85 | { | 110 | { |
111 | // m_log.DebugFormat("[PACKETPOOL]: Building {0} packet", type); | ||
112 | |||
86 | // Creating a new packet if we cannot reuse an old package | 113 | // Creating a new packet if we cannot reuse an old package |
87 | packet = Packet.BuildPacket(type); | 114 | packet = Packet.BuildPacket(type); |
88 | } | 115 | } |
89 | else | 116 | else |
90 | { | 117 | { |
118 | // m_log.DebugFormat("[PACKETPOOL]: Pulling {0} packet", type); | ||
119 | |||
91 | // Recycle old packages | 120 | // Recycle old packages |
92 | packet = (pool[type]).Pop(); | 121 | m_packetsReusedStat.Antecedent++; |
122 | |||
123 | packet = pool[type].Pop(); | ||
93 | } | 124 | } |
94 | } | 125 | } |
95 | 126 | ||
@@ -138,7 +169,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
138 | { | 169 | { |
139 | PacketType type = GetType(bytes); | 170 | PacketType type = GetType(bytes); |
140 | 171 | ||
141 | Array.Clear(zeroBuffer, 0, zeroBuffer.Length); | 172 | // Array.Clear(zeroBuffer, 0, zeroBuffer.Length); |
142 | 173 | ||
143 | int i = 0; | 174 | int i = 0; |
144 | Packet packet = GetPacket(type); | 175 | Packet packet = GetPacket(type); |
@@ -185,6 +216,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
185 | switch (packet.Type) | 216 | switch (packet.Type) |
186 | { | 217 | { |
187 | // List pooling packets here | 218 | // List pooling packets here |
219 | case PacketType.AgentUpdate: | ||
188 | case PacketType.PacketAck: | 220 | case PacketType.PacketAck: |
189 | case PacketType.ObjectUpdate: | 221 | case PacketType.ObjectUpdate: |
190 | case PacketType.ImprovedTerseObjectUpdate: | 222 | case PacketType.ImprovedTerseObjectUpdate: |
@@ -199,7 +231,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
199 | 231 | ||
200 | if ((pool[type]).Count < 50) | 232 | if ((pool[type]).Count < 50) |
201 | { | 233 | { |
202 | (pool[type]).Push(packet); | 234 | // m_log.DebugFormat("[PACKETPOOL]: Pushing {0} packet", type); |
235 | |||
236 | pool[type].Push(packet); | ||
203 | } | 237 | } |
204 | } | 238 | } |
205 | break; | 239 | break; |
@@ -211,16 +245,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
211 | } | 245 | } |
212 | } | 246 | } |
213 | 247 | ||
214 | public static T GetDataBlock<T>() where T: new() | 248 | public T GetDataBlock<T>() where T: new() |
215 | { | 249 | { |
216 | lock (DataBlocks) | 250 | lock (DataBlocks) |
217 | { | 251 | { |
252 | m_blocksReusedStat.Consequent++; | ||
253 | |||
218 | Stack<Object> s; | 254 | Stack<Object> s; |
219 | 255 | ||
220 | if (DataBlocks.TryGetValue(typeof(T), out s)) | 256 | if (DataBlocks.TryGetValue(typeof(T), out s)) |
221 | { | 257 | { |
222 | if (s.Count > 0) | 258 | if (s.Count > 0) |
259 | { | ||
260 | m_blocksReusedStat.Antecedent++; | ||
223 | return (T)s.Pop(); | 261 | return (T)s.Pop(); |
262 | } | ||
224 | } | 263 | } |
225 | else | 264 | else |
226 | { | 265 | { |
@@ -231,7 +270,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
231 | } | 270 | } |
232 | } | 271 | } |
233 | 272 | ||
234 | public static void ReturnDataBlock<T>(T block) where T: new() | 273 | public void ReturnDataBlock<T>(T block) where T: new() |
235 | { | 274 | { |
236 | if (block == null) | 275 | if (block == null) |
237 | return; | 276 | return; |