Recent

Author Topic: Total Memory and Availably Memory (cross platform)  (Read 1630 times)

jonnybravo

  • New Member
  • *
  • Posts: 13
Total Memory and Availably Memory (cross platform)
« on: March 26, 2022, 12:45:57 pm »
My apologies if this is not the right forum for my question.

Is there a preferred way to read Total Memory and Availably Memory, cross platform?

Thank you.


MarkMLl

  • Hero Member
  • *****
  • Posts: 6683
Re: Total Memory and Availably Memory (cross platform)
« Reply #1 on: March 26, 2022, 02:15:23 pm »
No, because they're meaningless quantities on systems which support virtual memory.

You might however find the amount currently allocated from e.g. https://www.freepascal.org/docs-html/current/rtl/system/getheapstatus.html useful or something like

Code: Pascal  [Select][+][-]
  1. (* This replaces Delphi's original variable which is now obsolete, there is no
  2.   equivalent to AllocMemCount.
  3. *)
  4. function AllocMemSize(): QWord;
  5.  
  6. begin
  7.   with GetFPCHeapStatus do
  8.     result := CurrHeapUsed
  9. end { AllocMemSize } ;
  10.  

Also familiarise yourself with use of the HeapTrc unit.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

PascalDragon

  • Hero Member
  • *****
  • Posts: 5469
  • Compiler Developer
Re: Total Memory and Availably Memory (cross platform)
« Reply #2 on: March 27, 2022, 11:26:03 am »
@MarkMLI: I think jonnybravo might mean the system's available and total memory.

@jonnybravo: At least I don't know of anything preexisting, cross platform code. You'll have to research for each platform you want to support how to do this and then write such yourself I'm afraid.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6683
Re: Total Memory and Availably Memory (cross platform)
« Reply #3 on: March 27, 2022, 11:43:19 am »
@MarkMLI: I think jonnybravo might mean the system's available and total memory.

Yes he might: and it's still meaningless when a program can be running "in the cloud" and have its resources changed dynamically.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: Total Memory and Availably Memory (cross platform)
« Reply #4 on: March 27, 2022, 11:52:24 am »
This unit which I crafted for one of my applications is cross-platform. I haven't extracted the memory part separately, you'll have to do that. No pain. no gain :)

