示例#1
0
        private static void MonitorLowPriority()
        {
            ShortTime lastTime = ShortTime.Now;

            while (true)
            {
                try
                {
                    Thread.Sleep(10);
                    ShortTime currentTime = ShortTime.Now;

                    long   sleepDelta        = (long)lastTime.ElapsedTicks(currentTime);
                    long   additionalDelay   = sleepDelta - 100 * TimeSpan.TicksPerMillisecond;
                    double additionalDelayMS = additionalDelay / (double)TimeSpan.TicksPerMillisecond;

                    if (additionalDelayMS > 1000)
                    {
                        LogLarge.Publish(additionalDelayMS.ToString() + " ms (Normal Priority)");
                    }
                    else if (additionalDelayMS > 500)
                    {
                        LogMedium.Publish(additionalDelayMS.ToString() + " ms (Normal Priority)");
                    }

                    Interlocked.Increment(ref s_lowProcessCount);

                    lastTime = currentTime;
                }
                catch (Exception ex)
                {
                    Log.Publish(MessageLevel.Warning, MessageFlags.BugReport, "Unexpected Exception Caught", null, null, ex);
                    Thread.Sleep(1000);
                }
            }
        }
示例#2
0
        private static void MonitorHighPriority()
        {
            //This one will primarily detect when the process is paused.
            //This occurs when garbage collection occurs.

            ShortTime lastTime = ShortTime.Now;

            while (true)
            {
                try
                {
                    Thread.Sleep(10);
                    ShortTime currentTime = ShortTime.Now;

                    long   sleepDelta        = (long)lastTime.ElapsedTicks(currentTime);
                    long   additionalDelay   = sleepDelta - 10 * TimeSpan.TicksPerMillisecond;
                    double additionalDelayMS = additionalDelay / (double)TimeSpan.TicksPerMillisecond;

                    if (additionalDelayMS > 1000)
                    {
                        LogLarge.Publish(additionalDelayMS.ToString() + " ms (High Priority)");
                    }
                    else if (additionalDelayMS > 300)
                    {
                        LogMedium.Publish(additionalDelayMS.ToString() + " ms (High Priority)");
                    }
                    else if (additionalDelayMS > 100)
                    {
                        LogSmall.Publish(additionalDelayMS.ToString() + " ms (High Priority)");
                    }

                    Interlocked.Increment(ref s_highProcessCount);

                    AdjustRealtime();

                    lastTime = currentTime;
                }
                catch (Exception ex)
                {
                    Log.Publish(MessageLevel.Warning, MessageFlags.BugReport, "Unexpected Exception Caught", null, null, ex);
                    Thread.Sleep(1000);
                }
            }
        }
示例#3
0
        private static void AdjustRealtime()
        {
            //This method is supposed to be called every 10 milliseconds on a high priority thread.
            //However don't update the time unless 100ms has elapsed.

            //Since DateTime can be programmatically changed, I'm using CPU Registers.
            long physicalTimeSinceLastSet = (long)s_currentTimeSetTime.ElapsedTicks();

            if (physicalTimeSinceLastSet < 100 * TimeSpan.TicksPerMillisecond)
            {
                return;
            }

            long clockSinceLastSet = DateTime.UtcNow.Ticks - s_currentTime;

            if (Math.Abs(physicalTimeSinceLastSet - clockSinceLastSet) > TimeSpan.TicksPerSecond)
            {
                Log.Publish(MessageLevel.Warning, MessageFlags.SystemHealth,
                            "System time has been adjusted by more than 1 second. Resetting Loading Figures.",
                            $"Expected Clock Change: {physicalTimeSinceLastSet / TimeSpan.TicksPerMillisecond} ms, Clock change: {clockSinceLastSet / TimeSpan.TicksPerMillisecond}");

                Reset();
                return;
            }
            if (clockSinceLastSet < 0)
            {
                Log.Publish(MessageLevel.Info, MessageFlags.SystemHealth, "System Clock did not advance.",
                            $"Expected Clock Change: {physicalTimeSinceLastSet / TimeSpan.TicksPerMillisecond} ms, Clock change: {clockSinceLastSet / TimeSpan.TicksPerMillisecond}");
            }

            int highDelay   = Interlocked.Exchange(ref s_highProcessCount, 0);
            int normalDelay = Interlocked.Exchange(ref s_normalProcessCount, 0);
            int lowDelay    = Interlocked.Exchange(ref s_lowProcessCount, 0);

            if (highDelay >= 5 && lowDelay <= 1)
            {
                try
                {
                    OnHighLoad?.Invoke();
                }
                catch (Exception)
                {
                }
            }

            long maxAdjustment = 0;

            if (lowDelay >= 7)
            {
                maxAdjustment = 500 * TimeSpan.TicksPerMillisecond;
            }
            else if (lowDelay >= 5)
            {
                maxAdjustment = 400 * TimeSpan.TicksPerMillisecond;
            }
            else if (normalDelay >= 7)
            {
                maxAdjustment = 300 * TimeSpan.TicksPerMillisecond;
            }
            else if (normalDelay >= 5)
            {
                maxAdjustment = 200 * TimeSpan.TicksPerMillisecond;
            }
            else if (highDelay >= 4)
            {
                maxAdjustment = 100 * TimeSpan.TicksPerMillisecond;
            }
            else
            {
                maxAdjustment = 50 * TimeSpan.TicksPerMillisecond;
            }

            if (maxAdjustment < clockSinceLastSet)
            {
                LogLoadingClock.Publish($"Behind by {clockSinceLastSet / TimeSpan.TicksPerMillisecond}ms adjusting by {maxAdjustment / TimeSpan.TicksPerMillisecond}ms");
            }

            long adjustment = Math.Min(clockSinceLastSet, maxAdjustment);

            if (adjustment >= 0)
            {
                Interlocked.Exchange(ref s_currentTime, s_currentTime + adjustment);
            }
            s_currentTimeSetTime = ShortTime.Now;
        }