| Index: systrace/atrace_helper/jni/procfs_utils.cc
|
| diff --git a/systrace/atrace_helper/jni/procfs_utils.cc b/systrace/atrace_helper/jni/procfs_utils.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f14abe7e70beba731979369ff6053a7621589c71
|
| --- /dev/null
|
| +++ b/systrace/atrace_helper/jni/procfs_utils.cc
|
| @@ -0,0 +1,117 @@
|
| +// Copyright 2017 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "procfs_utils.h"
|
| +
|
| +#include <stdio.h>
|
| +#include <string.h>
|
| +
|
| +#include "file_utils.h"
|
| +#include "logging.h"
|
| +
|
| +using file_utils::ForEachPidInProcPath;
|
| +using file_utils::ReadProcFile;
|
| +using file_utils::ReadProcFileTrimmed;
|
| +
|
| +namespace procfs_utils {
|
| +
|
| +namespace {
|
| +
|
| +const char kJavaAppPrefix[] = "/system/bin/app_process";
|
| +const char kZygotePrefix[] = "zygote";
|
| +
|
| +inline void ReadProcString(int pid, const char* path, char* buf, size_t size) {
|
| + if (!file_utils::ReadProcFileTrimmed(pid, path, buf, size))
|
| + buf[0] = '\0';
|
| +}
|
| +
|
| +inline void ReadExePath(int pid, char* buf, size_t size) {
|
| + char exe_path[64];
|
| + sprintf(exe_path, "/proc/%d/exe", pid);
|
| + ssize_t res = readlink(exe_path, buf, size - 1);
|
| + if (res >= 0)
|
| + buf[res] = '\0';
|
| + else
|
| + buf[0] = '\0';
|
| +}
|
| +
|
| +inline bool IsApp(const char* name, const char* exe) {
|
| + return strncmp(exe, kJavaAppPrefix, sizeof(kJavaAppPrefix) - 1) == 0 &&
|
| + strncmp(name, kZygotePrefix, sizeof(kZygotePrefix) - 1) != 0;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +int ReadTgid(int pid) {
|
| + static const char kTgid[] = "\nTgid:";
|
| + char buf[512];
|
| + ssize_t rsize = ReadProcFile(pid, "status", buf, sizeof(buf));
|
| + if (rsize <= 0)
|
| + return -1;
|
| + const char* tgid_line = strstr(buf, kTgid);
|
| + CHECK(tgid_line);
|
| + return atoi(tgid_line + sizeof(kTgid) - 1);
|
| +}
|
| +
|
| +std::unique_ptr<ProcessInfo> ReadProcessInfo(int pid) {
|
| + ProcessInfo* process = new ProcessInfo();
|
| + process->pid = pid;
|
| + ReadProcString(pid, "cmdline", process->name, sizeof(process->name));
|
| + if (process->name[0] != 0) {
|
| + ReadExePath(pid, process->exe, sizeof(process->exe));
|
| + process->is_app = IsApp(process->name, process->exe);
|
| + } else {
|
| + ReadProcString(pid, "comm", process->name, sizeof(process->name));
|
| + CHECK(process->name[0]);
|
| + process->in_kernel = true;
|
| + }
|
| + return std::unique_ptr<ProcessInfo>(process);
|
| +}
|
| +
|
| +void ReadProcessThreads(ProcessInfo* process) {
|
| + if (process->in_kernel)
|
| + return;
|
| +
|
| + char tasks_path[64];
|
| + sprintf(tasks_path, "/proc/%d/task", process->pid);
|
| + ForEachPidInProcPath(tasks_path, [process](int tid) {
|
| + if (process->threads.count(tid))
|
| + return;
|
| + ThreadInfo thread = { tid, "" };
|
| + char task_comm[64];
|
| + sprintf(task_comm, "task/%d/comm", tid);
|
| + ReadProcString(process->pid, task_comm, thread.name, sizeof(thread.name));
|
| + if (thread.name[0] == '\0' && process->is_app)
|
| + strcpy(thread.name, "UI Thread");
|
| + process->threads[tid] = thread;
|
| + });
|
| +}
|
| +
|
| +bool ReadOomStats(ProcessSnapshot* snapshot) {
|
| + char buf[64];
|
| + if (ReadProcFileTrimmed(snapshot->pid, "oom_score", buf, sizeof(buf)))
|
| + snapshot->oom_score = atoi(buf);
|
| + else
|
| + return false;
|
| + if (ReadProcFileTrimmed(snapshot->pid, "oom_score_adj", buf, sizeof(buf)))
|
| + snapshot->oom_score_adj = atoi(buf);
|
| + else
|
| + return false;
|
| + return true;
|
| +}
|
| +
|
| +bool ReadPageFaultsAndCpuTimeStats(ProcessSnapshot* snapshot) {
|
| + char buf[512];
|
| + if (!ReadProcFileTrimmed(snapshot->pid, "stat", buf, sizeof(buf)))
|
| + return false;
|
| + int ret = sscanf(buf,
|
| + "%*d (%*[^)]) %*c %*d %*d %*d %*d %*d %*u %lu %*lu %lu %*lu %lu %lu",
|
| + &snapshot->minor_faults, &snapshot->major_faults,
|
| + &snapshot->utime, &snapshot->stime);
|
| + CHECK(ret == 4);
|
| + return true;
|
| +}
|
| +
|
| +
|
| +} // namespace procfs_utils
|
|
|