View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0001286 | JEDI VCL | 00 JVCL Components | public | 2004-01-15 01:04 | 2004-03-09 02:46 |
| Reporter | anonymous | Assigned To | remkobonte | ||
| Priority | normal | Severity | block | Reproducibility | always |
| Status | closed | Resolution | duplicate | ||
| Product Version | |||||
| Target Version | Fixed in Version | ||||
| Summary | 0001286: division by zero on fast machines | ||||
| Description | Error 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 | ||||
| Tags | No tags attached. | ||||
|
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;
|
|
|
Duplicate of 0001023 and many other reports. |