View Issue Details

IDProjectCategoryView StatusLast Update
0031137FPCRTLpublic2021-01-08 09:38
ReporterThaddy de Koning Assigned ToFlorian  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
PlatformarmhfOSRaspbian 
Product Version3.1.1 
Fixed in Version3.3.1 
Summary0031137: TThread.ProcessorCount and TThread.IsSingleProcessor give wrong results
DescriptionOn a RaspBerri Pi 3 the processor count should be 4 and IsSingleProcessor should be false, since it is a quad-core.

But the result is 1 resp. true.

So the class properties TThread.ProcessorCount and TThread.IsSingleProcessor give wrong results.
Steps To Reproduceprogram untitled;
{$ifdef fpc}{$mode delphi}{$H+}{$endif}
uses classes;

begin
  Writeln(TThread.ProcessorCount,' ' , TThread.IsSingleProcessor);
end.

---
renders: 1 TRUE


TagsNo tags attached.
Fixed in Revision48106
FPCOldBugId
FPCTarget-
Attached Files

Activities

Thaddy de Koning

2016-12-18 10:03

reporter   ~0096877

Last edited: 2016-12-18 10:10

View 2 revisions

It doesn't matter if you add cthreads and/or add IsMultiThreaded:= true;
It also does not matter if you derive a class and /or create it.
The result is wrong.

delfion

2016-12-18 10:40

reporter   ~0096879

In Linux this piece of code is executed on startup (threadh.inc):
{$ifndef HAS_GETCPUCOUNT}
    function GetCPUCount: LongWord;
      begin
        Result := 1;
      end;
{$endif}

Thaddy de Koning

2016-12-18 10:47

reporter   ~0096880

Last edited: 2016-12-18 10:52

View 3 revisions

Hmmmm ;) So it's a bug...? Because nixes have a CPU count.
e.g: cat /proc/cpuinfo or lscpu

Thaddy de Koning

2016-12-18 11:17

reporter   ~0096883

I fiddled something that I did before ( http://forum.lazarus-ide.org/index.php?topic=33125.0 ) and fiddled some more existing code.
Here's a result that caters multiple platforms:
---
program cpucount;
{$modeswitch result}
{$IF defined(windows)}
uses windows;
{$endif}

{$IF defined(darwin)}
uses ctypes, sysctl;
{$endif}

{$IFDEF Linux}
uses ctypes, initc;

const _SC_NPROCESSORS_ONLN = 83;
function sysconf(i: cint): clong; cdecl; external name 'sysconf';
{$ENDIF}


function GetLogicalCpuCount: integer;
// returns a good default for the number of threads on this system
{$IF defined(windows)}
//returns total number of processors available to system including logical hyperthreaded processors
var
  i: Integer;
  ProcessAffinityMask, SystemAffinityMask: DWORD_PTR;
  Mask: DWORD;
  SystemInfo: SYSTEM_INFO;
begin
  if GetProcessAffinityMask(GetCurrentProcess, ProcessAffinityMask, SystemAffinityMask)
  then begin
    Result := 0;
    for i := 0 to 31 do begin
      Mask := DWord(1) shl i;
      if (ProcessAffinityMask and Mask)<>0 then
        inc(Result);
    end;
  end else begin
    //can't get the affinity mask so we just report the total number of processors
    GetSystemInfo(SystemInfo);
    Result := SystemInfo.dwNumberOfProcessors;
  end;
end;
{$ELSEIF defined(UNTESTEDsolaris)}
  begin
    t = sysconf(_SC_NPROC_ONLN);
  end;
{$ELSEIF defined(freebsd) or defined(darwin)}
var
  mib: array[0..1] of cint;
  len: cint;
  t: cint;
begin
  mib[0] := CTL_HW;
  mib[1] := HW_NCPU;
  len := sizeof(t);
  fpsysctl(pchar(@mib), 2, @t, @len, Nil, 0);
  Result:=t;
end;
{$ELSEIF defined(linux)}
  begin
    Result:=sysconf(_SC_NPROCESSORS_ONLN);
  end;

{$ELSE}
  begin
    Result:=1;
  end;
{$ENDIF}
begin
  writeln(GetLogicalCpuCount);
end.

Thaddy de Koning

2016-12-18 11:17

reporter   ~0096884

Last edited: 2016-12-18 11:23

View 2 revisions

I don't know if that would be acceptable as a patch, though...
I can split it up in the inc files per platform.
Verified windows, mac and linux.

Sven Barth

2016-12-18 11:49

manager   ~0096889

The use of sysconf() is not acceptable on Linux as by default that target doesn't link to libc and with that change it would. You'll need to find out how sysconf() itself determines the amount of processors and use that.

Thaddy de Koning

2016-12-18 12:17

reporter   ~0096891

Last edited: 2016-12-18 12:36

View 3 revisions

Ok. Will do. I mean try. Atm these should not have been provided. Misleading.

Sven Barth

2016-12-18 19:41

manager   ~0096907

They were provided due to Delphi compatibility. If we wouldn't add them when the majority of the platforms don't have an implementation yet we wouldn't add most of the functions that depend on platform specific functionality...
Considering that the addition of ProcessorCount was already three years ago not many people seem to use it anyway...

Thaddy de Koning

2016-12-18 20:35

reporter   ~0096913

That does not surprise me (at all). I discovered the possibility by accident investigating class vars.

Issue History

Date Modified Username Field Change
2016-12-18 09:56 Thaddy de Koning New Issue
2016-12-18 10:03 Thaddy de Koning Note Added: 0096877
2016-12-18 10:10 Thaddy de Koning Note Edited: 0096877 View Revisions
2016-12-18 10:40 delfion Note Added: 0096879
2016-12-18 10:47 Thaddy de Koning Note Added: 0096880
2016-12-18 10:51 Thaddy de Koning Note Edited: 0096880 View Revisions
2016-12-18 10:52 Thaddy de Koning Note Edited: 0096880 View Revisions
2016-12-18 11:17 Thaddy de Koning Note Added: 0096883
2016-12-18 11:17 Thaddy de Koning Note Added: 0096884
2016-12-18 11:23 Thaddy de Koning Note Edited: 0096884 View Revisions
2016-12-18 11:49 Sven Barth Note Added: 0096889
2016-12-18 12:17 Thaddy de Koning Note Added: 0096891
2016-12-18 12:35 Thaddy de Koning Note Edited: 0096891 View Revisions
2016-12-18 12:36 Thaddy de Koning Note Edited: 0096891 View Revisions
2016-12-18 19:41 Sven Barth Note Added: 0096907
2016-12-18 20:35 Thaddy de Koning Note Added: 0096913
2021-01-08 09:38 Florian Assigned To => Florian
2021-01-08 09:38 Florian Status new => resolved
2021-01-08 09:38 Florian Resolution open => fixed
2021-01-08 09:38 Florian Fixed in Version => 3.3.1
2021-01-08 09:38 Florian Fixed in Revision => 48106
2021-01-08 09:38 Florian FPCTarget => -