1bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian/* 2bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * Copyright (C) 2016 The Android Open Source Project 3bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * 4bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * Licensed under the Apache License, Version 2.0 (the "License"); 5bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * you may not use this file except in compliance with the License. 6bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * You may obtain a copy of the License at 7bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * 8bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * http://www.apache.org/licenses/LICENSE-2.0 9bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * 10bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * Unless required by applicable law or agreed to in writing, software 11bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * distributed under the License is distributed on an "AS IS" BASIS, 12bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * See the License for the specific language governing permissions and 14bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * limitations under the License. 15bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian */ 16bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 17bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#define LOG_TAG "storaged" 18bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 19bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <stdint.h> 20bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <time.h> 21bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 22bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <string> 23bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <unordered_map> 24bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 259c54268dce4c82f066e24dfc40803192f537e35fJin Qian#include <android/content/pm/IPackageManagerNative.h> 26bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <android-base/file.h> 27bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <android-base/logging.h> 28bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <android-base/macros.h> 299b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian#include <android-base/parseint.h> 30e83a6107c7b5c4e5bc4cca56012025de301212e7Jin Qian#include <android-base/strings.h> 31bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <android-base/stringprintf.h> 329c54268dce4c82f066e24dfc40803192f537e35fJin Qian#include <binder/IServiceManager.h> 33bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <log/log_event_list.h> 34bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 35bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include "storaged.h" 36bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include "storaged_uid_monitor.h" 37bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 38bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qianusing namespace android; 39bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qianusing namespace android::base; 409c54268dce4c82f066e24dfc40803192f537e35fJin Qianusing namespace android::content::pm; 41bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 429c54268dce4c82f066e24dfc40803192f537e35fJin Qianstatic bool refresh_uid_names; 43bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 445b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianstd::unordered_map<uint32_t, struct uid_info> uid_monitor::get_uid_io_stats() 45bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian{ 465b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian std::unique_ptr<lock_t> lock(new lock_t(&um_lock)); 475b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian return get_uid_io_stats_locked(); 485b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian}; 49bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 509c54268dce4c82f066e24dfc40803192f537e35fJin Qianstatic void get_uid_names(const vector<int>& uids, const vector<std::string*>& uid_names) 519c54268dce4c82f066e24dfc40803192f537e35fJin Qian{ 529c54268dce4c82f066e24dfc40803192f537e35fJin Qian sp<IServiceManager> sm = defaultServiceManager(); 539c54268dce4c82f066e24dfc40803192f537e35fJin Qian if (sm == NULL) { 549c54268dce4c82f066e24dfc40803192f537e35fJin Qian LOG_TO(SYSTEM, ERROR) << "defaultServiceManager failed"; 559c54268dce4c82f066e24dfc40803192f537e35fJin Qian return; 569c54268dce4c82f066e24dfc40803192f537e35fJin Qian } 579c54268dce4c82f066e24dfc40803192f537e35fJin Qian 589c54268dce4c82f066e24dfc40803192f537e35fJin Qian sp<IBinder> binder = sm->getService(String16("package_native")); 599c54268dce4c82f066e24dfc40803192f537e35fJin Qian if (binder == NULL) { 609c54268dce4c82f066e24dfc40803192f537e35fJin Qian LOG_TO(SYSTEM, ERROR) << "getService package_native failed"; 619c54268dce4c82f066e24dfc40803192f537e35fJin Qian return; 629c54268dce4c82f066e24dfc40803192f537e35fJin Qian } 639c54268dce4c82f066e24dfc40803192f537e35fJin Qian 649c54268dce4c82f066e24dfc40803192f537e35fJin Qian sp<IPackageManagerNative> package_mgr = interface_cast<IPackageManagerNative>(binder); 659c54268dce4c82f066e24dfc40803192f537e35fJin Qian std::vector<std::string> names; 669c54268dce4c82f066e24dfc40803192f537e35fJin Qian binder::Status status = package_mgr->getNamesForUids(uids, &names); 679c54268dce4c82f066e24dfc40803192f537e35fJin Qian if (!status.isOk()) { 689c54268dce4c82f066e24dfc40803192f537e35fJin Qian LOG_TO(SYSTEM, ERROR) << "package_native::getNamesForUids failed: " 699c54268dce4c82f066e24dfc40803192f537e35fJin Qian << status.exceptionMessage(); 709c54268dce4c82f066e24dfc40803192f537e35fJin Qian return; 719c54268dce4c82f066e24dfc40803192f537e35fJin Qian } 729c54268dce4c82f066e24dfc40803192f537e35fJin Qian 739c54268dce4c82f066e24dfc40803192f537e35fJin Qian for (uint32_t i = 0; i < uid_names.size(); i++) { 749c54268dce4c82f066e24dfc40803192f537e35fJin Qian if (!names[i].empty()) { 759c54268dce4c82f066e24dfc40803192f537e35fJin Qian *uid_names[i] = names[i]; 769c54268dce4c82f066e24dfc40803192f537e35fJin Qian } 779c54268dce4c82f066e24dfc40803192f537e35fJin Qian } 789c54268dce4c82f066e24dfc40803192f537e35fJin Qian 799c54268dce4c82f066e24dfc40803192f537e35fJin Qian refresh_uid_names = false; 809c54268dce4c82f066e24dfc40803192f537e35fJin Qian} 819c54268dce4c82f066e24dfc40803192f537e35fJin Qian 825b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianstd::unordered_map<uint32_t, struct uid_info> uid_monitor::get_uid_io_stats_locked() 83bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian{ 845b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian std::unordered_map<uint32_t, struct uid_info> uid_io_stats; 85bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian std::string buffer; 869b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian if (!ReadFileToString(UID_IO_STATS_PATH, &buffer)) { 87bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian PLOG_TO(SYSTEM, ERROR) << UID_IO_STATS_PATH << ": ReadFileToString failed"; 885b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian return uid_io_stats; 89bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian } 90bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 919b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian std::vector<std::string> io_stats = Split(buffer, "\n"); 92bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian struct uid_info u; 939c54268dce4c82f066e24dfc40803192f537e35fJin Qian vector<int> uids; 949c54268dce4c82f066e24dfc40803192f537e35fJin Qian vector<std::string*> uid_names; 95bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 96e83a6107c7b5c4e5bc4cca56012025de301212e7Jin Qian for (uint32_t i = 0; i < io_stats.size(); i++) { 97e83a6107c7b5c4e5bc4cca56012025de301212e7Jin Qian if (io_stats[i].empty()) { 98e83a6107c7b5c4e5bc4cca56012025de301212e7Jin Qian continue; 99e83a6107c7b5c4e5bc4cca56012025de301212e7Jin Qian } 1009b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian std::vector<std::string> fields = Split(io_stats[i], " "); 1019b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian if (fields.size() < 11 || 1029b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian !ParseUint(fields[0], &u.uid) || 1039b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian !ParseUint(fields[1], &u.io[FOREGROUND].rchar) || 1049b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian !ParseUint(fields[2], &u.io[FOREGROUND].wchar) || 1059b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian !ParseUint(fields[3], &u.io[FOREGROUND].read_bytes) || 1069b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian !ParseUint(fields[4], &u.io[FOREGROUND].write_bytes) || 1079b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian !ParseUint(fields[5], &u.io[BACKGROUND].rchar) || 1089b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian !ParseUint(fields[6], &u.io[BACKGROUND].wchar) || 1099b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian !ParseUint(fields[7], &u.io[BACKGROUND].read_bytes) || 1109b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian !ParseUint(fields[8], &u.io[BACKGROUND].write_bytes) || 1119b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian !ParseUint(fields[9], &u.io[FOREGROUND].fsync) || 1129b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian !ParseUint(fields[10], &u.io[BACKGROUND].fsync)) { 1139b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian LOG_TO(SYSTEM, WARNING) << "Invalid I/O stats: \"" 114e83a6107c7b5c4e5bc4cca56012025de301212e7Jin Qian << io_stats[i] << "\""; 115e83a6107c7b5c4e5bc4cca56012025de301212e7Jin Qian continue; 116e83a6107c7b5c4e5bc4cca56012025de301212e7Jin Qian } 117bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 1189c54268dce4c82f066e24dfc40803192f537e35fJin Qian uid_io_stats[u.uid] = u; 1199c54268dce4c82f066e24dfc40803192f537e35fJin Qian uid_io_stats[u.uid].name = std::to_string(u.uid); 1209c54268dce4c82f066e24dfc40803192f537e35fJin Qian uids.push_back(u.uid); 1219c54268dce4c82f066e24dfc40803192f537e35fJin Qian uid_names.push_back(&uid_io_stats[u.uid].name); 1225b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian if (last_uid_io_stats.find(u.uid) == last_uid_io_stats.end()) { 1239c54268dce4c82f066e24dfc40803192f537e35fJin Qian refresh_uid_names = true; 124bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian } else { 1259c54268dce4c82f066e24dfc40803192f537e35fJin Qian uid_io_stats[u.uid].name = last_uid_io_stats[u.uid].name; 126bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian } 127bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian } 128bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 1299c54268dce4c82f066e24dfc40803192f537e35fJin Qian if (!uids.empty() && refresh_uid_names) { 1309c54268dce4c82f066e24dfc40803192f537e35fJin Qian get_uid_names(uids, uid_names); 131bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian } 132bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 1335b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian return uid_io_stats; 134bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian} 135bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 1365b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianstatic const int MAX_UID_RECORDS_SIZE = 1000 * 48; // 1000 uids in 48 hours 137a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian 1385b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianstatic inline int records_size( 1398157775d791c124fcd84cdbeb7a751226bcb285bJin Qian const std::map<uint64_t, struct uid_records>& curr_records) 140a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian{ 1415b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian int count = 0; 1428157775d791c124fcd84cdbeb7a751226bcb285bJin Qian for (auto const& it : curr_records) { 1438157775d791c124fcd84cdbeb7a751226bcb285bJin Qian count += it.second.entries.size(); 1445b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian } 1455b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian return count; 146a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian} 147a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian 1485b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianstatic struct uid_io_usage zero_io_usage; 1499cdfdd3ff9481318a1631bd5584bfb527756d4d4Jin Qian 1505b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianvoid uid_monitor::add_records_locked(uint64_t curr_ts) 1515b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian{ 1525b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian // remove records more than 5 days old 1535b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian if (curr_ts > 5 * DAY_TO_SEC) { 1545b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian auto it = records.lower_bound(curr_ts - 5 * DAY_TO_SEC); 1555b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian records.erase(records.begin(), it); 1569cdfdd3ff9481318a1631bd5584bfb527756d4d4Jin Qian } 1579cdfdd3ff9481318a1631bd5584bfb527756d4d4Jin Qian 1588157775d791c124fcd84cdbeb7a751226bcb285bJin Qian struct uid_records new_records; 1595b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian for (const auto& p : curr_io_stats) { 1605b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian struct uid_record record = {}; 1615b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian record.name = p.first; 1625b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian record.ios = p.second; 1635b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian if (memcmp(&record.ios, &zero_io_usage, sizeof(struct uid_io_usage))) { 1648157775d791c124fcd84cdbeb7a751226bcb285bJin Qian new_records.entries.push_back(record); 1655b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian } 1669cdfdd3ff9481318a1631bd5584bfb527756d4d4Jin Qian } 1679cdfdd3ff9481318a1631bd5584bfb527756d4d4Jin Qian 1685b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian curr_io_stats.clear(); 1698157775d791c124fcd84cdbeb7a751226bcb285bJin Qian new_records.start_ts = start_ts; 1708157775d791c124fcd84cdbeb7a751226bcb285bJin Qian start_ts = curr_ts; 171a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian 1728157775d791c124fcd84cdbeb7a751226bcb285bJin Qian if (new_records.entries.empty()) 1735b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian return; 1745b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian 1755b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian // make some room for new records 1765b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian int overflow = records_size(records) + 1778157775d791c124fcd84cdbeb7a751226bcb285bJin Qian new_records.entries.size() - MAX_UID_RECORDS_SIZE; 1785b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian while (overflow > 0 && records.size() > 0) { 1798157775d791c124fcd84cdbeb7a751226bcb285bJin Qian auto del_it = records.begin(); 1808157775d791c124fcd84cdbeb7a751226bcb285bJin Qian overflow -= del_it->second.entries.size(); 1815b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian records.erase(records.begin()); 1825b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian } 1835b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian 1848157775d791c124fcd84cdbeb7a751226bcb285bJin Qian records[curr_ts] = new_records; 185a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian} 186a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian 1878157775d791c124fcd84cdbeb7a751226bcb285bJin Qianstd::map<uint64_t, struct uid_records> uid_monitor::dump( 188dd41d6b17115f5592f184b17351383c1b06d6336Jin Qian double hours, uint64_t threshold, bool force_report) 189bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian{ 1901275b1b6aaf417243ff3be17a400a21e26c42f39Jin Qian if (force_report) { 1911275b1b6aaf417243ff3be17a400a21e26c42f39Jin Qian report(); 1921275b1b6aaf417243ff3be17a400a21e26c42f39Jin Qian } 1931275b1b6aaf417243ff3be17a400a21e26c42f39Jin Qian 1945b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian std::unique_ptr<lock_t> lock(new lock_t(&um_lock)); 195bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 1968157775d791c124fcd84cdbeb7a751226bcb285bJin Qian std::map<uint64_t, struct uid_records> dump_records; 1975b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian uint64_t first_ts = 0; 1985b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian 1995b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian if (hours != 0) { 200dd41d6b17115f5592f184b17351383c1b06d6336Jin Qian first_ts = time(NULL) - hours * HOUR_TO_SEC; 201bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian } 202bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 203e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian for (auto it = records.lower_bound(first_ts); it != records.end(); ++it) { 2048157775d791c124fcd84cdbeb7a751226bcb285bJin Qian const std::vector<struct uid_record>& recs = it->second.entries; 2058157775d791c124fcd84cdbeb7a751226bcb285bJin Qian struct uid_records filtered; 206e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian 207e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian for (const auto& rec : recs) { 208e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian if (rec.ios.bytes[READ][FOREGROUND][CHARGER_ON] + 209e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian rec.ios.bytes[READ][FOREGROUND][CHARGER_OFF] + 210e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian rec.ios.bytes[READ][BACKGROUND][CHARGER_ON] + 211e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian rec.ios.bytes[READ][BACKGROUND][CHARGER_OFF] + 212e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian rec.ios.bytes[WRITE][FOREGROUND][CHARGER_ON] + 213e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian rec.ios.bytes[WRITE][FOREGROUND][CHARGER_OFF] + 214e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian rec.ios.bytes[WRITE][BACKGROUND][CHARGER_ON] + 215e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian rec.ios.bytes[WRITE][BACKGROUND][CHARGER_OFF] > threshold) { 2168157775d791c124fcd84cdbeb7a751226bcb285bJin Qian filtered.entries.push_back(rec); 217e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian } 218e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian } 2198157775d791c124fcd84cdbeb7a751226bcb285bJin Qian 2208157775d791c124fcd84cdbeb7a751226bcb285bJin Qian if (filtered.entries.empty()) 2218157775d791c124fcd84cdbeb7a751226bcb285bJin Qian continue; 2228157775d791c124fcd84cdbeb7a751226bcb285bJin Qian 2238157775d791c124fcd84cdbeb7a751226bcb285bJin Qian filtered.start_ts = it->second.start_ts; 224e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian dump_records.insert( 2258157775d791c124fcd84cdbeb7a751226bcb285bJin Qian std::pair<uint64_t, struct uid_records>(it->first, filtered)); 226e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian } 2275b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian 2285b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian return dump_records; 2295b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian} 230bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 2315b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianvoid uid_monitor::update_curr_io_stats_locked() 2325b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian{ 2335b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian std::unordered_map<uint32_t, struct uid_info> uid_io_stats = 2345b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian get_uid_io_stats_locked(); 2355b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian if (uid_io_stats.empty()) { 236bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian return; 237bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian } 238bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 2395b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian for (const auto& it : uid_io_stats) { 240bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian const struct uid_info& uid = it.second; 2415b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian 2425b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian if (curr_io_stats.find(uid.name) == curr_io_stats.end()) { 2435b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian curr_io_stats[uid.name] = {}; 2449cdfdd3ff9481318a1631bd5584bfb527756d4d4Jin Qian } 2459cdfdd3ff9481318a1631bd5584bfb527756d4d4Jin Qian 2465b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian struct uid_io_usage& usage = curr_io_stats[uid.name]; 247baff640d5d0a1abd95458f08017fe0e8babb8103Jin Qian int64_t fg_rd_delta = uid.io[FOREGROUND].read_bytes - 2485b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian last_uid_io_stats[uid.uid].io[FOREGROUND].read_bytes; 249baff640d5d0a1abd95458f08017fe0e8babb8103Jin Qian int64_t bg_rd_delta = uid.io[BACKGROUND].read_bytes - 2505b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian last_uid_io_stats[uid.uid].io[BACKGROUND].read_bytes; 251baff640d5d0a1abd95458f08017fe0e8babb8103Jin Qian int64_t fg_wr_delta = uid.io[FOREGROUND].write_bytes - 2525b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian last_uid_io_stats[uid.uid].io[FOREGROUND].write_bytes; 253baff640d5d0a1abd95458f08017fe0e8babb8103Jin Qian int64_t bg_wr_delta = uid.io[BACKGROUND].write_bytes - 254baff640d5d0a1abd95458f08017fe0e8babb8103Jin Qian last_uid_io_stats[uid.uid].io[BACKGROUND].write_bytes; 255baff640d5d0a1abd95458f08017fe0e8babb8103Jin Qian 256baff640d5d0a1abd95458f08017fe0e8babb8103Jin Qian usage.bytes[READ][FOREGROUND][charger_stat] += 257ccae2b5779e01e885bd7c85e314a2f8f523c4b94Jin Qian (fg_rd_delta < 0) ? 0 : fg_rd_delta; 258baff640d5d0a1abd95458f08017fe0e8babb8103Jin Qian usage.bytes[READ][BACKGROUND][charger_stat] += 259ccae2b5779e01e885bd7c85e314a2f8f523c4b94Jin Qian (bg_rd_delta < 0) ? 0 : bg_rd_delta; 260baff640d5d0a1abd95458f08017fe0e8babb8103Jin Qian usage.bytes[WRITE][FOREGROUND][charger_stat] += 261ccae2b5779e01e885bd7c85e314a2f8f523c4b94Jin Qian (fg_wr_delta < 0) ? 0 : fg_wr_delta; 2625b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian usage.bytes[WRITE][BACKGROUND][charger_stat] += 263ccae2b5779e01e885bd7c85e314a2f8f523c4b94Jin Qian (bg_wr_delta < 0) ? 0 : bg_wr_delta; 264bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian } 265bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 2665b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian last_uid_io_stats = uid_io_stats; 267bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian} 268bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 2695b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianvoid uid_monitor::report() 2705b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian{ 2715b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian std::unique_ptr<lock_t> lock(new lock_t(&um_lock)); 2725b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian 2735b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian update_curr_io_stats_locked(); 2745b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian add_records_locked(time(NULL)); 2755b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian} 2765b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian 2775b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianvoid uid_monitor::set_charger_state(charger_stat_t stat) 278bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian{ 2795b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian std::unique_ptr<lock_t> lock(new lock_t(&um_lock)); 280bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 2815b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian if (charger_stat == stat) { 282bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian return; 283bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian } 284a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian 2855b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian update_curr_io_stats_locked(); 2865b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian charger_stat = stat; 2875b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian} 2885b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian 2895b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianvoid uid_monitor::init(charger_stat_t stat) 2905b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian{ 2915b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian charger_stat = stat; 2928157775d791c124fcd84cdbeb7a751226bcb285bJin Qian start_ts = time(NULL); 2935b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian last_uid_io_stats = get_uid_io_stats(); 2945b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian} 2955b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian 2965b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianuid_monitor::uid_monitor() 2975b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian{ 2985b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian sem_init(&um_lock, 0, 1); 299a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian} 300a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian 301a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qianuid_monitor::~uid_monitor() 302a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian{ 3035b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian sem_destroy(&um_lock); 304bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian} 305