View Issue Details

IDProjectCategoryView StatusLast Update
0001286JEDI VCL00 JVCL Componentspublic2004-03-09 02:46
ReporteranonymousAssigned Toremkobonte 
PrioritynormalSeverityblockReproducibilityalways
Status closedResolutionduplicate 
Product Version 
Target VersionFixed in Version 
Summary0001286: division by zero on fast machines
DescriptionError appeared on new computer P4 2.6 GHz when application strated to report critical error division by zero on application start.
I have found that the reason is caused in
unit JclSysInfo
function GetCPUSpeed
lines Freq3 := Round((TotalCycles * 10) / TotalTicks);
and other where TotalTicks is zero.
After I have made changes in source code (see attached file), application started to work as usual.
pavel.vrecion@tiscali.cz
TagsNo tags attached.

Relationships

duplicate of 0001023 closedobones Nullpointer exception in jvcl200_d70 

Activities

2004-01-15 01:04

 

jclbug.txt (5,553 bytes)
unit JclSysInfo;

.....

Current function version:

//--------------------------------------------------------------------------------------------------

function GetCPUSpeed(var CpuSpeed: TFreqInfo): Boolean;
var
  T0, T1: TULargeInteger;
  CountFreq: TULargeInteger;
  Freq, Freq2, Freq3, Total: Integer;
  TotalCycles, Cycles: Int64;
  Stamp0, Stamp1: Int64;
  TotalTicks, Ticks: Cardinal;
  Tries, Priority: Integer;
  Thread: THandle;
begin
  Stamp0 := 0;
  Stamp1 := 0;
  Freq  := 0;
  Freq2 := 0;
  Freq3 := 0;
  Tries := 0;
  TotalCycles := 0;
  TotalTicks := 0;
  Total := 0;

  Thread := GetCurrentThread();
  Result := QueryPerformanceFrequency(Int64(CountFreq));
  if Result then
  begin
    while ((Tries < 3 ) or ((Tries < 20) and ((Abs(3 * Freq - Total) > 3) or
      (Abs(3 * Freq2 - Total) > 3) or (Abs(3 * Freq3 - Total) > 3)))) do
    begin
      Inc(Tries);
      Freq3 := Freq2;
      Freq2 := Freq;
      QueryPerformanceCounter(Int64(T0));
      T1.LowPart := T0.LowPart;
      T1.HighPart := T0.HighPart;

      Priority := GetThreadPriority(Thread);
      if Priority <> THREAD_PRIORITY_ERROR_RETURN then
        SetThreadPriority(Thread, THREAD_PRIORITY_TIME_CRITICAL);
      try
        while (T1.LowPart - T0.LowPart) < 50 do
        begin
          QueryPerformanceCounter(Int64(T1));
          Stamp0 := ReadTimeStampCounter;
        end;
        T0.LowPart := T1.LowPart;
        T0.HighPart := T1.HighPart;

        while (T1.LowPart - T0.LowPart) < 1000 do
        begin
          QueryPerformanceCounter(Int64(T1));
          Stamp1 := ReadTimeStampCounter;
        end;
      finally
        if Priority <> THREAD_PRIORITY_ERROR_RETURN then
          SetThreadPriority(Thread, Priority);
      end;

      Cycles := Stamp1 - Stamp0;
      Ticks := T1.LowPart - T0.LowPart;
      Ticks := Ticks * 100000;
      Ticks := Round(Ticks / (CountFreq.LowPart / 10));
      TotalTicks := TotalTicks + Ticks;
      TotalCycles := TotalCycles + Cycles;
      Freq := Round(Cycles / Ticks);
      Total := Freq + Freq2 + Freq3;
    end;
    Freq3 := Round((TotalCycles * 10) / TotalTicks);
    Freq2 := Round((TotalCycles * 100) / TotalTicks);

    if Freq2 - (Freq3 * 10) >= 6 then
      Inc(Freq3);

    CpuSpeed.RawFreq := Round(TotalCycles / TotalTicks);
    CpuSpeed.NormFreq := CpuSpeed.RawFreq;

    Freq := CpuSpeed.RawFreq * 10;
    if (Freq3 - Freq) >= 6 then
      Inc(CpuSpeed.NormFreq);

    CpuSpeed.ExTicks := TotalTicks;
    CpuSpeed.InCycles := TotalCycles;

    CpuSpeed.NormFreq := RoundFrequency(CpuSpeed.NormFreq);
    Result := True;
  end;