Code: Pascal  [Select][+][-]
  1. unit About_Unit2;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, FileInfo,
  9.   ExtCtrls
  10.   {$IFDEF DARWIN}
  11.   , Sysctl
  12.   {$ENDIF}
  13.   {$IFDEF UNIX}
  14.   , Unix
  15.   {$ENDIF}
  16.   {$IFDEF FREEBSD}
  17.   , SysCtl
  18.   {$ENDIF}
  19.   {$IFDEF WINDOWS}
  20.   , Windows, Win32Proc
  21.   {$ENDIF}
  22.   {$IFDEF LINUX}
  23.   , Linux, BaseUnix, CTypes
  24.   {$ENDIF}
  25.   , LCLIntf; // for OpenURL()
  26.  
  27. type
  28.  
  29.   { TForm2_About }
  30.  
  31.   TForm2_About = class(TForm)
  32.     InfoMemo: TMemo;
  33.     LicLabel2: TLabel;
  34.     MutexLabel: TLabel;
  35.     OK_Button: TButton;
  36.     Image1: TImage;
  37.     AppLabel: TLabel;
  38.     EvanLabel: TLabel;
  39.     VersionLabel: TLabel;
  40.     AuthorLabel: TLabel;
  41.     LicLabel1: TLabel;
  42.     LangLabel: TLabel;
  43.     AckLabel: TLabel;
  44.     CorbinLabel: TLabel;
  45.     MarkLabel: TLabel;
  46.     procedure FormActivate(Sender: TObject);
  47.     procedure FormCreate(Sender: TObject);
  48.     procedure FormShow(Sender: TObject);
  49.     procedure Image1Click(Sender: TObject);
  50.     procedure LicLabel2Click(Sender: TObject);
  51.     procedure LicLabel2MouseEnter(Sender: TObject);
  52.     procedure LicLabel2MouseLeave(Sender: TObject);
  53.     procedure OK_ButtonClick(Sender: TObject);
  54.   private
  55.  
  56.   public
  57.  
  58.   end;
  59.  
  60. var
  61.   Form2_About: TForm2_About;
  62.   FileVerInfo: TFileVersionInfo;
  63. implementation
  64.  
  65. {$R *.lfm}
  66.  
  67. { TForm2_About }
  68.  
  69. {$IFNDEF LINUX}
  70. {$IFNDEF WINDOWS}
  71. function HWmodel : AnsiString;
  72. var
  73.   mib : array[0..1] of Integer;
  74.   status : Integer;
  75.   len : size_t;
  76.   p   : PChar;
  77. begin
  78.  mib[0] := CTL_HW;
  79.  mib[1] := HW_MODEL;
  80.  
  81.  // find out the the length needed for the buffer
  82.  status := fpSysCtl(@mib, Length(mib), Nil, @len, Nil, 0);
  83.  if status <> 0 then RaiseLastOSError;
  84.  
  85.  // allocate the amount of memory discovered above for the buffer
  86.  GetMem(p, len);
  87.  
  88.  try
  89.    status := fpSysCtl(@mib, Length(mib), p, @len, Nil, 0);
  90.    if status <> 0 then RaiseLastOSError;
  91.    Result := p;
  92.  finally
  93.    FreeMem(p);
  94.  end;
  95. end;
  96.  
  97. {$IFDEF FREEBSD}
  98. function GetCPUarchitecture: AnsiString;
  99. var
  100.   status : Integer;
  101.   len : size_t;
  102.   p : PChar;
  103. begin
  104.   status := fpSysCtlByName('hw.machine_arch', Nil, @len, Nil, 0);
  105.   if status <> 0 then RaiseLastOSError;
  106.  
  107.   GetMem(p, len);
  108.  
  109.   try
  110.     status := fpSysCtlByName('hw.machine_arch', p, @len, Nil, 0);
  111.     if status <> 0 then RaiseLastOSError;
  112.     Result := p;
  113.   finally
  114.     FreeMem(p);
  115.   end;
  116. end;
  117. {$ENDIF}
  118.  
  119. function NumberOfCPU: Integer;
  120. var
  121. mib: array[0..1] of Integer;
  122.   status : Integer;
  123.   len : size_t;
  124. begin
  125.   mib[0] := CTL_HW;
  126.   mib[1] := HW_NCPU;
  127.   len := SizeOf(Result);
  128.   status := fpSysCtl(@mib, Length(mib), @Result, @len, Nil, 0);
  129.   if status <> 0 then RaiseLastOSError;
  130. end;
  131.  
  132. function NumberOfPkgCPU: Integer;
  133. var
  134.   status : Integer;
  135.   len : size_t;
  136. begin
  137.   len := SizeOf(Result);
  138.   status := fpSysCtlByName('hw.packages', @Result, @len, Nil, 0);
  139.   if status <> 0 then RaiseLastOSError;
  140. end;
  141.  
  142. function NumberOfPhysCPU: Integer;
  143. var
  144.   status : Integer;
  145.   len : size_t;
  146. begin
  147.   len := SizeOf(Result);
  148.   status := fpSysCtlByName('hw.physicalcpu', @Result, @len, Nil, 0);
  149.   if status <> 0 then RaiseLastOSError;
  150. end;
  151.  
  152. function NumberOfLogCPU: Integer;
  153. var
  154.   status : Integer;
  155.   len : size_t;
  156. begin
  157.   len := SizeOf(Result);
  158.   status := fpSysCtlByName('hw.logicalcpu', @Result, @len, Nil, 0);
  159.   if status <> 0 then RaiseLastOSError;
  160. end;
  161.  
  162. function GBMemorySize: Int64;
  163. var
  164. mib: array[0..1] of Integer;
  165.   status : Integer;
  166.   len : size_t;
  167. begin
  168.   mib[0] := CTL_HW;
  169.   {$IFDEF DARWIN}
  170.   mib[1] := HW_MEMSIZE;
  171.   {$ELSE}
  172.   mib[1] := HW_PHYSMEM;
  173.   {$ENDIF}
  174.   len := SizeOf(Result);
  175.   status := fpSysCtl(@mib, Length(mib), @Result, @len, Nil, 0);
  176.   if status <> 0 then RaiseLastOSError;
  177. end;
  178.  
  179. {$IFDEF DARWIN}
  180. function SwapUsage: String;
  181. type
  182.  swapinfo = record
  183.     xsu_total    : Int64;
  184.     xsu_avail    : Int64;
  185.     xsu_used     : Int64;
  186.     xsu_pagesize : Integer;
  187.     xsu_encrypted: Boolean;
  188. end;
  189.  
  190. var
  191.   mib : array[0..1] of Integer;
  192.   status : Integer;
  193.   len : size_t;
  194.   swap : swapinfo;
  195.   SwapEncrypted: String;
  196. begin
  197.   mib[0] := CTL_VM;
  198.   mib[1] := VM_SWAPUSAGE;
  199.   swap := Default(swapinfo);
  200.  
  201.   FillChar(swap, sizeof(swap), 0);
  202.   len := sizeof(swap);
  203.  
  204.   status := fpSysCtl(@mib, Length(mib), @swap, @len, Nil, 0);
  205.   if status <> 0 then RaiseLastOSError;
  206.  
  207.   if(swap.xsu_encrypted = true) then
  208.     SwapEncrypted := 'Yes' else SwapEncrypted := 'No';
  209.  
  210.   Result := 'Swap total: ' + FloatToStr(Round(swap.xsu_total /1024 /1024)) + ' MB'
  211.             + LineEnding + 'Swap used: ' + FloatToStr(Round(swap.xsu_used /1024 /1024)) + ' MB'
  212.             + LineEnding + 'Swap free: ' + FloatToStr(Round(swap.xsu_avail /1024 /1024)) + ' MB'
  213.             + LineEnding + 'Swap page size: ' + IntToStr(swap.xsu_pagesize) + ' bytes'
  214.             + LineEnding + 'Swap encrypted: ' + SwapEncrypted + LineEnding;
  215. end;
  216. {$ENDIF}
  217.  
  218. function MaxProcesses : Integer;
  219. var
  220.   mib : array[0..1] of Integer;
  221.   status : Integer;
  222.   len : size_t;
  223. begin
  224.   mib[0] := CTL_KERN;
  225.   mib[1] := KERN_MAXPROC;
  226.   len := sizeof(Result);
  227.   status := fpSysCtl(@mib, Length(mib), @Result, @len, Nil, 0);
  228.   if status <> 0 then RaiseLastOSError;
  229. end;
  230.  
  231. function BrandOfCPU: AnsiString;
  232. var
  233.   status : Integer;
  234.   len : size_t;
  235.   p : PChar;
  236. begin
  237.   status := fpSysCtlByName('machdep.cpu.brand_string', Nil, @len, Nil, 0);
  238.   if status <> 0 then RaiseLastOSError;
  239.  
  240.   GetMem(p, len);
  241.  
  242.   try
  243.     status := fpSysCtlByName('machdep.cpu.brand_string', p, @len, Nil, 0);
  244.     if status <> 0 then RaiseLastOSError;
  245.     Result := p;
  246.   finally
  247.     FreeMem(p);
  248.   end;
  249. end;
  250.  
  251. function KernelVersion : AnsiString;
  252. var
  253.   mib : array[0..1] of Integer;
  254.   status : Integer;
  255.   len : size_t;
  256.   p   : PChar;
  257. begin
  258.  mib[0] := CTL_KERN;
  259.  mib[1] := KERN_VERSION;
  260.  //get the length of the buffer
  261.  status := fpSysCtl(@mib, Length(mib), Nil, @len, Nil, 0);
  262.  if status<>0 then
  263.    RaiseLastOSError;
  264.  //allocates the buffer
  265.  GetMem(p, len);
  266.  try
  267.    status := fpSysCtl(@mib, Length(mib), p, @len, Nil, 0);
  268.    if status <> 0 then
  269.      RaiseLastOSError;
  270.    Result:=p;
  271.  finally
  272.    FreeMem(p);
  273.  end;
  274. end;
  275.  
  276. function GetClockInfo: String;
  277. type
  278.  clockinfo = record
  279.     hz      : Integer;  // clock frequency
  280.     tick    : Integer;  // ms per Hz tick
  281.     {$IFDEF DARWIN}
  282.     tickadj : Integer;  // clock skew rate
  283.     {$ENDIF}
  284.     {$IFDEF FREEBSD}
  285.     spare   : Integer;  // unused in FreeBSD
  286.     {$ENDIF}
  287.     stathz  : Integer;  // statistics clock frequency
  288.     profhz  : Integer;  // profiling clock frequency
  289.   end;
  290.  
  291. var
  292.  mib : array[0..1] of Integer;
  293.  status : Integer;
  294.  len : size_t;
  295.  clock : clockinfo;
  296. begin
  297.  mib[0] := CTL_KERN;
  298.  mib[1] := KERN_CLOCKRATE;
  299.  clock := Default(clockinfo);
  300.  
  301.  FillChar(clock, sizeof(clock), 0);
  302.  len := sizeof(clock);
  303.  
  304.  status := fpSysCtl(@mib, Length(mib), @clock, @len, Nil, 0);
  305.  if status <> 0 then RaiseLastOSError;
  306.  
  307.  Result := 'Clock freq: ' + IntToStr(clock.hz) + 'Hz' + LineEnding
  308.            + 'Ms per Hz tick: ' + IntToStr(clock.tick) + LineEnding
  309.            {$IFDEF DARWIN}
  310.            + 'Clock skew rate: ' + IntToStr(clock.tickadj) + LineEnding
  311.            {$ENDIF}
  312.            + 'Profiling clock freq: ' + IntToStr(clock.profhz) + ' Hz'
  313.            + LineEnding;
  314. end;
  315. {$ENDIF}
  316.  
  317. {$IFDEF WINDOWS}
  318. function GetLogicalCpuCount: Integer;
  319. var
  320.   SystemInfo: _SYSTEM_INFO;
  321. begin
  322.   GetSystemInfo(SystemInfo);
  323.   Result := SystemInfo.dwNumberOfProcessors;
  324. end;
  325.  
  326. function GetCPUType: String;
  327. var
  328.   SystemInfo: _SYSTEM_INFO;
  329. begin
  330.   GetSystemInfo(SystemInfo);
  331.   {386, 486, 586, 8664 (x86_64/AMD64)}
  332.   if(SystemInfo.dwProcessorType = 8664) then Result := 'x86_64'
  333.   else if(SystemInfo.dwProcessorType = 586) then Result := 'Pentium'
  334.   else if(SystemInfo.dwProcessorType = 486) then Result := '80486'
  335.   else if(SystemInfo.dwProcessorType = 386) then Result := '80386'
  336.   else Result := 'Unknown!';
  337. end;
  338.  
  339. function GetCPUArchitecture: String;
  340. var
  341.   SystemInfo: _SYSTEM_INFO;
  342. begin
  343.   GetSystemInfo(SystemInfo);
  344.  
  345.   if (SystemInfo.wProcessorArchitecture = 9) then Result := 'AMD64'
  346.   else if (SystemInfo.wProcessorArchitecture = 5) then Result := 'ARM'
  347.   else if (SystemInfo.wProcessorArchitecture = 12) then Result := 'ARM64'
  348.   else if (SystemInfo.wProcessorArchitecture = 0) then Result := 'Intel'
  349.   else Result := 'Unknown!'
  350. end;
  351.  
  352. function GetCPULevRev: String;
  353. var
  354.   SystemInfo: _SYSTEM_INFO;
  355. begin
  356.   GetSystemInfo(SystemInfo);
  357.  
  358.   Result := 'CPU Level: ' + IntToStr(SystemInfo.wProcessorLevel)
  359.         + LineEnding + 'CPU Revision: ' + IntToStr(SystemInfo.wProcessorRevision);
  360. end;
  361. {$ENDIF}
  362. {$ENDIF}
  363.  
  364. {$IFDEF LINUX}
  365. function sysconf(i:cint):clong;cdecl;external name 'sysconf';
  366. {$ENDIF}
  367.  
  368. procedure TForm2_About.OK_ButtonClick(Sender: TObject);
  369. begin
  370.   Close;
  371. end;
  372.  
  373. procedure TForm2_About.FormCreate(Sender: TObject);
  374. begin
  375.   FileVerInfo:=TFileVersionInfo.Create(Nil);
  376.   try
  377.     FileVerInfo.ReadFileInfo;
  378.     VersionLabel.Caption := 'Version: ' + FileVerInfo.VersionStrings.Values['FileVersion'];
  379.     //('Company: ',FileVerInfo.VersionStrings.Values['CompanyName']);
  380.     //('File description: ',FileVerInfo.VersionStrings.Values['FileDescription']);
  381.     //('File version: ',FileVerInfo.VersionStrings.Values['FileVersion']);
  382.     //('Internal name: ',FileVerInfo.VersionStrings.Values['InternalName']);
  383.     //('Legal copyright: ',FileVerInfo.VersionStrings.Values['LegalCopyright']);
  384.     //('Original filename: ',FileVerInfo.VersionStrings.Values['OriginalFilename']);
  385.     //('Product name: ',FileVerInfo.VersionStrings.Values['ProductName']);
  386.     //('Product version: ',FileVerInfo.VersionStrings.Values['ProductVersion']);
  387.   finally
  388.     FileVerInfo.Free;
  389.   end;
  390.  
  391.   // Darwin/Windows default Laz 2.1.0, FPC 3.3.1
  392.   {$IFDEF FREEBSD}
  393.   LangLabel.Caption := 'Programmed in Lazarus 2.1, FPC 3.3.1';
  394.   {$ENDIF}
  395.   {$IFDEF LINUX}
  396.   LangLabel.Caption := 'Programmed in Lazarus 2.1, FPC 3.0.4';
  397.   {$ENDIF}
  398.  
  399. end;
  400.  
  401. procedure TForm2_About.FormShow(Sender: TObject);
  402. begin
  403.   {$IFDEF DARWIN}
  404.   Form2_About.Height := 300;
  405.   {$ENDIF}
  406. end;
  407.  
  408.  
  409. procedure TForm2_About.Image1Click(Sender: TObject);
  410. {$IFDEF UNIX}
  411. {$IFNDEF LINUX}
  412. Var
  413.   ResInt: Int64;
  414.   ResStr: String;
  415. {$ENDIF}
  416. {$ENDIF}
  417. {$IFDEF WINDOWS}
  418. Var
  419.   Memory: TMemoryStatus;
  420. {$ENDIF}
  421. {$IFDEF LINUX}
  422. Var
  423.   KernelName: UtsName;
  424.   Info: TSysInfo;
  425. {$ENDIF}
  426. begin
  427.   if(InfoMemo.Visible = True) then
  428.     begin
  429.       InfoMemo.Visible := False;
  430.       InfoMemo.Text := '';
  431.       Exit;
  432.     end;
  433.  
  434.   {$IFDEF WINDOWS}
  435.   if WindowsVersion = wv95 then InfoMemo.Lines.Add('Windows 95')
  436.   else if WindowsVersion = wvNT4 then InfoMemo.Lines.Add('Windows NT v.4')
  437.   else if WindowsVersion = wv98 then InfoMemo.Lines.Add('Windows 98')
  438.   else if WindowsVersion = wvMe then InfoMemo.Lines.Add('Windows ME')
  439.   else if WindowsVersion = wv2000 then InfoMemo.Lines.Add('Windows 2000')
  440.   else if WindowsVersion = wvXP then InfoMemo.Lines.Add('Windows XP')
  441.   else if WindowsVersion = wvServer2003 then InfoMemo.Lines.Add('Windows Server 2003/Windows XP64')
  442.   else if WindowsVersion = wvVista then InfoMemo.Lines.Add('Windows Vista')
  443.   else if WindowsVersion = wv7 then InfoMemo.Lines.Add('Windows 7')
  444.   else if WindowsVersion = wv10 then InfoMemo.Lines.Add('Windows 10')
  445.   else InfoMemo.Lines.Add('Windows Unknown Version!');
  446.  
  447.   InfoMemo.Lines.Add('Logical CPU count: ' + IntToStr(GetLogicalCPUCount));
  448.   InfoMemo.Lines.Add('CPU type: ' + GetCPUType);
  449.   InfoMemo.Lines.Add('CPU architecture: ' + GetCPUArchitecture);
  450.   InfoMemo.Lines.Add(GetCPULevRev);
  451.  
  452.   Memory.dwLength := SizeOf(Memory);
  453.   GlobalMemoryStatus(Memory);
  454.   InfoMemo.Lines.Add(Format('Memory total: %f GB', [Memory.dwTotalPhys /1024 /1024 /1024]));
  455.   InfoMemo.Lines.Add(Format('Memory free: %f GB', [Memory.dwAvailPhys /1024 /1024 /1024]));
  456.   InfoMemo.Lines.Add(Format('Memory in use: %d%%', [Memory.dwMemoryLoad]));
  457.   InfoMemo.Lines.Add(Format('Pagefile size: %f GB', [Memory.dwTotalPageFile /1024 /1024 /1024]));
  458.   InfoMemo.Lines.Add(Format('Pagefile free: %f GB', [Memory.dwAvailPageFile /1024 /1024 /1024]));
  459.   InfoMemo.Lines.Add(Format('Virtual memory total: %f GB', [Memory.dwTotalVirtual /1024 /1024 /1024]));
  460.   InfoMemo.Lines.Add(Format('Virtual memory free: %f GB', [Memory.dwAvailVirtual /1024 /1024 /1024]));
  461.  
  462.   InfoMemo.Lines.Add(Format('Disk space total: %f GB', [DiskSize(0) /1024 /1024 /1024]));
  463.   InfoMemo.Lines.Add(Format('Disk space free: %f GB', [DiskFree(0) /1024 /1024 /1024]));
  464.   {$ENDIF}
  465.  
  466.   {$IFNDEF LINUX}
  467.   {$IFNDEF WINDOWS}
  468.   ResStr := HWmodel;
  469.   InfoMemo.Lines.Add('Hardware model: ' + ResStr);
  470.   {$IFDEF DARWIN}
  471.   ResStr := BrandOfCPU;
  472.   InfoMemo.Lines.Add(ResStr);
  473.   ResInt := NumberOfPkgCPU;
  474.   InfoMemo.Lines.Add('CPU packages: ' + IntToStr(ResInt));
  475.   ResInt := NumberOfPhysCPU;
  476.   InfoMemo.Lines.Add('CPU cores: ' + IntToStr(ResInt));
  477.   ResInt := NumberOfLogCPU;
  478.   InfoMemo.Lines.Add('CPU logical: ' + IntToStr(ResInt));
  479.   {$ENDIF}
  480.  
  481.   {$IFDEF FREEBSD}
  482.   InfoMemo.Lines.Add('CPU architecture: ' + GetCPUarchitecture);
  483.   {$ENDIF}
  484.  
  485.   ResInt := NumberOfCPU;
  486.   InfoMemo.Lines.Add('CPU threads: ' + IntToStr(ResInt));
  487.   InfoMemo.Lines.Add(' ');
  488.  
  489.   ResInt := Round(GBMemorySize);
  490.   InfoMemo.Lines.Add('Memory size: ' + IntToStr(Round(ResInt /1024 /1024 /1024)) + ' GB');
  491.   InfoMemo.Lines.Add(' ');
  492.  
  493.   {$IFDEF DARWIN}
  494.   InfoMemo.Lines.Add(SwapUsage);
  495.   {$ENDIF}
  496.  
  497.   InfoMemo.Lines.Add(GetClockInfo);
  498.  
  499.   ResStr := KernelVersion;
  500.   InfoMemo.Lines.Add(ResStr);
  501.   {$IFNDEF FREEBSD}
  502.   InfoMemo.Lines.Add(' ');
  503.   {$ENDIF}
  504.   ResInt := MaxProcesses;
  505.   InfoMemo.Lines.Add('Max processes: ' + IntToStr(ResInt));
  506.   {$ENDIF}
  507.   {$ENDIF}
  508.  
  509.   {$IFDEF LINUX}
  510.   fpuname(KernelName);
  511.   InfoMemo.Lines.Add('OS: ' + kernelname.sysname);
  512.   InfoMemo.Lines.Add('Hostname: ' + kernelname.nodename);
  513.   InfoMemo.Lines.Add('Release: ' + kernelname.release);
  514.   InfoMemo.Lines.Add('Kernel: ' + kernelname.version);
  515.   InfoMemo.Lines.Add('Architecture: ' + kernelname.machine);
  516.   InfoMemo.Lines.Add('');
  517.   InfoMemo.Lines.Add('CPU count: %d',  [SysConf(83)]);
  518.   InfoMemo.Lines.Add('CPU online: %d',  [SysConf(84)]);
  519.   SysInfo(@Info);
  520.   InfoMemo.Lines.Add('');
  521.   InfoMemo.Lines.Add('Total memory: %f GB', [Info.TotalRam /1024 /1024 /1024]);
  522.   InfoMemo.Lines.Add('Free memory: %f GB',  [Info.FreeRam /1024 /1024 /1024]);
  523.   InfoMemo.Lines.Add('Shared memory: %f GB',  [Info.SharedRam /1024 /1024 /1024]);
  524.   InfoMemo.Lines.Add('Buffer memory: %f GB',  [Info.BufferRam /1024 /1024 /1024]);
  525.   InfoMemo.Lines.Add('Total swap: %f GB', [Info.TotalSwap /1024 /1024 /1024]);
  526.   InfoMemo.Lines.Add('Free swap: %f GB', [Info.FreeSwap /1024 /1024 /1024]);
  527.   {$ENDIF}
  528.  
  529.   InfoMemo.Visible := True;
  530.   // Below needed or second time memo at bottom, not top
  531.   InfoMemo.VertScrollbar.Position := 1;
  532.   InfoMemo.VertScrollbar.Position := 0;
  533. end;
  534.  
  535. procedure TForm2_About.LicLabel2Click(Sender: TObject);
  536. begin
  537.   OpenURL('https://unlicense.org/');
  538. end;
  539.  
  540. procedure TForm2_About.LicLabel2MouseEnter(Sender: TObject);
  541. begin
  542.   Form2_About.LicLabel2.Cursor := crHandPoint;
  543.   Form2_About.LicLabel2.Font.Style := [fsUnderLine];
  544. end;
  545.  
  546. procedure TForm2_About.LicLabel2MouseLeave(Sender: TObject);
  547. begin
  548.   Form2_About.LicLabel2.Cursor := crDefault;
  549.   Form2_About.LicLabel2.Font.Style := [];
  550. end;
  551.  
  552. procedure TForm2_About.FormActivate(Sender: TObject);
  553. begin
  554.   {$IFDEF DARWIN}
  555.   // Make macOS-like About Box
  556.   Form2_About.BorderIcons := [biSystemMenu];
  557.   Form2_About.OK_Button.Visible := False;
  558.   Form2_About.Caption := '';
  559.   {$ENDIF}
  560.   {$IFDEF WINDOWS}
  561.   Form2_About.BorderIcons := [biSystemMenu];
  562.   Form2_About.OK_Button.Visible := True;
  563.   {$ENDIF}
  564. end;
  565.  
  566. end.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5469
  • Compiler Developer
