Skip to content

Commit

Permalink
enhanced CPU/cache information retrieval
Browse files Browse the repository at this point in the history
- if no CPU is detected, a generic name is used, with known HW abilities on ARM (has been observed with a VM on Apple M1)
- retrieve the cache info on Darwin/MacOS
  • Loading branch information
Arnaud Bouchez committed Feb 8, 2022
1 parent ef60583 commit 43c47fa
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 23 deletions.
11 changes: 5 additions & 6 deletions src/core/mormot.core.os.pas
Expand Up @@ -591,15 +591,14 @@ EOSException = class(Exception);
// - contains e.g. 'LENOVO 20HES23B0U ThinkPad T470'
BiosInfoText: RawUtf8;

{$ifdef OSWINDOWS}
/// Level 1 to 4 CPU caches as returned by GetLogicalProcessorInformation
// - yes, Intel introduced a Level 4 cache (eDRAM) with some Haswell/Iris CPUs
// - we don't retrieve this information from Linux / POSIX yet
// - this information is not retrieved on all Linux / POSIX systems yet
// - only Unified or Data caches are include (not Instruction or Trace)
// - note: some CPU - like the Apple M1 - have 128 bytes of LineSize
CpuCache: array[1..4] of record
Count, Size, LineSize: cardinal;
end;
{$endif OSWINDOWS}

{$ifdef OSLINUXANDROID}
/// contains the Flags: or Features: value of Linux /proc/cpuinfo
Expand Down Expand Up @@ -4190,13 +4189,13 @@ procedure RaiseLastModuleError(ModuleName: PChar; ModuleException: ExceptClass);

function Unicode_CodePage: integer;
begin
{$ifdef FPC}
{$ifdef FPC}
// = GetSystemCodePage on POSIX, Lazarus may override to UTF-8 on Windows
result := DefaultSystemCodePage;
{$else}
{$else}
// Delphi always uses the main Windows System Code Page
result := GetACP;
{$endif FPC}
{$endif FPC}
end;

