aboutsummaryrefslogtreecommitdiff
path: root/catapult/systrace/atrace_helper/jni/process_memory_stats.cc
diff options
context:
space:
mode:
Diffstat (limited to 'catapult/systrace/atrace_helper/jni/process_memory_stats.cc')
-rw-r--r--catapult/systrace/atrace_helper/jni/process_memory_stats.cc117
1 files changed, 61 insertions, 56 deletions
diff --git a/catapult/systrace/atrace_helper/jni/process_memory_stats.cc b/catapult/systrace/atrace_helper/jni/process_memory_stats.cc
index 516abea1..e13dc225 100644
--- a/catapult/systrace/atrace_helper/jni/process_memory_stats.cc
+++ b/catapult/systrace/atrace_helper/jni/process_memory_stats.cc
@@ -10,53 +10,36 @@
#include <memory>
#include "file_utils.h"
+#include "libmemtrack_wrapper.h"
#include "logging.h"
namespace {
-const int kKbPerPage = 4;
-
-// Takes a C string buffer and chunks it into lines without creating any
-// copies. It modifies the original buffer, by replacing \n with \0.
-class LineReader {
- public:
- LineReader(char* buf, size_t size) : ptr_(buf), end_(buf + size) {}
- const char* NextLine() {
- if (ptr_ >= end_)
- return nullptr;
- const char* cur = ptr_;
- char* next = strchr(ptr_, '\n');
- if (next) {
- *next = '\0';
- ptr_ = next + 1;
- } else {
- ptr_ = end_;
- }
- return cur;
- }
+const int kKbPerPage = 4;
- private:
- char* ptr_;
- char* end_;
-};
+const char kRss[] = "Rss";
+const char kPss[] = "Pss";
+const char kSwap[] = "Swap";
+const char kSharedClean[] = "Shared_Clean";
+const char kSharedDirty[] = "Shared_Dirty";
+const char kPrivateClean[] = "Private_Clean";
+const char kPrivateDirty[] = "Private_Dirty";
-bool ReadSmapsMetric(const char* line, const char* metric, uint64_t* res) {
- if (strncmp(line, metric, strlen(metric)))
+bool ReadSmapsMetric(
+ const char* line, const char* metric, int metric_size, uint64_t* res) {
+ if (strncmp(line, metric, metric_size - 1))
return false;
- line = strchr(line, ':');
- if (!line)
+ if (line[metric_size - 1] != ':')
return false;
- *res = strtoull(line + 1, nullptr, 10);
+ *res = strtoull(line + metric_size, nullptr, 10);
return true;
}
} // namespace
-ProcessMemoryStats::ProcessMemoryStats(int pid) : pid_(pid) {}
-
-bool ProcessMemoryStats::ReadLightStats() {
+bool ProcessMemoryStats::ReadLightStats(int pid) {
char buf[64];
- if (file_utils::ReadProcFile(pid_, "statm", buf, sizeof(buf)) <= 0)
+ if (file_utils::ReadProcFile(pid, "statm", buf, sizeof(buf)) <= 0)
return false;
uint32_t vm_size_pages;
uint32_t rss_pages;
@@ -67,10 +50,10 @@ bool ProcessMemoryStats::ReadLightStats() {
return true;
}
-bool ProcessMemoryStats::ReadFullStats() {
- const size_t kBufSize = 32u * 1024 * 1024;
+bool ProcessMemoryStats::ReadFullStats(int pid) {
+ const size_t kBufSize = 8u * 1024 * 1024;
std::unique_ptr<char[]> buf(new char[kBufSize]);
- ssize_t rsize = file_utils::ReadProcFile(pid_, "smaps", &buf[0], kBufSize);
+ ssize_t rsize = file_utils::ReadProcFile(pid, "smaps", &buf[0], kBufSize);
if (rsize <= 0)
return false;
MmapInfo* last_mmap_entry = nullptr;
@@ -79,54 +62,76 @@ bool ProcessMemoryStats::ReadFullStats() {
CHECK(rss_kb_ == 0);
// Iterate over all lines in /proc/PID/smaps.
- LineReader rd(&buf[0], rsize);
+ file_utils::LineReader rd(&buf[0], rsize);
for (const char* line = rd.NextLine(); line; line = rd.NextLine()) {
- // Check if the current line is the beginning of a new mmaps entry, e.g.:
- // be7f7000-be818000 rw-p 00000000 00:00 0 [stack]
- // Note that the mapped file name ([stack]) is optional and won't be
- // present
- // on anonymous memory maps (hence res >= 3 below).
- int res = sscanf(
- line, "%llx-%llx %4s %*llx %*[:0-9a-f] %*[0-9a-f]%*[ \t]%128[^\n]",
- &new_mmap->start_addr, &new_mmap->end_addr, new_mmap->prot_flags,
- new_mmap->mapped_file);
- if (res >= 3) {
+ if (!line[0])
+ continue;
+ // Performance optimization (hack).
+ // Any header line starts with lowercase hex digit but subsequent lines
+ // start with uppercase letter.
+ if (line[0] < 'A' || line[0] > 'Z') {
+ // Note that the mapped file name ([stack]) is optional and won't be
+ // present on anonymous memory maps (hence res >= 3 below).
+ int res = sscanf(line,
+ "%llx-%llx %4s %*llx %*[:0-9a-f] %*[0-9a-f]%*[ \t]%127[^\n]",
+ &new_mmap->start_addr, &new_mmap->end_addr, new_mmap->prot_flags,
+ new_mmap->mapped_file);
last_mmap_entry = new_mmap.get();
CHECK(new_mmap->end_addr >= new_mmap->start_addr);
- new_mmap->virt_kb = (new_mmap->end_addr - new_mmap->start_addr) / 1024;
+ new_mmap->virt_kb =
+ (new_mmap->end_addr - new_mmap->start_addr) / 1024;
if (res == 3)
new_mmap->mapped_file[0] = '\0';
virt_kb_ += new_mmap->virt_kb;
- mmaps_[new_mmap->start_addr] = std::move(new_mmap);
+ mmaps_.push_back(std::move(new_mmap));
new_mmap.reset(new MmapInfo());
} else {
// The current line is a metrics line within a mmap entry, e.g.:
// Size: 4 kB
uint64_t size = 0;
CHECK(last_mmap_entry);
- if (ReadSmapsMetric(line, "Rss:", &size)) {
+ if (ReadSmapsMetric(line, kRss, sizeof(kRss), &size)) {
last_mmap_entry->rss_kb = size;
rss_kb_ += size;
- } else if (ReadSmapsMetric(line, "Pss:", &size)) {
+ } else if (ReadSmapsMetric(line, kPss, sizeof(kPss), &size)) {
last_mmap_entry->pss_kb = size;
pss_kb_ += size;
- } else if (ReadSmapsMetric(line, "Swap:", &size)) {
+ } else if (ReadSmapsMetric(line, kSwap, sizeof(kSwap), &size)) {
last_mmap_entry->swapped_kb = size;
swapped_kb_ += size;
- } else if (ReadSmapsMetric(line, "Shared_Clean:", &size)) {
+ } else if (ReadSmapsMetric(
+ line, kSharedClean, sizeof(kSharedClean), &size)) {
last_mmap_entry->shared_clean_kb = size;
shared_clean_kb_ += size;
- } else if (ReadSmapsMetric(line, "Shared_Dirty:", &size)) {
+ } else if (ReadSmapsMetric(
+ line, kSharedDirty, sizeof(kSharedDirty), &size)) {
last_mmap_entry->shared_dirty_kb = size;
shared_dirty_kb_ += size;
- } else if (ReadSmapsMetric(line, "Private_Clean:", &size)) {
+ } else if (ReadSmapsMetric(
+ line, kPrivateClean, sizeof(kPrivateClean), &size)) {
last_mmap_entry->private_clean_kb = size;
private_clean_kb_ += size;
- } else if (ReadSmapsMetric(line, "Private_Dirty:", &size)) {
+ } else if (ReadSmapsMetric(
+ line, kPrivateDirty, sizeof(kPrivateDirty), &size)) {
last_mmap_entry->private_dirty_kb = size;
private_dirty_kb_ += size;
}
}
}
+ full_stats_ = true;
return true;
}
+
+bool ProcessMemoryStats::ReadGpuStats(int pid) {
+ MemtrackProc mt(pid);
+ gpu_graphics_kb_ = mt.graphics_total() / 1024;
+ gpu_graphics_pss_kb_ = mt.graphics_pss() / 1024;
+ gpu_gl_kb_ = mt.gl_total() / 1024;
+ gpu_gl_pss_kb_ = mt.gl_pss() / 1024;
+ gpu_other_kb_ = mt.other_total() / 1024;
+ gpu_other_pss_kb_ = mt.other_pss() / 1024;
+
+ gpu_stats_ = !mt.has_errors() &&
+ (gpu_graphics_kb_ != 0 || gpu_gl_kb_ != 0 || gpu_other_kb_ != 0);
+ return gpu_stats_;
+}