131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv/* 231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv * Copyright (C) 2016 The Android Open Source Project 331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv * 431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv * Licensed under the Apache License, Version 2.0 (the "License"); 531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv * you may not use this file except in compliance with the License. 631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv * You may obtain a copy of the License at 731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv * 831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv * http://www.apache.org/licenses/LICENSE-2.0 931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv * 1031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv * Unless required by applicable law or agreed to in writing, software 1131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv * distributed under the License is distributed on an "AS IS" BASIS, 1231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv * See the License for the specific language governing permissions and 1431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv * limitations under the License. 1531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv */ 1631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 1731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv#include "bootio_collector.h" 1831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv#include <android-base/logging.h> 1931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv#include <android-base/file.h> 2031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv#include <log/log.h> 2131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv#include "protos.pb.h" 2231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv#include "time.h" 2331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv#include <unordered_map> 2459b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv#include <inttypes.h> 2531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv#include <dirent.h> 2631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 2731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkivnamespace android { 2831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 2931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv#define CPU_STAT_FILE "/proc/stat" 3031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv#define SAMPLES_FILE "/samples" 3131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv#define PID_STAT_FILE "/proc/%d/stat" 3231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv#define PID_CMDLINE_FILE "/proc/%d/cmdline" 3331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv#define PID_IO_FILE "/proc/%d/io" 3431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv#define PROC_DIR "/proc" 3531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 3631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkivstatic const int PROC_NAME_LEN = 64; 3731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkivstatic const int THREAD_NAME_LEN = 32; 3831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkivstatic const int MAX_LINE = 256; 3931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 4031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv#define die(...) { LOG(ERROR) << (__VA_ARGS__); exit(EXIT_FAILURE); } 4131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 4231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkivvoid PopulateCpu(CpuData& cpu) { 4331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv long unsigned utime, ntime, stime, itime; 4431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv long unsigned iowtime, irqtime, sirqtime; 4531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv FILE *file; 4631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv file = fopen(CPU_STAT_FILE, "r"); 4731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (!file) die("Could not open /proc/stat.\n"); 4831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv fscanf(file, "cpu %lu %lu %lu %lu %lu %lu %lu", &utime, &ntime, &stime, 4931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv &itime, &iowtime, &irqtime, &sirqtime); 5031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv fclose(file); 5131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv cpu.set_utime(utime); 5231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv cpu.set_ntime(ntime); 5331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv cpu.set_stime(stime); 5431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv cpu.set_itime(itime); 5531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv cpu.set_iowtime(iowtime); 5631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv cpu.set_irqtime(irqtime); 5731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv cpu.set_sirqtime(sirqtime); 5831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv} 5931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 6031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkivvoid ClearPreviousResults(std::string path) { 6131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv std::string err; 6231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (!android::base::RemoveFileIfExists(path, &err)) { 6331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv LOG(ERROR) << "failed to remove the file " << path << " " << err; 6431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv return; 6531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 6631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv} 6731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 6831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkivint ReadIo(char *filename, AppSample *sample) { 6931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv FILE *file; 7031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv char line[MAX_LINE]; 7131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv unsigned int rchar, wchar, syscr, syscw, readbytes, writebytes; 7231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 7331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv file = fopen(filename, "r"); 7431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (!file) return 1; 7531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv while (fgets(line, MAX_LINE, file)) { 7631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sscanf(line, "rchar: %u", &rchar); 7731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sscanf(line, "wchar: %u", &wchar); 7831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sscanf(line, "syscr: %u", &syscr); 7931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sscanf(line, "syscw: %u", &syscw); 8031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sscanf(line, "read_bytes: %u", &readbytes); 8131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sscanf(line, "write_bytes: %u", &writebytes); 8231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 8331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv fclose(file); 8431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sample->set_rchar(rchar); 8531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sample->set_wchar(wchar); 8631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sample->set_syscr(syscr); 8731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sample->set_syscw(syscw); 8831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sample->set_readbytes(readbytes); 8931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sample->set_writebytes(writebytes); 9031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv return 0; 9131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv} 9231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 9331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkivint ReadStatForName(char *filename, AppData *app) { 9431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv FILE *file; 9531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv char buf[MAX_LINE], *open_paren, *close_paren; 9631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 9731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv file = fopen(filename, "r"); 9831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (!file) return 1; 9931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv fgets(buf, MAX_LINE, file); 10031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv fclose(file); 10131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 10231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv /* Split at first '(' and last ')' to get process name. */ 10331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv open_paren = strchr(buf, '('); 10431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv close_paren = strrchr(buf, ')'); 10531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (!open_paren || !close_paren) return 1; 10631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 10731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv *open_paren = *close_paren = '\0'; 10831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (!app->has_tname()) { 10931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv app->set_tname(open_paren + 1, close_paren - open_paren - 1); 11031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 11131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv return 0; 11231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv} 11331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 11431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkivint ReadStat(char *filename, AppSample *sample) { 11531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv FILE *file; 11631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv char buf[MAX_LINE], *open_paren, *close_paren; 11731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 11831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv file = fopen(filename, "r"); 11931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (!file) return 1; 12031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv fgets(buf, MAX_LINE, file); 12131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv fclose(file); 12231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 12331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv /* Split at first '(' and last ')' to get process name. */ 12431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv open_paren = strchr(buf, '('); 12531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv close_paren = strrchr(buf, ')'); 12631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (!open_paren || !close_paren) return 1; 12731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 12831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv uint64_t utime; 12931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv uint64_t stime; 13031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv uint64_t rss; 13131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 13231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv /* Scan rest of string. */ 13331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sscanf(close_paren + 1, 13431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv " %*c " "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d " 13559b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv "%" PRIu64 /*SCNu64*/ 13659b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv "%" PRIu64 /*SCNu64*/ "%*d %*d %*d %*d %*d %*d %*d %*d " 13759b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv "%" PRIu64 /*SCNu64*/ "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d", 13831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv &utime, 13931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv &stime, 14031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv &rss); 14131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sample->set_utime(utime); 14231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sample->set_stime(stime); 14331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sample->set_rss(rss); 14431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 14531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv return 0; 14631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv} 14731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 14831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkivint ReadCmdline(char *filename, AppData *app) { 14931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv FILE *file; 15031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv char line[MAX_LINE]; 15131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 15231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv line[0] = '\0'; 15331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv file = fopen(filename, "r"); 15431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (!file) return 1; 15531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv fgets(line, MAX_LINE, file); 15631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv fclose(file); 15731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (strlen(line) > 0) { 15831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv app->set_name(line, strlen(line)); 15931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } else { 16031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv app->set_name("N/A"); 16131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 16231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv return 0; 16331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv}; 16431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 16531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkivvoid ReadProcData(std::unordered_map<int, AppData*>& pidDataMap, DataContainer& dataContainer, 16659b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv time_t currentTimeUtc, time_t currentUptime) { 16731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv DIR *procDir; 16831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv struct dirent *pidDir; 16931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv pid_t pid; 17031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv char filename[64]; 17131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv procDir = opendir(PROC_DIR); 17231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (!procDir) die("Could not open /proc.\n"); 17331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv while ((pidDir = readdir(procDir))) { 17431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (!isdigit(pidDir->d_name[0])) { 17531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv continue; 17631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 17731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv pid = atoi(pidDir->d_name); 17831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv AppData *data; 17931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 18031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv // TODO: in theory same pid can be shared for multiple processes, 18131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv // might need add extra check. 18231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (pidDataMap.count(pid) == 0) { 18331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv data = dataContainer.add_app(); 18431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv data->set_pid(pid); 18531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sprintf(filename, PID_STAT_FILE, pid); 18631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv ReadStatForName(filename, data); 18731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sprintf(filename, PID_CMDLINE_FILE, pid); 18831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv ReadCmdline(filename, data); 18931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv pidDataMap[pid] = data; 19031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } else { 19131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv data = pidDataMap[pid]; 19231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 19331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv AppSample *sample = data->add_samples(); 19431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sample->set_timestamp(currentTimeUtc); 19559b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv sample->set_uptime(currentUptime); 19631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 19731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sprintf(filename, PID_STAT_FILE, pid); 19831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv ReadStat(filename, sample); 19931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 20031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sprintf(filename, PID_IO_FILE, pid); 20131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv ReadIo(filename, sample); 20231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 20331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv} 20431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 20531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkivuint64_t SumCpuValues(CpuData& cpu) { 20631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv return cpu.utime() + cpu.ntime() + cpu.stime() + cpu.itime() + cpu.iowtime() + 20731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv cpu.irqtime() + cpu.sirqtime(); 20831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv} 20931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 21031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkivtime_t GetUptime() { 21131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv std::string uptime_str; 21231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (!android::base::ReadFileToString("/proc/uptime", &uptime_str)) { 21331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv LOG(ERROR) << "Failed to read /proc/uptime"; 21431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv return -1; 21531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 21631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 21731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv // Cast intentionally rounds down. 21831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv return static_cast<time_t>(strtod(uptime_str.c_str(), NULL)); 21931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv} 22031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 22159b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkivstruct Stats { 22259b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv int uptime; 22359b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv float cpu; 22459b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv uint64_t rbytes; 22559b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv uint64_t wbytes; 22659b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv}; 22759b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv 22831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkivvoid PrintPids(DataContainer& data, std::unordered_map<int, uint64_t>& cpuDataMap) { 22931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv printf("rchar: number of bytes the process read, using any read-like system call " 23031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv "(from files, pipes, tty...).\n"); 23131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv printf("wchar: number of bytes the process wrote using any write-like system call.\n"); 23231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv printf("wchar: number of bytes the process wrote using any write-like system call.\n"); 23331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv printf("syscr: number of write-like system call invocations that the process performed.\n"); 23431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv printf("rbytes: number of bytes the process directly read from disk.\n"); 23531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv printf("wbytes: number of bytes the process originally dirtied in the page-cache " 23631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv "(assuming they will go to disk later).\n\n"); 23731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 23831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv std::unique_ptr<AppSample> bootZeroSample(new AppSample()); 23959b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv std::map<int, Stats> statsMap; 24059b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv // Init stats map 24159b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv Stats emptyStat {0, 0., 0, 0}; 24259b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv for (auto it = cpuDataMap.begin(); it != cpuDataMap.end(); it++) { 24359b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv statsMap[it->first] = emptyStat; 24459b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv } 24531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv for (int i = 0; i < data.app_size(); i++) { 24631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv const AppData appData = data.app(i); 24731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv printf("\n-----------------------------------------------------------------------------\n"); 24831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv printf("PID:\t%u\n", appData.pid()); 24931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv printf("Name:\t%s\n", appData.name().c_str()); 25031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv printf("ThName:\t%s\n", appData.tname().c_str()); 25159b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv printf("%-15s%-13s%-13s%-13s%-13s%-13s%-13s%-13s\n", "Uptime inter.", "rchar", "wchar", 25231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv "syscr", "syscw", "rbytes", "wbytes", "cpu%"); 25331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv const AppSample *olderSample = NULL; 25431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv const AppSample *newerSample = NULL; 25531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv bool isFirstSample = true; 25631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv for (int j = 0; j < appData.samples_size(); j++) { 25731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv olderSample = newerSample; 25831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv newerSample = &(appData.samples(j)); 25931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (olderSample == NULL) { 26031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv olderSample = bootZeroSample.get(); 26131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 26231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv float cpuLoad = 0.; 26331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv uint64_t cpuDelta; 26431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (isFirstSample) { 26531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv cpuDelta = cpuDataMap[newerSample->timestamp()]; 26631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } else { 26731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv cpuDelta = cpuDataMap[newerSample->timestamp()] - 26831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv cpuDataMap[olderSample->timestamp()]; 26931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 27031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (cpuDelta != 0) { 27131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv cpuLoad = (newerSample->utime() - olderSample->utime() + 27231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv newerSample->stime() - olderSample->stime()) * 100. / cpuDelta; 27331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 27459b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv Stats& stats = statsMap[newerSample->timestamp()]; 27559b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv stats.uptime = newerSample->uptime(); 27659b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv stats.cpu += cpuLoad; 27759b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv stats.rbytes += (newerSample->readbytes() - olderSample->readbytes()); 27859b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv stats.wbytes += (newerSample->writebytes() - olderSample->writebytes()); 27959b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv 28019b97bb5bb6d7a627d2dd15800d2d9b804f262daGeorge Burgess IV // Note that all of these are explicitly `long long`s, not int64_t, 28119b97bb5bb6d7a627d2dd15800d2d9b804f262daGeorge Burgess IV // so we can't use PRId64 here. 28219b97bb5bb6d7a627d2dd15800d2d9b804f262daGeorge Burgess IV#define NUMBER "%-13lld" 28319b97bb5bb6d7a627d2dd15800d2d9b804f262daGeorge Burgess IV printf("%5lld - %-5lld " NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER "%-9.2f\n", 28419b97bb5bb6d7a627d2dd15800d2d9b804f262daGeorge Burgess IV#undef NUMBER 28559b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv olderSample->uptime(), 28659b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv newerSample->uptime(), 28731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv newerSample->rchar() - olderSample->rchar(), 28831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv newerSample->wchar() - olderSample->wchar(), 28931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv newerSample->syscr() - olderSample->syscr(), 29031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv newerSample->syscw() - olderSample->syscw(), 29131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv newerSample->readbytes() - olderSample->readbytes(), 29231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv newerSample->writebytes() - olderSample->writebytes(), 29331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv cpuLoad); 29431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv isFirstSample = false; 29531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 29631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv printf("-----------------------------------------------------------------------------\n"); 29719b97bb5bb6d7a627d2dd15800d2d9b804f262daGeorge Burgess IV#define NUMBER "%-13lld" 29819b97bb5bb6d7a627d2dd15800d2d9b804f262daGeorge Burgess IV printf("%-15s" NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER "\n", 29919b97bb5bb6d7a627d2dd15800d2d9b804f262daGeorge Burgess IV#undef NUMBER 30031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv "Total", 30131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv newerSample->rchar(), 30231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv newerSample->wchar(), 30331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv newerSample->syscr(), 30431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv newerSample->syscw(), 30531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv newerSample->readbytes(), 30631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv newerSample->writebytes()); 30731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 30859b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv printf("\nAggregations\n%-10s%-13s%-13s%-13s\n", 30959b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv "Total", 31059b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv "rbytes", 31159b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv "wbytes", 31259b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv "cpu%"); 31359b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv 31459b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv for (auto it = statsMap.begin(); it != statsMap.end(); it++) { 31559b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv printf("%-10u%-13" PRIu64 "%-13" PRIu64 "%-9.2f\n", 31659b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv it->second.uptime, 31759b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv it->second.rbytes, 31859b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv it->second.wbytes, 31959b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv it->second.cpu); 32059b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv } 32131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv} 32231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 32331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv} 32431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 32531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii TomkivBootioCollector::BootioCollector(std::string path) { 32631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv DCHECK_EQ('/', path.back()); 32731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv path_ = path; 32831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv} 32931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 33031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkivvoid BootioCollector::StartDataCollection(int timeout, int samples) { 33131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv android::ClearPreviousResults(getStoragePath()); 33231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv int remaining = samples + 1; 33331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv int delayS = timeout / samples; 33431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 33531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv std::unordered_map < int, AppData * > pidDataMap; 33631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv std::unique_ptr <DataContainer> data(new DataContainer()); 33731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv while (remaining > 0) { 33831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv time_t currentTimeUtc = time(nullptr); 33959b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv time_t currentUptime = android::GetUptime(); 34031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv CpuData *cpu = data->add_cpu(); 34131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv cpu->set_timestamp(currentTimeUtc); 34259b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv cpu->set_uptime(currentUptime); 34331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv android::PopulateCpu(*cpu); 34459b10642478f17f2d59ae0d1ca0e5c42fa17f026Vitalii Tomkiv android::ReadProcData(pidDataMap, *data.get(), currentTimeUtc, currentUptime); 34531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv remaining--; 34631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (remaining == 0) { 34731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv continue; 34831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 34931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv sleep(delayS); 35031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 35131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv std::string file_data; 35231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (!data->SerializeToString(&file_data)) { 35331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv LOG(ERROR) << "Failed to serialize"; 35431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv return; 35531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 35631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (!android::base::WriteStringToFile(file_data, getStoragePath())) { 35731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv LOG(ERROR) << "Failed to write samples"; 35831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 35931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv} 36031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 36131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkivvoid BootioCollector::Print() { 36231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv std::string file_data; 36331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (!android::base::ReadFileToString(getStoragePath(), &file_data)) { 36431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv printf("Failed to read data from file.\n"); 36531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv return; 36631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 36731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv std::unique_ptr <DataContainer> data(new DataContainer()); 36831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv if (!data->ParsePartialFromString(file_data)) { 36931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv printf("Failed to parse data.\n"); 37031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv return; 37131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 37231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv std::unordered_map<int, uint64_t> cpuDataMap; 37331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv for (int i = 0; i < data->cpu_size(); i++) { 37431c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv CpuData cpu_data = data->cpu(i); 37531c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv cpuDataMap[cpu_data.timestamp()] = android::SumCpuValues(cpu_data); 37631c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv } 37731c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv android::PrintPids(*data.get(), cpuDataMap); 37831c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv} 37931c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 38031c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv 38131c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkivstd::string BootioCollector::getStoragePath() { 38231c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv return path_ + SAMPLES_FILE; 38331c2e747abd0ba26e1abacbdd56d9f222e7d9e30Vitalii Tomkiv} 384