function Unicode_CompareString(PW1, PW2: PWideChar; L1, L2: PtrInt;
Expand Down
64 changes: 47 additions & 17 deletions src/core/mormot.core.os.posix.inc
Expand Up @@ -2262,6 +2262,8 @@ function getpagesize: integer; cdecl; external clib;

{$ifdef OSLINUX}

function get_nprocs: integer; cdecl; external clib;

procedure SetLinuxDistrib(const release: RawUtf8);
var
distrib: TOperatingSystem;
Expand Down Expand Up @@ -2440,6 +2442,25 @@ procedure crc32blocksarm64(crc128, data128: PBlock128; count: integer); external

{$endif CPUAARCH64}

function KB(Size: cardinal): shortstring;
begin
if Size >= 1 shl 30 then
begin
str(Size shr 30, result);
result := result + 'GB';
end
else if Size >= 1 shl 20 then
begin
str(Size shr 20, result);
result := result + 'MB';
end
else
begin
str(Size shr 10, result);
result := result + 'KB';
end
end;

procedure InitializeSpecificUnit;
var
P: PAnsiChar;
Expand Down Expand Up @@ -2482,6 +2503,17 @@ begin
modname := fpsysctlhwstr(HW_MODEL, temp);
with uts do
OSVersionText := sysname + '-' + release + ' ' + version;
{$ifdef OSDARWIN}
CpuCache[1].LineSize := fpsysctlhwint(HW_CACHELINE);
CpuCache[1].Size := fpsysctlhwint(HW_L1DCACHESIZE);
CpuCache[2].LineSize := fpsysctlhwint(HW_CACHELINE);
CpuCache[2].Size := fpsysctlhwint(HW_L2CACHESIZE);
CpuCacheSize := CpuCache[2].Size;
if CpuCacheSize = 0 then
CpuCacheSize := CpuCache[1].Size;
if CpuCacheSize <> 0 then
CpuCacheText := 'L1=' + KB(CpuCache[1].Size) + ' L2=' + KB(CpuCache[2].Size);
{$endif OSDARWIN}
{$else}
{$ifdef OSANDROID}
release := GetSystemProperty('ro.build.version.release');
Expand Down Expand Up @@ -2606,30 +2638,19 @@ begin
CpuCacheSize := GetNextCardinal(cache);
while cache^ = ' ' do
inc(cache);
case cache^ of
'k',
case upcase(cache^) of
'K':
CpuCacheSize := CpuCacheSize shl 10;
'm',
'M':
CpuCacheSize := CpuCacheSize shl 20;
'g',
'G':
CpuCacheSize := CpuCacheSize shl 30;
end;
if CpuCacheSize < 1 shl 20 then
begin
str(CpuCacheSize shr 10, CpuInfoText);
CpuInfoText := CpuInfoText + 'KB cache';
end
else
begin
str(CpuCacheSize shr 20, CpuInfoText);
CpuInfoText := CpuInfoText + 'MB cache';
end;
end;
SystemInfo.release := release;
{$endif OSBSDDARWIN}
if CpuCacheSize <> 0 then
CpuInfoText := KB(CpuCacheSize) + ' cache';
SystemInfo.uts.release := uts.Release;
SystemInfo.uts.sysname := uts.Sysname;
SystemInfo.uts.version := uts.Version;
Expand All @@ -2638,16 +2659,25 @@ begin
GetNextCardinal(P) shl 8 +
GetNextCardinal(P);
OSVersion32.os := OS_KIND;
MoveSmall(@KernelRevision, @OSVersion32.utsrelease, SizeOf(OSVersion32.utsrelease));
MoveSmall(@KernelRevision, @OSVersion32.utsrelease, 3); // 24-bit version
with SystemInfo.uts do
OSVersionText := sysname + ' ' + release;
if SystemInfo.release <> '' then
OSVersionText := SystemInfo.release + ' - ' + OSVersionText;
{$ifdef OSANDROID}
OSVersionText := 'Android (' + OSVersionText + ')';
{$else}
{$ifdef OSLINUX}
if SystemInfo.dwNumberOfProcessors = 0 then // e.g. QEMU limited /proc/cpuinfo
SystemInfo.dwNumberOfProcessors := get_nprocs;
{$endif OSLINUX}
{$endif OSANDROID}
if (SystemInfo.dwNumberOfProcessors > 0) and
(modname <> nil) then
if SystemInfo.dwNumberOfProcessors = 0 then
SystemInfo.dwNumberOfProcessors := 1;
if modname = nil then
CpuInfoText := Format('%d x generic ' + CPU_ARCH_TEXT + ' cpu %s',
[SystemInfo.dwNumberOfProcessors, CpuInfoText])
else
CpuInfoText := Format('%d x %s %s (' + CPU_ARCH_TEXT + ')',
[SystemInfo.dwNumberOfProcessors, modname, CpuInfoText]);
if CpuInfoText = '' then
Expand Down
12 changes: 12 additions & 0 deletions src/crypt/mormot.crypt.core.pas
Expand Up @@ -10420,6 +10420,7 @@ procedure InitializeUnit;
rk: TKeyArray;
bi, bo: TAesBlock;
shablock: array[0..63] of byte;
i: PtrInt;
{$endif USEARMCRYPTO}
begin
ComputeAesStaticTables;
Expand Down Expand Up @@ -10492,6 +10493,17 @@ procedure InitializeUnit;
// ARMv8 SHA HW opcodes seem not available
exclude(CpuFeatures, ahcSha2);
end;
i := PosEx('x generic', CpuInfoText);
if i <> 0 then
begin // some VM/QEMU software don't actually return a proper CPU name
inc(i, 9);
if ahcCRC32 in CpuFeatures then
insert(' crc', CpuInfoText, i);
if ahcSha2 in CpuFeatures then
insert(' sha', CpuInfoText, i);
if ahcAes in CpuFeatures then
insert(' aes', CpuInfoText, i);
end;
{$endif USEARMCRYPTO}
assert(SizeOf(TMd5Buf) = SizeOf(TMd5Digest));
assert(SizeOf(TAes) = AES_CONTEXT_SIZE);
Expand Down

0 comments on commit 43c47fa

Please sign in to comment.