libmeminfo: Add SmapsRollup
This adds the tests and SmapsRollup() parsing function in
ProcMemInfo. Adds tests to check the return value as well as
the correctness.
Bug: 111694435
Test: libmeminfo_test 1 --gtest_filter=TestProcMemInfo.*
Test: libmeminfo_benchmark --benchmark_filter=BM_SmapsRollup_
Result:
----------------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------------
BM_SmapsRollup_old 4751 ns 4730 ns 149458
BM_SmapsRollup_new 4858 ns 4837 ns 144636
----------------------------------------------------------
Change-Id: Ia051fe53a7622e3091502ff7166efafae35e7935
Signed-off-by: Sandeep Patil <sspatil@google.com>
diff --git a/libmeminfo_benchmark.cpp b/libmeminfo_benchmark.cpp
index e9cb763..81fc3b3 100644
--- a/libmeminfo_benchmark.cpp
+++ b/libmeminfo_benchmark.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <meminfo/procmeminfo.h>
#include <meminfo/sysmeminfo.h>
#include <fcntl.h>
@@ -31,6 +32,9 @@
#include <benchmark/benchmark.h>
+using ::android::meminfo::MemUsage;
+using ::android::meminfo::ProcMemInfo;
+using ::android::meminfo::SmapsOrRollupFromFile;
using ::android::meminfo::SysMemInfo;
enum {
@@ -457,4 +461,85 @@
}
BENCHMARK(BM_VmallocInfo_new);
+// This implementation is picked up as-is from frameworks/base/core/jni/android_os_Debug.cpp
+// and only slightly modified to use std:unique_ptr.
+static bool get_smaps_rollup(const std::string path, MemUsage* rollup) {
+ char lineBuffer[1024];
+ auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose};
+ if (fp != nullptr) {
+ char* line;
+ while (true) {
+ if (fgets(lineBuffer, sizeof(lineBuffer), fp.get()) == NULL) {
+ break;
+ }
+ line = lineBuffer;
+
+ switch (line[0]) {
+ case 'P':
+ if (strncmp(line, "Pss:", 4) == 0) {
+ char* c = line + 4;
+ while (*c != 0 && (*c < '0' || *c > '9')) {
+ c++;
+ }
+ rollup->pss += atoi(c);
+ } else if (strncmp(line, "Private_Clean:", 14) == 0 ||
+ strncmp(line, "Private_Dirty:", 14) == 0) {
+ char* c = line + 14;
+ while (*c != 0 && (*c < '0' || *c > '9')) {
+ c++;
+ }
+ rollup->uss += atoi(c);
+ }
+ break;
+ case 'R':
+ if (strncmp(line, "Rss:", 4) == 0) {
+ char* c = line + 4;
+ while (*c != 0 && (*c < '0' || *c > '9')) {
+ c++;
+ }
+ rollup->rss += atoi(c);
+ }
+ break;
+ case 'S':
+ if (strncmp(line, "SwapPss:", 8) == 0) {
+ char* c = line + 8;
+ long lSwapPss;
+ while (*c != 0 && (*c < '0' || *c > '9')) {
+ c++;
+ }
+ lSwapPss = atoi(c);
+ rollup->swap_pss += lSwapPss;
+ }
+ break;
+ }
+ }
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+static void BM_SmapsRollup_old(benchmark::State& state) {
+ std::string exec_dir = ::android::base::GetExecutableDirectory();
+ std::string path = ::android::base::StringPrintf("%s/testdata1/smaps", exec_dir.c_str());
+ for (auto _ : state) {
+ MemUsage stats;
+ CHECK_EQ(get_smaps_rollup(path, &stats), true);
+ CHECK_EQ(stats.pss, 108384);
+ }
+}
+BENCHMARK(BM_SmapsRollup_old);
+
+static void BM_SmapsRollup_new(benchmark::State& state) {
+ std::string exec_dir = ::android::base::GetExecutableDirectory();
+ std::string path = ::android::base::StringPrintf("%s/testdata1/smaps", exec_dir.c_str());
+ for (auto _ : state) {
+ MemUsage stats;
+ CHECK_EQ(SmapsOrRollupFromFile(path, &stats), true);
+ CHECK_EQ(stats.pss, 108384);
+ }
+}
+BENCHMARK(BM_SmapsRollup_new);
+
BENCHMARK_MAIN();