Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d346349d authored by Sandeep Patil's avatar Sandeep Patil Committed by Gerrit Code Review
Browse files

Merge changes from topic "procrank-ready"

* changes:
  Add procrank2
  libmeminfo: defer maps reading only when required for procmeminfo
  libmeminfo: Add support to reset workingset without procmeminfo objects
  libmeminfo: Add support to fiter accounting based on page flags
  libmeminfo: Add support to read zram memory consumption
  libmeminfo: Add support for counting swap pages
parents bcc2d608 a14119d0
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -54,6 +54,11 @@ cc_test {
    srcs: [
        "libmeminfo_test.cpp"
    ],

    data: [
        "testdata1/*",
        "testdata2/*"
    ],
}

cc_benchmark {
@@ -67,4 +72,8 @@ cc_benchmark {
        "libmeminfo",
        "libprocinfo",
    ],

    data: [
        "testdata1/*",
    ],
}
+4 −1
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ struct MemUsage {
    uint64_t pss;
    uint64_t uss;

    uint64_t swap;

    uint64_t private_clean;
    uint64_t private_dirty;
    uint64_t shared_clean;
@@ -41,6 +43,7 @@ struct MemUsage {
          rss(0),
          pss(0),
          uss(0),
          swap(0),
          private_clean(0),
          private_dirty(0),
          shared_clean(0),
@@ -49,7 +52,7 @@ struct MemUsage {
    ~MemUsage() = default;

    void clear() {
        vss = rss = pss = uss = 0;
        vss = rss = pss = uss = swap = 0;
        private_clean = private_dirty = shared_clean = shared_dirty = 0;
    }
};
+8 −2
Original line number Diff line number Diff line
@@ -29,13 +29,16 @@ namespace meminfo {
class ProcMemInfo final {
    // Per-process memory accounting
  public:
    ProcMemInfo(pid_t pid, bool get_wss = false);
    // Reset the working set accounting of the process via /proc/<pid>/clear_refs
    static bool ResetWorkingSet(pid_t pid);

    ProcMemInfo(pid_t pid, bool get_wss = false, uint64_t pgflags = 0, uint64_t pgflags_mask = 0);

    const std::vector<Vma>& Maps();
    const MemUsage& Usage();
    const MemUsage& Wss();
    const std::vector<uint16_t>& SwapOffsets();

    bool WssReset();
    ~ProcMemInfo() = default;

  private:
@@ -44,11 +47,14 @@ class ProcMemInfo final {

    pid_t pid_;
    bool get_wss_;
    uint64_t pgflags_;
    uint64_t pgflags_mask_;

    std::vector<Vma> maps_;

    MemUsage usage_;
    MemUsage wss_;
    std::vector<uint16_t> swap_offsets_;
};

}  // namespace meminfo
+31 −15
Original line number Diff line number Diff line
@@ -28,6 +28,21 @@ namespace meminfo {
class SysMemInfo final {
    // System or Global memory accounting
  public:
    static constexpr const char* kMemTotal = "MemTotal:";
    static constexpr const char* kMemFree = "MemFree:";
    static constexpr const char* kMemBuffers = "Buffers:";
    static constexpr const char* kMemCached = "Cached:";
    static constexpr const char* kMemShmem = "Shmem:";
    static constexpr const char* kMemSlab = "Slab:";
    static constexpr const char* kMemSReclaim = "SReclaimable:";
    static constexpr const char* kMemSUnreclaim = "SUnreclaim:";
    static constexpr const char* kMemSwapTotal = "SwapTotal:";
    static constexpr const char* kMemSwapFree = "SwapFree:";
    static constexpr const char* kMemMapped = "Mapped:";
    static constexpr const char* kMemVmallocUsed = "VmallocUsed:";
    static constexpr const char* kMemPageTables = "PageTables:";
    static constexpr const char* kMemKernelStack = "KernelStack:";

    static const std::vector<std::string> kDefaultSysMemInfoTags;

    SysMemInfo() = default;
@@ -38,24 +53,25 @@ class SysMemInfo final {
                     const std::string& path = "/proc/meminfo");

    // getters
    uint64_t mem_total_kb() { return mem_in_kb_["MemTotal:"]; }
    uint64_t mem_free_kb() { return mem_in_kb_["MemFree:"]; }
    uint64_t mem_buffers_kb() { return mem_in_kb_["Buffers:"]; }
    uint64_t mem_cached_kb() { return mem_in_kb_["Cached:"]; }
    uint64_t mem_shmem_kb() { return mem_in_kb_["Shmem:"]; }
    uint64_t mem_slab_kb() { return mem_in_kb_["Slab:"]; }
    uint64_t mem_slab_reclailmable_kb() { return mem_in_kb_["SReclaimable:"]; }
    uint64_t mem_slab_unreclaimable_kb() { return mem_in_kb_["SUnreclaim:"]; }
    uint64_t mem_swap_kb() { return mem_in_kb_["SwapTotal:"]; }
    uint64_t mem_free_swap_kb() { return mem_in_kb_["SwapFree:"]; }
    uint64_t mem_zram_kb() { return mem_in_kb_["Zram:"]; }
    uint64_t mem_mapped_kb() { return mem_in_kb_["Mapped:"]; }
    uint64_t mem_vmalloc_used_kb() { return mem_in_kb_["VmallocUsed:"]; }
    uint64_t mem_page_tables_kb() { return mem_in_kb_["PageTables:"]; }
    uint64_t mem_kernel_stack_kb() { return mem_in_kb_["KernelStack:"]; }
    uint64_t mem_total_kb() { return mem_in_kb_[kMemTotal]; }
    uint64_t mem_free_kb() { return mem_in_kb_[kMemFree]; }
    uint64_t mem_buffers_kb() { return mem_in_kb_[kMemBuffers]; }
    uint64_t mem_cached_kb() { return mem_in_kb_[kMemCached]; }
    uint64_t mem_shmem_kb() { return mem_in_kb_[kMemShmem]; }
    uint64_t mem_slab_kb() { return mem_in_kb_[kMemSlab]; }
    uint64_t mem_slab_reclailmable_kb() { return mem_in_kb_[kMemSReclaim]; }
    uint64_t mem_slab_unreclaimable_kb() { return mem_in_kb_[kMemSUnreclaim]; }
    uint64_t mem_swap_kb() { return mem_in_kb_[kMemSwapTotal]; }
    uint64_t mem_swap_free_kb() { return mem_in_kb_[kMemSwapFree]; }
    uint64_t mem_mapped_kb() { return mem_in_kb_[kMemMapped]; }
    uint64_t mem_vmalloc_used_kb() { return mem_in_kb_[kMemVmallocUsed]; }
    uint64_t mem_page_tables_kb() { return mem_in_kb_[kMemPageTables]; }
    uint64_t mem_kernel_stack_kb() { return mem_in_kb_[kMemPageTables]; }
    uint64_t mem_zram_kb(const std::string& zram_dev = "");

  private:
    std::map<std::string, uint64_t> mem_in_kb_;
    bool MemZramDevice(const std::string& zram_dev, uint64_t* mem_zram_dev);
};

}  // namespace meminfo
+56 −5
Original line number Diff line number Diff line
@@ -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 @@ enum {
    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;

@@ -69,7 +71,8 @@ void get_mem_info(uint64_t mem[], const char* file) {
    static const char* const tags[] = {
            "MemTotal:",     "MemFree:",    "Buffers:",     "Cached:",   "Shmem:", "Slab:",
            "SReclaimable:", "SUnreclaim:", "SwapTotal:",   "SwapFree:", "ZRam:",  "Mapped:",
            "VmallocUsed:",  "PageTables:", "KernelStack:", NULL};
            "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 @@ void get_mem_info(uint64_t mem[], const char* file) {
    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 @@ Hugepagesize: 2048 kB)meminfo";
}
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();
Loading