end;

Repaired function version:

//--------------------------------------------------------------------------------------------------

function GetCPUSpeed(var CpuSpeed: TFreqInfo): Boolean;
var
  T0, T1: TULargeInteger;
  CountFreq: TULargeInteger;
  Freq, Freq2, Freq3, Total: Integer;
  TotalCycles, Cycles: Int64;
  Stamp0, Stamp1: Int64;
  TotalTicks, Ticks: Cardinal;
  Tries, Priority: Integer;
  Thread: THandle;
begin
  Stamp0 := 0;
  Stamp1 := 0;
  Freq  := 0;
  Freq2 := 0;
  Freq3 := 0;
  Tries := 0;
  TotalCycles := 0;
  TotalTicks := 0;
  Total := 0;

  Thread := GetCurrentThread();
  Result := QueryPerformanceFrequency(Int64(CountFreq));
  if Result then
  begin
    while ((Tries < 3 ) or ((Tries < 20) and ((Abs(3 * Freq - Total) > 3) or
      (Abs(3 * Freq2 - Total) > 3) or (Abs(3 * Freq3 - Total) > 3)))) do
    begin
      Inc(Tries);
      Freq3 := Freq2;
      Freq2 := Freq;
      QueryPerformanceCounter(Int64(T0));
      T1.LowPart := T0.LowPart;
      T1.HighPart := T0.HighPart;

      Priority := GetThreadPriority(Thread);
      if Priority <> THREAD_PRIORITY_ERROR_RETURN then
        SetThreadPriority(Thread, THREAD_PRIORITY_TIME_CRITICAL);
      try
        while (T1.LowPart - T0.LowPart) < 50 do
        begin
          QueryPerformanceCounter(Int64(T1));
          Stamp0 := ReadTimeStampCounter;
        end;
        T0.LowPart := T1.LowPart;
        T0.HighPart := T1.HighPart;

        while (T1.LowPart - T0.LowPart) < 1000 do
        begin
          QueryPerformanceCounter(Int64(T1));
          Stamp1 := ReadTimeStampCounter;
        end;
      finally
        if Priority <> THREAD_PRIORITY_ERROR_RETURN then
          SetThreadPriority(Thread, Priority);
      end;

      Cycles := Stamp1 - Stamp0;
      Ticks := T1.LowPart - T0.LowPart;
      Ticks := Ticks * 100000;
      Ticks := Round(Ticks / (CountFreq.LowPart / 10));
      TotalTicks := TotalTicks + Ticks;
      TotalCycles := TotalCycles + Cycles;
      if Ticks>0
       then Freq := Round(Cycles / Ticks)
       else Freq := 0;
      Total := Freq + Freq2 + Freq3;
    end;
    if TotalTicks>0
     then Freq3 := Round((TotalCycles * 10) / TotalTicks)
     else Freq3 := 0;
    if TotalTicks>0
     then Freq2 := Round((TotalCycles * 100) / TotalTicks)
     else Freq2 := 0;

    if Freq2 - (Freq3 * 10) >= 6 then
      Inc(Freq3);

    if TotalTicks>0
     then CpuSpeed.RawFreq := Round(TotalCycles / TotalTicks)
     else CpuSpeed.RawFreq := 0;
    CpuSpeed.NormFreq := CpuSpeed.RawFreq;

    Freq := CpuSpeed.RawFreq * 10;
    if (Freq3 - Freq) >= 6 then
      Inc(CpuSpeed.NormFreq);

    CpuSpeed.ExTicks := TotalTicks;
    CpuSpeed.InCycles := TotalCycles;

    CpuSpeed.NormFreq := RoundFrequency(CpuSpeed.NormFreq);
    Result := True;
  end;
end;

jclbug.txt (5,553 bytes)

remkobonte

2004-01-15 07:51

developer   ~0002797

Duplicate of 0001023 and many other reports.

Issue History

Date Modified Username Field Change
2004-03-09 02:46 user72 Status resolved => closed