healthMonitor: use MemAvailable for memory utilzation calculation

We notice the memory utilization can easily reach 95% or higher when
large files are being readed, and most memories are consumed by
filesystem as file cache.

In current memory utilizaion calculation, it calculate "total - free"
as uesd memory size, which includes buff/cache as part of used memory.

Convert method to get MemAvailable and MemTotal by parsing from
/proc/meminfo, then calculate "unavailable" memory percentage
for memory utilization.

Tested results:

root@bletchley:~# free
              total        used        free      shared  buff/cache   available
Mem:        2066620      247320       59108       34412     1760192     1713028
Swap:             0           0           0

root@bletchley:~# busctl introspect xyz.openbmc_project.HealthMon \
> /xyz/openbmc_project/sensors/utilization/Memory \
> xyz.openbmc_project.Sensor.Value
NAME                             TYPE      SIGNATURE RESULT/VALUE                             FLAGS
.MaxValue                        property  d         100                                      emits-change writable
.MinValue                        property  d         0                                        emits-change writable
.Unit                            property  s         "xyz.openbmc_project.Sensor.Value.Uni... emits-change writable
.Value                           property  d         14.9148                                  emits-change writable

Signed-off-by: Potin Lai <potin.lai@quantatw.com>
Change-Id: Ib87edb313bcfbdae1306847babc4c7a5d96766f9
diff --git a/healthMonitor.cpp b/healthMonitor.cpp
index 3c5cd89..aaa27ee 100644
--- a/healthMonitor.cpp
+++ b/healthMonitor.cpp
@@ -143,22 +143,44 @@
 {
     /* Unused var: path */
     std::ignore = path;
-    struct sysinfo s_info;
+    std::ifstream meminfo("/proc/meminfo");
+    std::string line;
+    double memTotal = -1;
+    double memAvail = -1;
 
-    sysinfo(&s_info);
-    double usedRam = s_info.totalram - s_info.freeram;
-    double memUsePerc = usedRam / s_info.totalram * 100;
+    while (std::getline(meminfo, line))
+    {
+        std::string name;
+        double value;
+        std::istringstream iss(line);
+
+        if (!(iss >> name >> value))
+        {
+            continue;
+        }
+
+        if (name.starts_with("MemTotal"))
+        {
+            memTotal = value;
+        }
+        else if (name.starts_with("MemAvailable"))
+        {
+            memAvail = value;
+        }
+    }
+
+    if (memTotal <= 0 || memAvail <= 0)
+    {
+        return std::numeric_limits<double>::quiet_NaN();
+    }
 
     if (DEBUG)
     {
-        std::cout << "Memory Utilization is " << memUsePerc << "\n";
-
-        std::cout << "TotalRam: " << s_info.totalram
-                  << " FreeRam: " << s_info.freeram << "\n";
-        std::cout << "UseRam: " << usedRam << "\n";
+        std::cout << "MemTotal: " << memTotal << " MemAvailable: " << memAvail
+                  << std::endl;
     }
 
-    return memUsePerc;
+    return (memTotal - memAvail) / memTotal * 100;
 }
 
 double readStorageUtilization(std::string path)