Last active
February 25, 2019 07:47
-
-
Save Xor-el/aeb711157551d0b071e474fc4a7e9360 to your computer and use it in GitHub Desktop.
Get True CPU Count For Windows, Linux and MAC OSX
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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