public void Start() { // Calling start on a running Stopwatch is a no-op. if (!isRunning) { startTimeStamp = GetTimestamp(); if (CPUTimeIsAvailable) { //Remember the Thread ID, processor number & CurrentMHz timerStartThreadHandle = Win32.GetCurrentThread(); timerStartCPUID = Win32.GetCurrentProcessorNumber(); PROCESSOR_POWER_INFORMATION thisppi; thisppi = CPUPowerWrapper.GetCurrentPowerInfoforProcessor(); timerStartCurrentMHz = thisppi.CurrentMhz; timerEndCurrentMHz = thisppi.CurrentMhz; startCPUcycles = GetCPUCycles(); //CPU Cycles consumed by the thread up to this point elapsedCPUThisPeriod = 0; } isRunning = true; } }
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; } } } }