libmeminfo: Add support to read zram memory consumption

Bug: 114325007
Bug: 111694435
Test: libmeminfo_test 1 --gtest_filter=SysMemInfoParse.TestZramTotal
Benchmark: libmeminfo_benchmark --benchmark_filter=BM_.*ZramTotal
Benchmark Result on Blueline:
-----------------------------------------------------------
Benchmark                    Time           CPU Iterations
-----------------------------------------------------------
BM_OldReadZramTotal       3857 ns       3839 ns     134096
BM_NewReadZramTotal       4461 ns       4440 ns     157341

Change-Id: I5220fa17b101981ef859179960fe78fe68e84852
Signed-off-by: Sandeep Patil <[email protected]>
diff --git a/libmeminfo_benchmark.cpp b/libmeminfo_benchmark.cpp
index e2239f0..1db0824 100644
--- a/libmeminfo_benchmark.cpp
+++ b/libmeminfo_benchmark.cpp
@@ -17,6 +17,8 @@
 #include <meminfo/sysmeminfo.h>
 
 #include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
@@ -46,7 +48,7 @@
     MEMINFO_COUNT
 };
 
-void get_mem_info(uint64_t mem[], const char* file) {
+static void get_mem_info(uint64_t mem[], const char* file) {
     char buffer[4096];
     unsigned int numFound = 0;
 
@@ -67,9 +69,10 @@
     buffer[len] = 0;
 
     static const char* const tags[] = {
-            "MemTotal:",     "MemFree:",    "Buffers:",     "Cached:",       "Shmem:", "Slab:",
-            "SReclaimable:", "SUnreclaim:", "SwapTotal:",   "SwapFree:",     "ZRam:",  "Mapped:",
-            "VmallocUsed:",  "PageTables:", "KernelStack:", NULL};
+            "MemTotal:",     "MemFree:",    "Buffers:",     "Cached:",   "Shmem:", "Slab:",
+            "SReclaimable:", "SUnreclaim:", "SwapTotal:",   "SwapFree:", "ZRam:",  "Mapped:",
+            "VmallocUsed:",  "PageTables:", "KernelStack:", NULL
+    };
 
     static const int tagsLen[] = {9, 8, 8, 7, 6, 5, 13, 11, 10, 9, 5, 7, 12, 11, 12, 0};
 
@@ -78,7 +81,8 @@
     while (*p && (numFound < (sizeof(tagsLen) / sizeof(tagsLen[0])))) {
         int i = 0;
         while (tags[i]) {
-            //std::cout << "tag =" << tags[i] << " p = " << std::string(p, tagsLen[i]) << std::endl;
+            // std::cout << "tag =" << tags[i] << " p = " << std::string(p, tagsLen[i]) <<
+            // std::endl;
             if (strncmp(p, tags[i], tagsLen[i]) == 0) {
                 p += tagsLen[i];
                 while (*p == ' ') p++;
@@ -214,4 +218,51 @@
 }
 BENCHMARK(BM_ReadMemInfo);
 
+static uint64_t get_zram_mem_used(const std::string& zram_dir) {
+    FILE* f = fopen((zram_dir + "mm_stat").c_str(), "r");
+    if (f) {
+        uint64_t mem_used_total = 0;
+
+        int matched = fscanf(f, "%*d %*d %" SCNu64 " %*d %*d %*d %*d", &mem_used_total);
+        if (matched != 1)
+            fprintf(stderr, "warning: failed to parse %s\n", (zram_dir + "mm_stat").c_str());
+
+        fclose(f);
+        return mem_used_total;
+    }
+
+    f = fopen((zram_dir + "mem_used_total").c_str(), "r");
+    if (f) {
+        uint64_t mem_used_total = 0;
+
+        int matched = fscanf(f, "%" SCNu64, &mem_used_total);
+        if (matched != 1)
+            fprintf(stderr, "warning: failed to parse %s\n", (zram_dir + "mem_used_total").c_str());
+
+        fclose(f);
+        return mem_used_total;
+    }
+
+    return 0;
+}
+
+static void BM_OldReadZramTotal(benchmark::State& state) {
+    std::string exec_dir = ::android::base::GetExecutableDirectory();
+    std::string zram_mmstat_dir = exec_dir + "/testdata1/";
+    for (auto _ : state) {
+        uint64_t zram_total __attribute__((unused)) = get_zram_mem_used(zram_mmstat_dir) / 1024;
+    }
+}
+BENCHMARK(BM_OldReadZramTotal);
+
+static void BM_NewReadZramTotal(benchmark::State& state) {
+    std::string exec_dir = ::android::base::GetExecutableDirectory();
+    std::string zram_mmstat_dir = exec_dir + "/testdata1/";
+    ::android::meminfo::SysMemInfo mi;
+    for (auto _ : state) {
+        uint64_t zram_total __attribute__((unused)) = mi.mem_zram_kb(zram_mmstat_dir);
+    }
+}
+BENCHMARK(BM_NewReadZramTotal);
+
 BENCHMARK_MAIN();