summaryrefslogtreecommitdiff
path: root/libmeminfo/tools/wsstop.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libmeminfo/tools/wsstop.cpp')
-rw-r--r--libmeminfo/tools/wsstop.cpp219
1 files changed, 0 insertions, 219 deletions
diff --git a/libmeminfo/tools/wsstop.cpp b/libmeminfo/tools/wsstop.cpp
deleted file mode 100644
index 368d04edf..000000000
--- a/libmeminfo/tools/wsstop.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <getopt.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <algorithm>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <meminfo/pageacct.h>
-#include <meminfo/procmeminfo.h>
-
-using ::android::meminfo::ProcMemInfo;
-using ::android::meminfo::Vma;
-
-// Global options
-static int32_t g_delay = 0;
-static int32_t g_total = 2;
-static pid_t g_pid = -1;
-
-[[noreturn]] static void usage(int exit_status) {
- fprintf(stderr,
- "%s [-d DELAY_BETWEEN_EACH_SAMPLE] [-n REFRESH_TOTAL] PID\n"
- "-d\tdelay between each working set sample (default 0)\n"
- "-n\ttotal number of refreshes before we exit (default 2)\n",
- getprogname());
-
- exit(exit_status);
-}
-
-static void print_header() {
- const char* addr1 = " start end ";
- const char* addr2 = " addr addr ";
-
- printf("%s virtual shared shared private private\n", addr1);
- printf("%s size RSS PSS clean dirty clean dirty swap "
- "swapPSS",
- addr2);
- printf(" object\n");
-}
-
-static void print_divider() {
- printf("---------------- ---------------- ");
- printf("--------- --------- --------- --------- --------- --------- --------- --------- "
- "--------- ");
- printf("------------------------------\n");
-}
-
-static void print_vma(const Vma& v) {
- printf("%16" PRIx64 " %16" PRIx64 " ", v.start, v.end);
- printf("%8" PRIu64 "K %8" PRIu64 "K %8" PRIu64 "K %8" PRIu64 "K %8" PRIu64 "K %8" PRIu64
- "K %8" PRIu64 "K %8" PRIu64 "K %8" PRIu64 "K ",
- v.usage.vss / 1024, v.usage.rss / 1024, v.usage.pss / 1024, v.usage.shared_clean / 1024,
- v.usage.shared_dirty / 1024, v.usage.private_clean / 1024, v.usage.private_dirty / 1024,
- v.usage.swap / 1024, v.usage.swap_pss / 1024);
- printf("%s\n", v.name.c_str());
-}
-
-static bool same_vma(const Vma& cur, const Vma& last) {
- return (cur.start == last.start && cur.end == last.end && cur.name == last.name &&
- cur.flags == last.flags && cur.offset == last.offset);
-}
-
-static Vma diff_vma_params(const Vma& cur, const Vma& last) {
- Vma res;
- res.usage.shared_clean = cur.usage.shared_clean > last.usage.shared_clean
- ? cur.usage.shared_clean - last.usage.shared_clean
- : 0;
- res.usage.shared_dirty = cur.usage.shared_dirty > last.usage.shared_dirty
- ? cur.usage.shared_dirty - last.usage.shared_dirty
- : 0;
- res.usage.private_clean = cur.usage.private_clean > last.usage.private_clean
- ? cur.usage.private_clean - last.usage.private_clean
- : 0;
- res.usage.private_dirty = cur.usage.private_dirty > last.usage.private_dirty
- ? cur.usage.private_dirty - last.usage.private_dirty
- : 0;
-
- res.usage.rss = cur.usage.rss > last.usage.rss ? cur.usage.rss - last.usage.rss : 0;
- res.usage.pss = cur.usage.pss > last.usage.pss ? cur.usage.pss - last.usage.pss : 0;
- res.usage.uss = cur.usage.uss > last.usage.uss ? cur.usage.uss - last.usage.uss : 0;
- res.usage.swap = cur.usage.swap > last.usage.swap ? cur.usage.swap - last.usage.swap : 0;
- res.usage.swap_pss =
- cur.usage.swap_pss > last.usage.swap_pss ? cur.usage.swap_pss - last.usage.swap_pss : 0;
-
- // set vma properties to the same as the current one.
- res.start = cur.start;
- res.end = cur.end;
- res.offset = cur.offset;
- res.flags = cur.flags;
- res.name = cur.name;
- return res;
-}
-
-static void diff_workingset(std::vector<Vma>& wss, std::vector<Vma>& old, std::vector<Vma>* res) {
- res->clear();
- auto vma_sorter = [](const Vma& a, const Vma& b) { return a.start < b.start; };
- std::sort(wss.begin(), wss.end(), vma_sorter);
- std::sort(old.begin(), old.end(), vma_sorter);
- if (old.empty()) {
- *res = wss;
- return;
- }
-
- for (auto& i : wss) {
- bool found_same_vma = false;
- // TODO: This is highly inefficient, fix it if it takes
- // too long. Worst case will be system_server
- for (auto& j : old) {
- if (same_vma(i, j)) {
- res->emplace_back(diff_vma_params(i, j));
- found_same_vma = true;
- break;
- }
- }
-
- if (!found_same_vma) {
- res->emplace_back(i);
- }
- }
-
- std::sort(res->begin(), res->end(), vma_sorter);
- return;
-}
-
-static int workingset() {
- std::vector<Vma> last_wss = {};
- std::vector<Vma> diff_wss = {};
- uint32_t nr_refresh = 0;
-
- while (true) {
- std::unique_ptr<ProcMemInfo> proc_mem = std::make_unique<ProcMemInfo>(g_pid, true);
- std::vector<Vma> wss = proc_mem->MapsWithPageIdle();
-
- diff_workingset(wss, last_wss, &diff_wss);
- diff_wss.erase(std::remove_if(diff_wss.begin(), diff_wss.end(),
- [](const auto& v) { return v.usage.rss == 0; }),
- diff_wss.end());
- if ((nr_refresh % 5) == 0) {
- print_header();
- print_divider();
- }
-
- for (const auto& v : diff_wss) {
- print_vma(v);
- }
-
- nr_refresh++;
- if (nr_refresh == g_total) {
- break;
- }
-
- last_wss = wss;
- sleep(g_delay);
- print_divider();
- }
-
- return 0;
-}
-
-int main(int argc, char* argv[]) {
- struct option longopts[] = {
- {"help", no_argument, nullptr, 'h'},
- {0, 0, nullptr, 0},
- };
-
- int opt;
- while ((opt = getopt_long(argc, argv, "d:n:h", longopts, nullptr)) != -1) {
- switch (opt) {
- case 'd':
- g_delay = atoi(optarg);
- break;
- case 'n':
- g_total = atoi(optarg);
- break;
- case 'h':
- usage(EXIT_SUCCESS);
- default:
- usage(EXIT_FAILURE);
- }
- }
-
- if ((argc - 1) < optind) {
- fprintf(stderr, "Invalid arguments: Must provide <pid> at the end\n");
- usage(EXIT_FAILURE);
- }
-
- g_pid = atoi(argv[optind]);
- if (g_pid <= 0) {
- fprintf(stderr, "Invalid process id %s\n", argv[optind]);
- usage(EXIT_FAILURE);
- }
-
- if (!::android::meminfo::PageAcct::KernelHasPageIdle()) {
- fprintf(stderr, "Missing support for Idle page tracking in the kernel\n");
- return 0;
- }
-
- return workingset();
-}