Skip to content

Instantly share code, notes, and snippets.

@Xor-el
Last active February 25, 2019 07:47
Show Gist options
  • Save Xor-el/aeb711157551d0b071e474fc4a7e9360 to your computer and use it in GitHub Desktop.
Save Xor-el/aeb711157551d0b071e474fc4a7e9360 to your computer and use it in GitHub Desktop.
Get True CPU Count For Windows, Linux and MAC OSX
unit ULogicalCPUCount;
// http://wiki.lazarus.freepascal.org/Example_of_multi-threaded_application:_array_of_threads#1._Detect_number_of_cores_available.
{ Copyright (c) 2018 by Ugochukwu Mmaduekwe
Distributed under the MIT software license, see the accompanying file LICENSE
or visit http://www.opensource.org/licenses/mit-license.php.
}
{$IFDEF FPC}
{$MODE DELPHI}
{$HINTS OFF}
{$ENDIF FPC}
interface
{$IFDEF FPC}
{$IFDEF LINUX}
{$linklib c}
uses
ctypes;
{$ENDIF LINUX}
{$IFDEF WINDOWS}
uses
Windows;
{$ENDIF WINDOWS}
{$IF DEFINED(DARWIN) OR DEFINED(FREEBSD)}
uses
ctypes, sysctl;
{$ENDIF}
{$ENDIF FPC}
type
TLogicalCPUCount = class sealed(TObject)
public
//returns number of cores: a computer with two hyperthreaded cores will report 4
class function GetLogicalCPUCount(): Int32; static;
end;
implementation
{$IFDEF FPC}
{$IF DEFINED(LINUX)}
const
_SC_NPROCESSORS_ONLN = 83;
function sysconf(i: cint): clong; cdecl; external Name 'sysconf';
{$ENDIF LINUX}
{$ENDIF FPC}
{ TLogicalCPUCount }
class function TLogicalCPUCount.GetLogicalCPUCount(): Int32;
{$IFDEF FPC}
{$IFDEF WINDOWS}
var
LIdx: Int32;
LProcessAffinityMask, LSystemAffinityMask: DWORD_PTR;
LMask: DWORD;
LSystemInfo: SYSTEM_INFO;
{$ENDIF WINDOWS}
{$IF DEFINED(DARWIN) OR DEFINED(FREEBSD)}
var
LMib: array[0..1] of cint;
Llen, Lt: cint;
{$ENDIF}
{$ENDIF FPC}
begin
{$IFNDEF FPC}
// For Delphi
Result := System.CPUCount;
{$ELSE}
{$IF DEFINED(WINDOWS)}
//returns total number of processors available to system including logical hyperthreaded processors
if GetProcessAffinityMask(GetCurrentProcess, LProcessAffinityMask,
LSystemAffinityMask) then
begin
Result := 0;
for LIdx := 0 to 31 do
begin
LMask := DWORD(1) shl LIdx;
if (LProcessAffinityMask and LMask) <> 0 then
begin
System.Inc(Result);
end;
end;
end
else
begin
// can't get the affinity mask so we just report the total number of processors
GetSystemInfo(LSystemInfo);
Result := LSystemInfo.dwNumberOfProcessors;
end;
{$ELSEIF DEFINED(DARWIN) OR DEFINED(FREEBSD)}
LMib[0] := CTL_HW;
LMib[1] := HW_NCPU;
Llen := System.SizeOf(Lt);
{$IF DEFINED(VER3_0_0) OR DEFINED(VER3_0_2)}
fpsysctl(PChar(@LMib), 2, @Lt, @Llen, nil, 0);
{$ELSE}
fpsysctl(@LMib, 2, @Lt, @Llen, nil, 0);
{$ENDIF}
Result := Lt;
{$ELSEIF DEFINED(LINUX)}
Result := sysconf(_SC_NPROCESSORS_ONLN);
{$ELSE}
// Fallback for other platforms
Result := 1;
{$ENDIF WINDOWS}
{$ENDIF FPC}
end;
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment