File: AppDomainResourcePerfCounters.cs

package info (click to toggle)
mono 6.14.1%2Bds2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,282,732 kB
  • sloc: cs: 11,182,461; xml: 2,850,281; ansic: 699,123; cpp: 122,919; perl: 58,604; javascript: 30,841; asm: 21,845; makefile: 19,602; sh: 10,973; python: 4,772; pascal: 925; sql: 859; sed: 16; php: 1
file content (133 lines) | stat: -rw-r--r-- 6,088 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//------------------------------------------------------------------------------
// <copyright file="AppDomainResourcePerfCounters.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//------------------------------------------------------------------------------

namespace System.Web.Management {
    using System;
    using System.Configuration;
    using System.Web;
    using System.Threading;

    internal class AppDomainResourcePerfCounters {

        private const  uint      NUM_SECONDS_TO_POLL = 5;

        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        internal static void Init() {
            if (_fInit)
                return;

            lock (_InitLock) {
                if (_fInit)
                    return;

                if (AppDomain.MonitoringIsEnabled) {
                    PerfCounters.SetCounter(AppPerfCounter.APP_CPU_USED_BASE, 100);
                    _Timer = new Timer((new AppDomainResourcePerfCounters()).TimerCallback, null,
                                       NUM_SECONDS_TO_POLL * 1000, NUM_SECONDS_TO_POLL * 1000);
                }
                _fInit = true;
            }
        }

        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        internal static void Stop() {
            if (_Timer == null)
                return; // already stopped

            _StopRequested = true;

            lock (_InitLock) {
                if (_Timer != null) {
                    ((IDisposable)_Timer).Dispose();
                    _Timer = null;
                }
            }

            // Wait for the _inProgressLock lock
            while (_inProgressLock != 0) {
                Thread.Sleep(100);
            }
        }

        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        // Static data
        private static bool      _fInit                = false;
        private static object    _InitLock             = new object();
        private static Timer     _Timer                = null;
        private static int       _inProgressLock       = 0;
        private static bool      _StopRequested        = false;

        // Instance data
        private int       _MemUsageLastReported = 0;
        private int       _CPUUsageLastReported = 0;
        private TimeSpan  _TotalCPUTime;
        private DateTime  _LastCollectTime;


        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        private AppDomainResourcePerfCounters() {
            _TotalCPUTime = AppDomain.CurrentDomain.MonitoringTotalProcessorTime;
            _LastCollectTime = DateTime.UtcNow;
        }

        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        private void TimerCallback(Object state) {

            if ( _StopRequested ||  // Stop has been called -- exit immediately
                 !AppDomain.MonitoringIsEnabled || // Monitoring APIs will throw NotSupportedException if not-enabled
                 Interlocked.Exchange(ref _inProgressLock, 1) != 0) // Is some thread currently executing the callback
            {
                return;
            }

            try {
                SetPerfCounters();
            } catch { // don't bubble up exceptions, since we are on a timer thread
            } finally {
                Interlocked.Exchange(ref _inProgressLock, 0);
            }
        }

        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        private void SetPerfCounters() {

            ////////////////////////////////////////////////////////////
            // Calculate memory: Limited to 2TB (Int32.MaxValue * 1024 bytes)
            long memInKB = (AppDomain.CurrentDomain.MonitoringSurvivedMemorySize / 1024); // Mem used in KB
            _MemUsageLastReported = (int) Math.Min(Int32.MaxValue, Math.Max(0, memInKB)); // Make sure its within 0 and Int32.MaxValue
            PerfCounters.SetCounter(AppPerfCounter.APP_MEMORY_USED, _MemUsageLastReported);

            ////////////////////////////////////////////////////////////
            // Calculate CPU
            DateTime dtUtcNow = DateTime.UtcNow;
            TimeSpan newTotalCPUTime = AppDomain.CurrentDomain.MonitoringTotalProcessorTime;

            double  timeElapsed = (dtUtcNow - _LastCollectTime).TotalMilliseconds; // Total time since last collect
            double  cpuTimeUsed = (newTotalCPUTime - _TotalCPUTime).TotalMilliseconds; // Total CPU time used since last collect
            int     cpuPercent  = (int) ((cpuTimeUsed * 100) / timeElapsed); // Percent of CPU time used

            _CPUUsageLastReported = Math.Min(100, Math.Max(0, cpuPercent)); // Make sure it's within 0 and 100
            PerfCounters.SetCounter(AppPerfCounter.APP_CPU_USED, _CPUUsageLastReported);

            // Update variables for next time
            _TotalCPUTime = newTotalCPUTime;
            _LastCollectTime = dtUtcNow;
        }
    }
}