Re: Total Memory and Availably Memory (cross platform)
« Reply #5 on: March 28, 2022, 01:24:29 pm »
@MarkMLI: I think jonnybravo might mean the system's available and total memory.

Yes he might: and it's still meaningless when a program can be running "in the cloud" and have its resources changed dynamically.

That depends upon the use case however. If the application is run on some cloud system with a remote UI or terminal access then of course it will display the information of the cloud system it's running on and not the own system. Depending on the use case this might or might not be what is desired. That's neither for me nor you to answer, but only for jonnybravo.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6683
Re: Total Memory and Availably Memory (cross platform)
« Reply #6 on: March 28, 2022, 02:24:24 pm »
That depends upon the use case however. If the application is run on some cloud system with a remote UI or terminal access then of course it will display the information of the cloud system it's running on and not the own system. Depending on the use case this might or might not be what is desired. That's neither for me nor you to answer, but only for jonnybravo.

Absolutely. But industry-wide- and irrespective of OS- we seem to be heading away from the traditional situation where resources are owned by a process to one where they're owned by a VM image or a Docker-style container, with external interfaces such as sockets being mapped and remapped by the host. And in this situation, as with earlier enterprise-grade OSes such as SunOS, resources can be added and removed or the host system partitioned on the fly with no clear mechanism to advise application code that something's changed.

I'm not confident that that's a particularly healthy situation. The hoops that things like Docker have to jump through are so tortuous that I'm coming to believe that it's time for a ground-up redesign.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018