rework Core.TickCount

This commit is contained in:
Mark Sturgill 2013-10-07 00:22:11 -07:00
parent b3535985d7
commit 7b6cf66b87
9 changed files with 107 additions and 49 deletions

View file

@ -112,13 +112,71 @@ namespace Server
public static Thread Thread { get { return m_Thread; } }
public static MultiTextWriter MultiConsoleOut { get { return m_MultiConOut; } }
public static int TickCount {
#if false && !MONO
[DllImport("kernel32")]
private static extern long GetTickCount64();
#endif
/* DateTime.Now and DateTime.UtcNow depend on the system time which is undesirable.
* GetTickCount64 is unavailable on Windows XP and Windows Server 2003.
* Stopwatch.GetTimestamp() (QueryPerformanceCounter) is high resolution,
* but expensive to call and unreliable with certain system configurations.
*/
/* The following implementation is an effective substitute for GetTickCount64 that
* is reliable as long as it is retrieved once every 2^32 ms (~49 days).
*/
#if Framework_4_0
private static ThreadLocal<long> _HighOrder = new ThreadLocal<long>();
private static ThreadLocal<uint> _LastTickCount = new ThreadLocal<uint>();
private static readonly long _Frequency = Stopwatch.Frequency;
public static long TickCount {
get {
if (Stopwatch.IsHighResolution) // TODO: GetTimestamp is unreliable with certain system configurations.
return (int)((double)Stopwatch.GetTimestamp() / Stopwatch.Frequency * 1000);
return Environment.TickCount;
if (Stopwatch.IsHighResolution) // TODO: Unreliable with certain system configurations.
return (long)((double)Stopwatch.GetTimestamp() / _Frequency * 1000);
uint t = (uint)Environment.TickCount;
if (_LastTickCount.Value > t) // Wrapped
_HighOrder.Value += 0x100000000;
_LastTickCount.Value = t;
return _HighOrder.Value | _LastTickCount.Value;
}
}
#else
private static long _HighOrder;
private static uint _LastTickCount;
private static object _TickSync = new object();
private static readonly long _Frequency = Stopwatch.Frequency;
public static long TickCount
{
get
{
if (Stopwatch.IsHighResolution) // TODO: Unreliable with certain system configurations.
return (long)((double)Stopwatch.GetTimestamp() / _Frequency * 1000);
lock (_TickSync)
{
uint t = (uint)Environment.TickCount;
if (_LastTickCount > t) // Wrapped
_HighOrder += 0x100000000;
_LastTickCount = t;
return _HighOrder | _LastTickCount;
}
}
}
#endif
#if Framework_4_0
public static readonly bool Is64Bit = Environment.Is64BitProcess;
@ -513,10 +571,10 @@ namespace Server
try
{
DateTime now, last = DateTime.UtcNow;
long now, last = TickCount;
const int sampleInterval = 100;
const float ticksPerSecond = (float)(TimeSpan.TicksPerSecond * sampleInterval);
const float ticksPerSecond = (float)(1000 * sampleInterval);
TimeSpan _oneMS = TimeSpan.FromMilliseconds( 1 );
long sample = 0;
@ -539,9 +597,9 @@ namespace Server
if( (++sample % sampleInterval) == 0 )
{
now = DateTime.UtcNow;
now = TickCount;
m_CyclesPerSecond[m_CycleIndex++ % m_CyclesPerSecond.Length] =
ticksPerSecond / (now.Ticks - last.Ticks);
ticksPerSecond / (now - last);
last = now;
}
}

View file

@ -660,11 +660,11 @@ namespace Server
private class MovementRecord
{
public int m_End;
public long m_End;
private static Queue<MovementRecord> m_InstancePool = new Queue<MovementRecord>();
public static MovementRecord NewInstance( int end )
public static MovementRecord NewInstance( long end )
{
MovementRecord r;
@ -682,7 +682,7 @@ namespace Server
return r;
}
private MovementRecord( int end )
private MovementRecord( long end )
{
m_End = end;
}
@ -744,7 +744,7 @@ namespace Server
private int m_TithingPoints;
private bool m_DisplayGuildTitle;
private Mobile m_GuildFealty;
private int m_NextSpellTime;
private long m_NextSpellTime;
private DateTime[] m_StuckMenuUses;
private Timer m_ExpireCombatant;
private Timer m_ExpireCriminal;
@ -752,9 +752,9 @@ namespace Server
private Timer m_LogoutTimer;
private Timer m_CombatTimer;
private Timer m_ManaTimer, m_HitsTimer, m_StamTimer;
private int m_NextSkillTime;
private int m_NextActionTime;
private int m_NextActionMessage;
private long m_NextSkillTime;
private long m_NextActionTime;
private long m_NextActionMessage;
private bool m_Paralyzed;
private ParalyzedTimer m_ParaTimer;
private bool m_Frozen;
@ -1482,7 +1482,7 @@ namespace Server
}
}
public int NextCombatTime
public long NextCombatTime
{
get
{
@ -1586,7 +1586,7 @@ namespace Server
}
}
private int m_LastMoveTime;
private long m_LastMoveTime;
/// <summary>
/// Gets or sets the number of steps this player may take when hidden before being revealed.
@ -1664,7 +1664,7 @@ namespace Server
}
}
public int LastMoveTime
public long LastMoveTime
{
get
{
@ -1845,7 +1845,7 @@ namespace Server
return String.Format( "0x{0:X} \"{1}\"", m_Serial.Value, Name );
}
public int NextActionTime
public long NextActionTime
{
get
{
@ -1857,7 +1857,7 @@ namespace Server
}
}
public int NextActionMessage
public long NextActionMessage
{
get
{
@ -2157,9 +2157,9 @@ namespace Server
#endregion
private int m_NextCombatTime;
private long m_NextCombatTime;
public int NextSkillTime
public long NextSkillTime
{
get
{
@ -3078,7 +3078,7 @@ namespace Server
public static int WalkMount { get { return m_WalkMount; } set { m_WalkMount = value; } }
public static int RunMount { get { return m_RunMount; } set { m_RunMount = value; } }
private int m_EndQueue;
private long m_EndQueue;
private static ArrayList m_MoveList = new ArrayList();
@ -3279,7 +3279,7 @@ namespace Server
int delay = ComputeMovementSpeed( d );
int end;
long end;
if( m_MoveRecords.Count > 0 )
end = m_EndQueue + delay;
@ -11335,7 +11335,7 @@ namespace Server
}
}
public int NextSpellTime
public long NextSpellTime
{
get
{

View file

@ -1025,7 +1025,7 @@ namespace Server.Network {
}
}
private int m_NextCheckActivity;
private long m_NextCheckActivity;
public bool CheckAlive() {
if ( m_Socket == null )