示例#1
0
        //Wrapper for CallNtPowerInformation
        internal static ArrayList GetAllProcessorPowerInfo()
        {
            const Int32 processorSpeedInformation = 11; //Used in call to CallNtPowerInformation
            ArrayList   CPUspeeds = new ArrayList();
            PROCESSOR_POWER_INFORMATION oneppi = new PROCESSOR_POWER_INFORMATION();
            uint   ProcessorSpeedArraySize     = (UInt32)Environment.ProcessorCount * (UInt32)Marshal.SizeOf(oneppi);
            IntPtr CPUInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(PROCESSOR_POWER_INFORMATION)) * Environment.ProcessorCount);
            uint   retval  = Win32.CallNtPowerInformation(
                processorSpeedInformation,
                (IntPtr)null,
                (UInt32)0,
                CPUInfo,
                ProcessorSpeedArraySize);

            if (retval == 0)
            {
                IntPtr currentptr = ((IntPtr)CPUInfo);

                for (int i = 0; i < Environment.ProcessorCount; i++)
                {
                    PROCESSOR_POWER_INFORMATION ppi = (PROCESSOR_POWER_INFORMATION)Marshal.PtrToStructure(currentptr, typeof(PROCESSOR_POWER_INFORMATION));
                    currentptr = (IntPtr)((int)currentptr + Marshal.SizeOf(oneppi));
                    CPUspeeds.Add(ppi);
                }
            }
            Marshal.FreeCoTaskMem(CPUInfo);
            return(CPUspeeds);
        }
示例#2
0
        // Returns the Processor Spped information for the current processor
        internal static PROCESSOR_POWER_INFORMATION GetCurrentPowerInfoforProcessor()
        {
            PROCESSOR_POWER_INFORMATION ppi = new PROCESSOR_POWER_INFORMATION();
            ArrayList currentCPUspeeds;

            currentCPUspeeds = GetAllProcessorPowerInfo();
            uint currentCPUID = Win32.GetCurrentProcessorNumber();

            ppi = (PROCESSOR_POWER_INFORMATION)currentCPUspeeds[(int)currentCPUID];
            return(ppi);
        }
示例#3
0
        public void Stop()
        {
            // Calling stop on a stopped Stopwatch is a no-op.
            if (isRunning)
            {
                long endTimeStamp = 0;
                endTimeStamp = GetTimestamp();

                if (CPUTimeIsAvailable)
                {
                    timerEndThreadHandle = Win32.GetCurrentThread();
                    long endCPUcycles = GetCPUCycles(); //Get CPU Cycles first

                    if (timerEndThreadHandle != timerStartThreadHandle)
                    {
                        threadSwitchOccurred = true; //A thread switch is a problem, since CPU Cycles are accumulated
                        endCPUcycles         = 0;    // at the thread level
                        startCPUcycles       = 0;
                    }
                    else
                    {
                        if (endCPUcycles > startCPUcycles)
                        {
                            elapsedCPUThisPeriod = endCPUcycles - startCPUcycles;
                            elapsedCPU          += elapsedCPUThisPeriod;
                        }
                        //How likely is it for the CPU time accumulator to wrap???
                        else
                        {
                            elapsedCPU     = 0;
                            endCPUcycles   = 0;
                            startCPUcycles = 0;
                        }
                    }
                }

                long elapsedThisPeriod = endTimeStamp - startTimeStamp;
                elapsed  += elapsedThisPeriod;
                isRunning = false;
                if (elapsed < 0)
                {
                    // When measuring small time periods the StopWatch.Elapsed*
                    // properties can return negative values.  This is due to
                    // bugs in the basic input/output system (BIOS) or the hardware
                    // abstraction layer (HAL) on machines with variable-speed CPUs
                    // (e.g. Intel SpeedStep).

                    elapsed = 0;
                }

                if (CPUTimeIsAvailable && elapsedCPU > 0)
                {
                    timerEndCPUID = Win32.GetCurrentProcessorNumber();
                    if (timerEndCPUID != timerStartCPUID)
                    {
                        // Exposed as the FinishedOnDifferentProcessor property
                        // Stopwatch cannot detect context switches in general,
                        // but we do know at least one context switch occurred in this case
                        //
                        cpuSwitchOccurred = true;
                    }
                    PROCESSOR_POWER_INFORMATION thisppi = CPUPowerWrapper.GetCurrentPowerInfoforProcessor();
                    timerEndCurrentMHz = thisppi.CurrentMhz;
                    timerEndMaxMHz     = thisppi.MaxMhz;
                    if (timerStartCurrentMHz != timerEndCurrentMHz)     // CPU speed change detected
                    {
                        // Exposed as the PowerManagementChangeOccurred property
                        // so long as the rdtsc is constant across power management events,
                        // this is no cause for concern
                        cpuspeedChangeOccurred = true;
                    }
                }
            }
        }