Exemplo n.º 1
0
 private static extern bool GetSystemTimes(
     out FILETIME lpIdleTime,
     out FILETIME lpKernelTime,
     out FILETIME lpUserTime
     );
Exemplo n.º 2
0
        public ProcessorPerformanceInfo[] GetProcessorPerfInfo()
        {
            // We can get the Processor load a number of different ways :
            // 1. Using Performance Counters, however they might not be running on all machines
            //    (can programatically change registry to fix kindof)
            //    Advantage: we can get load of each CPU independently.
            //    Disadvantage: on Vista/Win2003/8 the user needs to be admin/part of Performance Monitor Users group.
            // 2. Using PInvoke call to GetSystemTimes then we can just divide the load between CPUs (ok but not accurate)
            // 3. Using PInvoke call to NTQuerySystemInformation (disadvantage is that this API is not guaranteed to be available
            //      in the next version of Windows and is not recommended by Microsoft.
            //      However, the TaskManager does use this API, and it has proper multi-proc/core support.
            // 4. Using WMI: too much overhead? Need to have WMI service running.

            //We are currently using #1, 2

            //in general the CPU speed is the same for all the CPUs in a system.
            //so let us just get the first CPU speed, and set it as the current speed - for now.
            //an accurate current speed can be obtained from WMI, but that may be too much overhead
            //this method can be safely called without a perf hit, since it caches the processor info
            GetProcessorInfo();
            double currentCpuSpeed = 0;

            //we know that the list is now initialised
            if (processors != null && processors.Count > 0)
            {
                currentCpuSpeed = processors[0].SpeedMax;
            }

            List <ProcessorPerformanceInfo> perfInfos = new List <ProcessorPerformanceInfo>(processorCount);

            // Initialise things on the first run //

            // Check if performance counters are enabled
            // And initialise some variables for the first run
            if (firstRun)
            {
                //For Mono, we know PerformanceCounters are not implemented at the moment (March 2008). So, we just compile it out.

                canUseCounters = EnablePerformanceCounters(true);

                firstRun = false;
                //logger.Trace("Performance Counters Enabled? " + canUseCounters);
                // Initialise this for the first time.
                timeOfLastCallForProcessTime = DateTime.Now;
                prevProcessTime = Process.GetCurrentProcess().TotalProcessorTime;
                if (!canUseCounters)
                {
                    bool success = GetSystemTimes(out prevIdleTime, out prevKernelTime, out prevUserTime);
                }
                Thread.Sleep(500); // sleep a little on the first run to put some time between calls to check proc. usage
            }


            // Calculate CPU Usage for Executor Process //

            // For both canUseCounters and !canUseCounters
            // Calculate the difference between successive calls to this method.
            DateTime timeNow  = DateTime.Now;
            TimeSpan interval = timeNow.Subtract(timeOfLastCallForProcessTime);
            // todoLater: processTime actually needs to also include process time of DotNetExecutor.exe/JavaExecutor which may be running Jobs AND which processor it's running on
            TimeSpan processTime             = Process.GetCurrentProcess().TotalProcessorTime;
            double   executorCPUUsagePercent = 100 * (processTime.TotalMilliseconds - prevProcessTime.TotalMilliseconds) / interval.TotalMilliseconds;

            if (executorCPUUsagePercent > 100.00)
            {
                //logger.Warn("CPU Usage for this process measured over 100%. Setting value to 100%.");
                executorCPUUsagePercent = 100.00;
            }
            timeOfLastCallForProcessTime = timeNow;
            prevProcessTime = processTime;


            // Calculate Overall CPU Usage //

            try
            {
                if (canUseCounters)
                {
                    int numCpus = CpuUsageCounters.Length;
                    for (int i = 0; i < numCpus; i++)
                    {
                        double nextValue = (double)CpuUsageCounters[i].NextValue();

                        if (nextValue > 100.00)
                        {
                            //logger.Warn("CPU Usage for overall system measured over 100%. Setting value to 100%.");
                            nextValue = 100.00;
                        }
                        ProcessorPerformanceInfo perfInfo =
                            new ProcessorPerformanceInfo(i.ToString(), currentCpuSpeed, nextValue, executorCPUUsagePercent);
                        perfInfos.Add(perfInfo);
                    }
                }
            }
            catch (System.UnauthorizedAccessException ux)
            {
                //logger.Warn("Cannot access performance counter data: " + ux.Message);
                canUseCounters = false;
            }

            if (!canUseCounters)
            {
                // refer : http://www.codeproject.com/KB/threads/Get_CPU_Usage.aspx
                // If we cant use Performance Counters then try GetSystemTimes
                FILETIME idleTime, kernelTime, userTime;
                double   cpuUsagePercent = 0.0;

                if (GetSystemTimes(out idleTime, out kernelTime, out userTime))
                {
                    ulong idleTimeDifference   = GetDifference(idleTime, prevIdleTime);
                    ulong kernelTimeDifference = GetDifference(kernelTime, prevKernelTime);
                    ulong userTimeDifference   = GetDifference(userTime, prevUserTime);

                    ulong sysTime = (kernelTimeDifference + userTimeDifference);
                    cpuUsagePercent = 100 * (sysTime - idleTimeDifference) / sysTime; // This is total time over ALL processors so needs to be divided

                    prevIdleTime   = idleTime;
                    prevKernelTime = kernelTime;
                    prevUserTime   = userTime;

                    //logger.Debug("refreshInterval: " + interval.Ticks);
                    //logger.Debug("Idle time diff: " + idleTimeDifference);
                    //logger.Debug("Kernel time diff: " + kernelTimeDifference);
                    //logger.Debug("User time diff: " + userTimeDifference);
                    //logger.Debug("System time diff: " + sysTime);
                    //logger.Debug("Sys + Idle - Interval = " + (sysTime + idleTimeDifference - (ulong)interval.Ticks));
                    //this seemed logical, but is wrong! always gives a weird 100+ value
                    //logger.Debug("CPU Usage: % " + (100 * sysTime / (ulong)(interval.Ticks)));
                    //this is confusing but correct!
                    //logger.Debug("Alt CPU Usage: % " + cpuUsagePercent);
                }
                else
                {
                    //logger.Warn("GetSystemTimes returned false");
                }

                double individualCpuUsagePercent = cpuUsagePercent;
                if (processorCount > 1)
                {
                    individualCpuUsagePercent = (double)(cpuUsagePercent / (double)processorCount);
                }

                if (individualCpuUsagePercent > 100.00)
                {
                    //logger.Warn("CPU Usage for overall system measured over 100% (per core). Setting value to 100% (per core).");
                    individualCpuUsagePercent = 100.00;
                }

                //return empty values for performance for now
                for (int i = 0; i < processorCount; i++)
                {
                    ProcessorPerformanceInfo perfInfo =
                        new ProcessorPerformanceInfo(i.ToString(), currentCpuSpeed, individualCpuUsagePercent, executorCPUUsagePercent);
                    perfInfos.Add(perfInfo);
                }
            }

            return(perfInfos.ToArray());
        }