diff --git a/Scripts/Commands/Handlers.cs b/Scripts/Commands/Handlers.cs index 88d052f72..8ebb0bff4 100644 --- a/Scripts/Commands/Handlers.cs +++ b/Scripts/Commands/Handlers.cs @@ -17,6 +17,7 @@ using Server.Targeting; using Server.Targets; using Server.Gumps; using Server.Commands.Generic; +using Server.Diagnostics; namespace Server.Commands { @@ -75,8 +76,7 @@ namespace Server.Commands Register( "ProfileWorld", AccessLevel.Administrator, new CommandEventHandler( ProfileWorld_OnCommand ) ); Register( "TraceInternal", AccessLevel.Administrator, new CommandEventHandler( TraceInternal_OnCommand ) ); Register( "TraceExpanded", AccessLevel.Administrator, new CommandEventHandler( TraceExpanded_OnCommand ) ); - Register( "PacketProfiles", AccessLevel.Administrator, new CommandEventHandler( PacketProfiles_OnCommand ) ); - Register( "TimerProfiles", AccessLevel.Administrator, new CommandEventHandler( TimerProfiles_OnCommand ) ); + Register( "WriteProfiles", AccessLevel.Administrator, new CommandEventHandler( WriteProfiles_OnCommand ) ); Register( "SetProfiles", AccessLevel.Administrator, new CommandEventHandler( SetProfiles_OnCommand ) ); Register( "Light", AccessLevel.Counselor, new CommandEventHandler( Light_OnCommand ) ); @@ -447,84 +447,35 @@ namespace Server.Commands } } - [Usage( "PacketProfiles" )] - [Description( "Generates a log file containing performance information pertaining to networking data packets." )] - public static void PacketProfiles_OnCommand( CommandEventArgs e ) + [Usage( "WriteProfiles" )] + [Description( "Generates a log files containing performance diagnostic information." )] + public static void WriteProfiles_OnCommand( CommandEventArgs e ) { try { - using ( StreamWriter sw = new StreamWriter( "packetprofiles.log", true ) ) + using ( StreamWriter sw = new StreamWriter( "profiles.log", true ) ) { sw.WriteLine( "# Dump on {0:f}", DateTime.Now ); sw.WriteLine( "# Core profiling for " + Core.ProfileTime ); - PacketProfile[] profiles = PacketProfile.OutgoingProfiles; - - int totalSeconds = (int) Core.ProfileTime.TotalSeconds; - - if ( totalSeconds < 1 ) - totalSeconds = 1; - - sw.WriteLine(); - sw.WriteLine( "# Outgoing:" ); - - for ( int i = 0; i < profiles.Length; ++i ) - { - PacketProfile prof = profiles[i]; - - if ( prof == null ) - continue; - - sw.WriteLine( "0x{0,-10:X2} {6,10} {1,-10} {2,10} {3,-10:F2} {4,10:F5} {5,-10:F5} {7,10} {8,-10} {9,10} {10,10:F5} {11:F5}", i, prof.Count, prof.TotalByteLength, prof.AverageByteLength, prof.TotalProcTime.TotalSeconds, prof.AverageProcTime.TotalSeconds, prof.Constructed, prof.Constructed / totalSeconds, prof.Count / totalSeconds, prof.TotalByteLength / totalSeconds, prof.TotalProcTime.TotalSeconds / totalSeconds, prof.PeakProcTime.TotalSeconds ); - } - - profiles = PacketProfile.IncomingProfiles; - - sw.WriteLine(); - sw.WriteLine( "# Incoming:" ); - - for ( int i = 0; i < profiles.Length; ++i ) - { - PacketProfile prof = profiles[i]; - - if ( prof == null ) - continue; - - sw.WriteLine( "0x{0,-10:X2} {1,-10} {2,10} {3,-10:F2} {4,10:F5} {5:F5} {6:F5}", i, prof.Count, prof.TotalByteLength, prof.AverageByteLength, prof.TotalProcTime.TotalSeconds, prof.AverageProcTime.TotalSeconds, prof.PeakProcTime.TotalSeconds ); - } - - sw.WriteLine(); - sw.WriteLine(); - } - } - catch - { - } - } - - [Usage( "TimerProfiles" )] - [Description( "Generates a log file containing performance information pertaining to timers." )] - public static void TimerProfiles_OnCommand( CommandEventArgs e ) - { - try - { - using ( StreamWriter sw = new StreamWriter( "timerprofiles.log", true ) ) - { - Dictionary profiles = Timer.Profiles; - - sw.WriteLine( "# Dump on {0:f}", DateTime.Now ); - sw.WriteLine( "# Core profiling for " + Core.ProfileTime ); + sw.WriteLine( "# Packet send" ); + BaseProfile.WriteAll( sw, PacketSendProfile.Profiles ); sw.WriteLine(); - foreach ( KeyValuePair kvp in profiles ) - { - string name = kvp.Key; - TimerProfile prof = kvp.Value; - - sw.WriteLine( "{6,-100}{0,-12}{1,12} {2,-12}{3,12} {4,-12:F5}{5:F5} {7:F5}", prof.Created, prof.Started, prof.Stopped, prof.Ticked, prof.TotalProcTime.TotalSeconds, prof.AverageProcTime.TotalSeconds, name, prof.PeakProcTime.TotalSeconds ); - } - + sw.WriteLine( "# Packet receive" ); + BaseProfile.WriteAll( sw, PacketReceiveProfile.Profiles ); sw.WriteLine(); + + sw.WriteLine( "# Timer" ); + BaseProfile.WriteAll( sw, TimerProfile.Profiles ); + sw.WriteLine(); + + sw.WriteLine( "# Gump response" ); + BaseProfile.WriteAll( sw, GumpProfile.Profiles ); + sw.WriteLine(); + + sw.WriteLine( "# Target response" ); + BaseProfile.WriteAll( sw, TargetProfile.Profiles ); sw.WriteLine(); } } diff --git a/Server/Diagnostics/BaseProfile.cs b/Server/Diagnostics/BaseProfile.cs new file mode 100644 index 000000000..0eeaacbda --- /dev/null +++ b/Server/Diagnostics/BaseProfile.cs @@ -0,0 +1,112 @@ +/*************************************************************************** + * PacketProfile.cs + * ------------------- + * begin : May 1, 2002 + * copyright : (C) The RunUO Software Team + * email : info@runuo.com + * + * $Id: PacketProfile.cs 4 2006-06-15 04:28:39Z mark $ + * + ***************************************************************************/ + +/*************************************************************************** + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + ***************************************************************************/ + +using System; +using System.IO; +using System.Collections.Generic; +using System.Diagnostics; + +namespace Server.Diagnostics { + public abstract class BaseProfile { + public static void WriteAll( TextWriter op, IEnumerable profiles ) where T : BaseProfile { + List list = new List( profiles ); + + list.Sort( delegate( T a, T b ) { + return -a.TotalTime.CompareTo( b.TotalTime ); + } ); + + foreach ( T prof in list ) { + prof.WriteTo( op ); + op.WriteLine(); + } + } + + private string _name; + + private int _count; + + private TimeSpan _totalTime; + private TimeSpan _peakTime; + + private Stopwatch _stopwatch; + + public string Name { + get { + return _name; + } + } + + public int Count { + get { + return _count; + } + } + + public TimeSpan AverageTime { + get { + return TimeSpan.FromTicks( _totalTime.Ticks / Math.Max( 1, _count ) ); + } + } + + public TimeSpan PeakTime { + get { + return _peakTime; + } + } + + public TimeSpan TotalTime { + get { + return _totalTime; + } + } + + public BaseProfile( string name ) { + _name = name; + + _stopwatch = new Stopwatch(); + } + + public virtual void Start() { + if ( _stopwatch.IsRunning ) { + _stopwatch.Reset(); + } + + _stopwatch.Start(); + } + + public virtual void Finish() { + TimeSpan elapsed = _stopwatch.Elapsed; + + _totalTime += elapsed; + + if ( elapsed > _peakTime ) { + _peakTime = elapsed; + } + + _count++; + + _stopwatch.Reset(); + } + + public virtual void WriteTo( TextWriter op ) { + op.Write( "{0,-100} {1,12:N0} {2,12:F5} {3,-12:F5} {4,12:F5}", Name, Count, AverageTime.TotalSeconds, PeakTime.TotalSeconds, TotalTime.TotalSeconds ); + } + } +} \ No newline at end of file diff --git a/Server/Diagnostics/GumpProfile.cs b/Server/Diagnostics/GumpProfile.cs new file mode 100644 index 000000000..ec2df112b --- /dev/null +++ b/Server/Diagnostics/GumpProfile.cs @@ -0,0 +1,53 @@ +/*************************************************************************** + * PacketProfile.cs + * ------------------- + * begin : May 1, 2002 + * copyright : (C) The RunUO Software Team + * email : info@runuo.com + * + * $Id: PacketProfile.cs 4 2006-06-15 04:28:39Z mark $ + * + ***************************************************************************/ + +/*************************************************************************** + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + ***************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Server.Diagnostics { + public class GumpProfile : BaseProfile { + private static Dictionary _profiles = new Dictionary(); + + public static IEnumerable Profiles { + get { + return _profiles.Values; + } + } + + public static GumpProfile Acquire( Type type ) { + if ( !Core.Profiling ) { + return null; + } + + GumpProfile prof; + + if ( !_profiles.TryGetValue( type, out prof ) ) { + _profiles.Add( type, prof = new GumpProfile( type ) ); + } + + return prof; + } + + public GumpProfile( Type type ) + : base( type.FullName ) { + } + } +} \ No newline at end of file diff --git a/Server/Diagnostics/PacketProfile.cs b/Server/Diagnostics/PacketProfile.cs new file mode 100644 index 000000000..0b08cda7f --- /dev/null +++ b/Server/Diagnostics/PacketProfile.cs @@ -0,0 +1,131 @@ +/*************************************************************************** + * PacketProfile.cs + * ------------------- + * begin : May 1, 2002 + * copyright : (C) The RunUO Software Team + * email : info@runuo.com + * + * $Id: PacketProfile.cs 4 2006-06-15 04:28:39Z mark $ + * + ***************************************************************************/ + +/*************************************************************************** + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + ***************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace Server.Diagnostics { + public abstract class BasePacketProfile : BaseProfile { + private long _totalLength; + + public long TotalLength { + get { + return _totalLength; + } + } + + public double AverageLength { + get { + return ( double ) _totalLength / Math.Max( 1, this.Count ); + } + } + + public BasePacketProfile( string name ) + : base( name ) { + } + + public void Finish( int length ) { + Finish(); + + _totalLength += length; + } + + public override void WriteTo( TextWriter op ) { + base.WriteTo( op ); + + op.Write( "\t{0,12:F2} {1,-12:N0}", AverageLength, TotalLength ); + } + } + + public class PacketSendProfile : BasePacketProfile { + private static Dictionary _profiles = new Dictionary(); + + public static IEnumerable Profiles { + get { + return _profiles.Values; + } + } + + public static PacketSendProfile Acquire( Type type ) { + if ( !Core.Profiling ) { + return null; + } + + PacketSendProfile prof; + + if ( !_profiles.TryGetValue( type, out prof ) ) { + _profiles.Add( type, prof = new PacketSendProfile( type ) ); + } + + return prof; + } + + private int _created; + + public int Created { + get { + return _created; + } + set { + _created = value; + } + } + + public PacketSendProfile( Type type ) + : base( type.FullName ) { + } + + public override void WriteTo( TextWriter op ) { + base.WriteTo( op ); + + op.Write( "\t{0,12:N0}", Created ); + } + } + + public class PacketReceiveProfile : BasePacketProfile { + private static Dictionary _profiles = new Dictionary(); + + public static IEnumerable Profiles { + get { + return _profiles.Values; + } + } + + public static PacketReceiveProfile Acquire( int packetId ) { + if ( !Core.Profiling ) { + return null; + } + + PacketReceiveProfile prof; + + if ( !_profiles.TryGetValue( packetId, out prof ) ) { + _profiles.Add( packetId, prof = new PacketReceiveProfile( packetId ) ); + } + + return prof; + } + + public PacketReceiveProfile( int packetId ) + : base( String.Format( "0x{0:X2}", packetId ) ) { + } + } +} \ No newline at end of file diff --git a/Server/Diagnostics/TargetProfile.cs b/Server/Diagnostics/TargetProfile.cs new file mode 100644 index 000000000..417cd7ce7 --- /dev/null +++ b/Server/Diagnostics/TargetProfile.cs @@ -0,0 +1,53 @@ +/*************************************************************************** + * PacketProfile.cs + * ------------------- + * begin : May 1, 2002 + * copyright : (C) The RunUO Software Team + * email : info@runuo.com + * + * $Id: PacketProfile.cs 4 2006-06-15 04:28:39Z mark $ + * + ***************************************************************************/ + +/*************************************************************************** + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + ***************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Server.Diagnostics { + public class TargetProfile : BaseProfile { + private static Dictionary _profiles = new Dictionary(); + + public static IEnumerable Profiles { + get { + return _profiles.Values; + } + } + + public static TargetProfile Acquire( Type type ) { + if ( !Core.Profiling ) { + return null; + } + + TargetProfile prof; + + if ( !_profiles.TryGetValue( type, out prof ) ) { + _profiles.Add( type, prof = new TargetProfile( type ) ); + } + + return prof; + } + + public TargetProfile( Type type ) + : base( type.FullName ) { + } + } +} \ No newline at end of file diff --git a/Server/Diagnostics/TimerProfile.cs b/Server/Diagnostics/TimerProfile.cs new file mode 100644 index 000000000..3d2f72a75 --- /dev/null +++ b/Server/Diagnostics/TimerProfile.cs @@ -0,0 +1,89 @@ +/*************************************************************************** + * PacketProfile.cs + * ------------------- + * begin : May 1, 2002 + * copyright : (C) The RunUO Software Team + * email : info@runuo.com + * + * $Id: PacketProfile.cs 4 2006-06-15 04:28:39Z mark $ + * + ***************************************************************************/ + +/*************************************************************************** + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + ***************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace Server.Diagnostics { + public class TimerProfile : BaseProfile { + private static Dictionary _profiles = new Dictionary(); + + public static IEnumerable Profiles { + get { + return _profiles.Values; + } + } + + public static TimerProfile Acquire( string name ) { + if ( !Core.Profiling ) { + return null; + } + + TimerProfile prof; + + if ( !_profiles.TryGetValue( name, out prof ) ) { + _profiles.Add( name, prof = new TimerProfile( name ) ); + } + + return prof; + } + + private int _created, _started, _stopped; + + public int Created { + get { + return _created; + } + set { + _created = value; + } + } + + public int Started { + get { + return _started; + } + set { + _started = value; + } + } + + public int Stopped { + get { + return _stopped; + } + set { + _stopped = value; + } + } + + public TimerProfile( string name ) + : base( name ) { + } + + public override void WriteTo( TextWriter op ) { + base.WriteTo( op ); + + op.Write( "\t{0,12:N0} {1,12:N0} {2,-12:N0}", _created, _started, _stopped ); + } + } +} \ No newline at end of file diff --git a/Server/Network/MessagePump.cs b/Server/Network/MessagePump.cs index f2605af92..f98d6c56b 100644 --- a/Server/Network/MessagePump.cs +++ b/Server/Network/MessagePump.cs @@ -26,6 +26,7 @@ using System.Net; using System.Net.Sockets; using Server; using Server.Network; +using Server.Diagnostics; namespace Server.Network { @@ -221,8 +222,11 @@ namespace Server.Network return false; } - PacketProfile profile = PacketProfile.GetIncomingProfile( packetID ); - DateTime start = ( profile == null ? DateTime.MinValue : DateTime.Now ); + PacketReceiveProfile prof = PacketReceiveProfile.Acquire( packetID ); + + if ( prof != null ) { + prof.Start(); + } byte[] packetBuffer; @@ -241,8 +245,9 @@ namespace Server.Network if ( BufferSize >= packetLength ) m_Buffers.ReleaseBuffer( packetBuffer ); - if ( profile != null ) - profile.Record( packetLength, DateTime.Now - start ); + if ( prof != null ) { + prof.Finish( packetLength ); + } } } else diff --git a/Server/Network/NetState.cs b/Server/Network/NetState.cs index 74932c7ca..c2e3dbc8b 100644 --- a/Server/Network/NetState.cs +++ b/Server/Network/NetState.cs @@ -32,6 +32,7 @@ using Server.Items; using Server.Gumps; using Server.Menus; using Server.HuePickers; +using Server.Diagnostics; namespace Server.Network { public interface IPacketEncoder { @@ -534,8 +535,7 @@ namespace Server.Network { return; } - PacketProfile prof = PacketProfile.GetOutgoingProfile( ( byte ) p.PacketID ); - DateTime start = ( prof == null ? DateTime.MinValue : DateTime.Now ); + PacketSendProfile prof = PacketSendProfile.Acquire( p.GetType() ); int length; byte[] buffer = p.Compile( m_CompressionEnabled, out length ); @@ -546,6 +546,10 @@ namespace Server.Network { return; } + if ( prof != null ) { + prof.Start(); + } + if ( m_Encoder != null ) { m_Encoder.EncodeOutgoingPacket( this, ref buffer, ref length ); } @@ -572,7 +576,7 @@ namespace Server.Network { p.OnSend(); if ( prof != null ) { - prof.Record( length, DateTime.Now - start ); + prof.Finish( length ); } } else { Console.WriteLine( "Client: {0}: null buffer send, disconnecting...", this ); diff --git a/Server/Network/PacketHandlers.cs b/Server/Network/PacketHandlers.cs index 625d49c28..8ae0883d1 100644 --- a/Server/Network/PacketHandlers.cs +++ b/Server/Network/PacketHandlers.cs @@ -34,6 +34,7 @@ using Server.Movement; using Server.Prompts; using Server.HuePickers; using Server.ContextMenus; +using Server.Diagnostics; using CV = Server.ClientVersion; namespace Server.Network @@ -1010,69 +1011,81 @@ namespace Server.Network if ( t != null ) { - if ( x == -1 && y == -1 && !serial.IsValid ) - { - // User pressed escape - t.Cancel( from, TargetCancelType.Canceled ); + TargetProfile prof = TargetProfile.Acquire( t.GetType() ); + + if ( prof != null ) { + prof.Start(); } - else - { - object toTarget; - if ( type == 1 ) + try { + if ( x == -1 && y == -1 && !serial.IsValid ) { - if ( graphic == 0 ) - { - toTarget = new LandTarget( new Point3D( x, y, z ), from.Map ); - } - else - { - Map map = from.Map; + // User pressed escape + t.Cancel( from, TargetCancelType.Canceled ); + } + else + { + object toTarget; - if ( map == null || map == Map.Internal ) + if ( type == 1 ) + { + if ( graphic == 0 ) { - t.Cancel( from, TargetCancelType.Canceled ); - return; + toTarget = new LandTarget( new Point3D( x, y, z ), from.Map ); } else { - Tile[] tiles = map.Tiles.GetStaticTiles( x, y, !t.DisallowMultis ); + Map map = from.Map; - bool valid = false; - - for ( int i = 0; !valid && i < tiles.Length; ++i ) - { - if ( tiles[i].Z == z && (tiles[i].ID & 0x3FFF) == (graphic & 0x3FFF) ) - valid = true; - } - - if ( !valid ) + if ( map == null || map == Map.Internal ) { t.Cancel( from, TargetCancelType.Canceled ); return; } else { - toTarget = new StaticTarget( new Point3D( x, y, z ), graphic ); + Tile[] tiles = map.Tiles.GetStaticTiles( x, y, !t.DisallowMultis ); + + bool valid = false; + + for ( int i = 0; !valid && i < tiles.Length; ++i ) + { + if ( tiles[i].Z == z && (tiles[i].ID & 0x3FFF) == (graphic & 0x3FFF) ) + valid = true; + } + + if ( !valid ) + { + t.Cancel( from, TargetCancelType.Canceled ); + return; + } + else + { + toTarget = new StaticTarget( new Point3D( x, y, z ), graphic ); + } } } } - } - else if ( serial.IsMobile ) - { - toTarget = World.FindMobile( serial ); - } - else if ( serial.IsItem ) - { - toTarget = World.FindItem( serial ); - } - else - { - t.Cancel( from, TargetCancelType.Canceled ); - return; - } + else if ( serial.IsMobile ) + { + toTarget = World.FindMobile( serial ); + } + else if ( serial.IsItem ) + { + toTarget = World.FindItem( serial ); + } + else + { + t.Cancel( from, TargetCancelType.Canceled ); + return; + } - t.Invoke( from, toTarget ); + t.Invoke( from, toTarget ); + } + } finally { + if ( prof != null ) { + prof.Finish(); + } } } } @@ -1123,8 +1136,18 @@ namespace Server.Network state.RemoveGump( gump ); + GumpProfile prof = GumpProfile.Acquire( gump.GetType() ); + + if ( prof != null ) { + prof.Start(); + } + gump.OnResponse( state, new RelayInfo( buttonID, switches, textEntries ) ); + if ( prof != null ) { + prof.Finish(); + } + return; } } diff --git a/Server/Network/PacketProfile.cs b/Server/Network/PacketProfile.cs deleted file mode 100644 index 4e9ccf53f..000000000 --- a/Server/Network/PacketProfile.cs +++ /dev/null @@ -1,159 +0,0 @@ -/*************************************************************************** - * PacketProfile.cs - * ------------------- - * begin : May 1, 2002 - * copyright : (C) The RunUO Software Team - * email : info@runuo.com - * - * $Id$ - * - ***************************************************************************/ - -/*************************************************************************** - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - ***************************************************************************/ - -using System; - -namespace Server.Network -{ - public class PacketProfile - { - private int m_Constructed; - private int m_Count; - private int m_TotalByteLength; - private TimeSpan m_TotalProcTime; - private TimeSpan m_PeakProcTime; - private bool m_Outgoing; - - [CommandProperty( AccessLevel.Administrator )] - public bool Outgoing - { - get{ return m_Outgoing; } - } - - [CommandProperty( AccessLevel.Administrator )] - public int Constructed - { - get{ return m_Constructed; } - } - - [CommandProperty( AccessLevel.Administrator )] - public int TotalByteLength - { - get{ return m_TotalByteLength; } - } - - [CommandProperty( AccessLevel.Administrator )] - public TimeSpan TotalProcTime - { - get{ return m_TotalProcTime; } - } - - [CommandProperty( AccessLevel.Administrator )] - public TimeSpan PeakProcTime - { - get{ return m_PeakProcTime; } - } - - [CommandProperty( AccessLevel.Administrator )] - public int Count - { - get{ return m_Count; } - } - - [CommandProperty( AccessLevel.Administrator )] - public double AverageByteLength - { - get - { - if ( m_Count == 0 ) - return 0; - - return Math.Round( (double) m_TotalByteLength / m_Count, 2 ); - } - } - - [CommandProperty( AccessLevel.Administrator )] - public TimeSpan AverageProcTime - { - get - { - if ( m_Count == 0 ) - return TimeSpan.Zero; - - return TimeSpan.FromTicks( m_TotalProcTime.Ticks / m_Count ); - } - } - - public void Record( int byteLength, TimeSpan processTime ) - { - ++m_Count; - m_TotalByteLength += byteLength; - m_TotalProcTime += processTime; - - if ( processTime > m_PeakProcTime ) - m_PeakProcTime = processTime; - } - - public void RegConstruct() - { - ++m_Constructed; - } - - public PacketProfile( bool outgoing ) - { - m_Outgoing = outgoing; - } - - private static PacketProfile[] m_OutgoingProfiles; - private static PacketProfile[] m_IncomingProfiles; - - public static PacketProfile GetOutgoingProfile( int packetID ) - { - if ( !Core.Profiling ) - return null; - - PacketProfile prof = m_OutgoingProfiles[packetID]; - - if ( prof == null ) - m_OutgoingProfiles[packetID] = prof = new PacketProfile( true ); - - return prof; - } - - public static PacketProfile GetIncomingProfile( int packetID ) - { - if ( !Core.Profiling ) - return null; - - PacketProfile prof = m_IncomingProfiles[packetID]; - - if ( prof == null ) - m_IncomingProfiles[packetID] = prof = new PacketProfile( false ); - - return prof; - } - - public static PacketProfile[] OutgoingProfiles - { - get{ return m_OutgoingProfiles; } - } - - public static PacketProfile[] IncomingProfiles - { - get{ return m_IncomingProfiles; } - } - - static PacketProfile() - { - m_OutgoingProfiles = new PacketProfile[0x100]; - m_IncomingProfiles = new PacketProfile[0x100]; - } - } -} \ No newline at end of file diff --git a/Server/Network/Packets.cs b/Server/Network/Packets.cs index 198124228..798528fe8 100644 --- a/Server/Network/Packets.cs +++ b/Server/Network/Packets.cs @@ -34,6 +34,7 @@ using Server.Menus.Questions; using Server.Prompts; using Server.HuePickers; using Server.ContextMenus; +using Server.Diagnostics; namespace Server.Network { @@ -3460,10 +3461,11 @@ namespace Server.Network { m_PacketID = packetID; - PacketProfile prof = PacketProfile.GetOutgoingProfile( (byte)packetID ); + PacketSendProfile prof = PacketSendProfile.Acquire( GetType() ); - if ( prof != null ) - prof.RegConstruct(); + if ( prof != null ) { + prof.Created++; + } } public void EnsureCapacity( int length ) @@ -3479,12 +3481,13 @@ namespace Server.Network m_Length = length; m_Stream = PacketWriter.CreateInstance( length );// new PacketWriter( length ); - m_Stream.Write( (byte) packetID ); + m_Stream.Write( ( byte ) packetID ); - PacketProfile prof = PacketProfile.GetOutgoingProfile( (byte)packetID ); + PacketSendProfile prof = PacketSendProfile.Acquire( GetType() ); - if ( prof != null ) - prof.RegConstruct(); + if ( prof != null ) { + prof.Created++; + } } public PacketWriter UnderlyingStream diff --git a/Server/Timer.cs b/Server/Timer.cs index 56c1651d7..898b617b5 100644 --- a/Server/Timer.cs +++ b/Server/Timer.cs @@ -24,6 +24,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Threading; +using Server.Diagnostics; namespace Server { @@ -43,92 +44,6 @@ namespace Server public delegate void TimerStateCallback( object state ); public delegate void TimerStateCallback( T state ); - public class TimerProfile - { - private int m_Created; - private int m_Started; - private int m_Stopped; - private int m_Ticked; - private TimeSpan m_TotalProcTime; - private TimeSpan m_PeakProcTime; - - [CommandProperty( AccessLevel.Administrator )] - public int Created - { - get{ return m_Created; } - } - - [CommandProperty( AccessLevel.Administrator )] - public int Started - { - get{ return m_Started; } - } - - [CommandProperty( AccessLevel.Administrator )] - public int Stopped - { - get{ return m_Stopped; } - } - - [CommandProperty( AccessLevel.Administrator )] - public int Ticked - { - get{ return m_Ticked; } - } - - [CommandProperty( AccessLevel.Administrator )] - public TimeSpan TotalProcTime - { - get{ return m_TotalProcTime; } - } - - [CommandProperty( AccessLevel.Administrator )] - public TimeSpan PeakProcTime - { - get{ return m_PeakProcTime; } - } - - [CommandProperty( AccessLevel.Administrator )] - public TimeSpan AverageProcTime - { - get - { - if ( m_Ticked == 0 ) - return TimeSpan.Zero; - - return TimeSpan.FromTicks( m_TotalProcTime.Ticks / m_Ticked ); - } - } - - public void RegCreation() - { - ++m_Created; - } - - public void RegStart() - { - ++m_Started; - } - - public void RegStopped() - { - ++m_Stopped; - } - - public void RegTicked( TimeSpan procTime ) - { - ++m_Ticked; - m_TotalProcTime += procTime; - - if ( procTime > m_PeakProcTime ) - m_PeakProcTime = procTime; - } - - public TimerProfile() - { - } - } - public class Timer { private DateTime m_Next; @@ -218,27 +133,19 @@ namespace Server } } - private static Dictionary m_Profiles = new Dictionary(); - - public static Dictionary Profiles{ get{ return m_Profiles; } } - public TimerProfile GetProfile() { - if ( !Core.Profiling ) + if ( !Core.Profiling ) { return null; + } string name = ToString(); - if ( name == null ) + if ( name == null ) { name = "null"; + } - TimerProfile prof = null; - m_Profiles.TryGetValue( name, out prof ); - - if ( prof == null ) - m_Profiles[name] = prof = new TimerProfile(); - - return prof; + return TimerProfile.Acquire( name ); } public class TimerThread @@ -481,19 +388,13 @@ namespace Server int index = 0; - Stopwatch watch = null; - while ( index < m_BreakCount && m_Queue.Count != 0 ) { Timer t = m_Queue.Dequeue(); TimerProfile prof = t.GetProfile(); if ( prof != null ) { - if ( watch == null ) { - watch = Stopwatch.StartNew(); - } else { - watch.Start(); - } + prof.Start(); } t.OnTick(); @@ -501,8 +402,7 @@ namespace Server ++index; if ( prof != null ) { - prof.RegTicked( watch.Elapsed ); - watch.Reset(); + prof.Finish(); } } } @@ -525,8 +425,9 @@ namespace Server { TimerProfile prof = GetProfile(); - if ( prof != null ) - prof.RegCreation(); + if ( prof != null ) { + prof.Created++; + } } public Timer( TimeSpan delay, TimeSpan interval, int count ) @@ -734,8 +635,9 @@ namespace Server TimerProfile prof = GetProfile(); - if ( prof != null ) - prof.RegStart(); + if ( prof != null ) { + prof.Started++; + } } } @@ -748,8 +650,9 @@ namespace Server TimerProfile prof = GetProfile(); - if ( prof != null ) - prof.RegStopped(); + if ( prof != null ) { + prof.Stopped++; + } } }