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#ifndef _STORAGED_UID_MONITOR_H_ 18bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#define _STORAGED_UID_MONITOR_H_ 19bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 20bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <stdint.h> 21bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 22bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <string> 23bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <unordered_map> 24a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian#include <vector> 25bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 265b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianenum uid_stat_t { 275b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian FOREGROUND = 0, 285b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian BACKGROUND = 1, 295b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian UID_STATS = 2 305b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian}; 315b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian 325b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianenum charger_stat_t { 335b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian CHARGER_OFF = 0, 345b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian CHARGER_ON = 1, 355b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian CHARGER_STATS = 2 365b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian}; 375b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian 385b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianenum io_type_t { 395b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian READ = 0, 405b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian WRITE = 1, 415b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian IO_TYPES = 2 42bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian}; 43bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 44bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qianstruct uid_io_stats { 45bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian uint64_t rchar; // characters read 46bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian uint64_t wchar; // characters written 47bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian uint64_t read_bytes; // bytes read (from storage layer) 48bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian uint64_t write_bytes; // bytes written (to storage layer) 49e83a6107c7b5c4e5bc4cca56012025de301212e7Jin Qian uint64_t fsync; // number of fsync syscalls 50bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian}; 51bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 52bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qianstruct uid_info { 53bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian uint32_t uid; // user id 54bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian std::string name; // package name 555b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian struct uid_io_stats io[UID_STATS]; // [0]:foreground [1]:background 56a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian}; 57bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 585b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianstruct uid_io_usage { 595b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian uint64_t bytes[IO_TYPES][UID_STATS][CHARGER_STATS]; 605b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian}; 615b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian 625b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianstruct uid_record { 63a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian std::string name; 645b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian struct uid_io_usage ios; 65bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian}; 66bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 678157775d791c124fcd84cdbeb7a751226bcb285bJin Qianstruct uid_records { 688157775d791c124fcd84cdbeb7a751226bcb285bJin Qian uint64_t start_ts; 698157775d791c124fcd84cdbeb7a751226bcb285bJin Qian std::vector<struct uid_record> entries; 708157775d791c124fcd84cdbeb7a751226bcb285bJin Qian}; 718157775d791c124fcd84cdbeb7a751226bcb285bJin Qian 72bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qianclass uid_monitor { 73bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qianprivate: 745b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian // last dump from /proc/uid_io/stats, uid -> uid_info 755b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian std::unordered_map<uint32_t, struct uid_info> last_uid_io_stats; 765b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian // current io usage for next report, app name -> uid_io_usage 775b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian std::unordered_map<std::string, struct uid_io_usage> curr_io_stats; 788157775d791c124fcd84cdbeb7a751226bcb285bJin Qian // io usage records, end timestamp -> {start timestamp, vector of records} 798157775d791c124fcd84cdbeb7a751226bcb285bJin Qian std::map<uint64_t, struct uid_records> records; 805b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian // charger ON/OFF 815b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian charger_stat_t charger_stat; 825b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian // protects curr_io_stats, last_uid_io_stats, records and charger_stat 835b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian sem_t um_lock; 848157775d791c124fcd84cdbeb7a751226bcb285bJin Qian // start time for IO records 858157775d791c124fcd84cdbeb7a751226bcb285bJin Qian uint64_t start_ts; 865b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian 875b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian // reads from /proc/uid_io/stats 885b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian std::unordered_map<uint32_t, struct uid_info> get_uid_io_stats_locked(); 895b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian // flushes curr_io_stats to records 905b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian void add_records_locked(uint64_t curr_ts); 915b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian // updates curr_io_stats and set last_uid_io_stats 925b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian void update_curr_io_stats_locked(); 935b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian 94bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qianpublic: 95bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian uid_monitor(); 96a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian ~uid_monitor(); 975b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian // called by storaged main thread 985b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian void init(charger_stat_t stat); 995b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian // called by storaged -u 1005b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian std::unordered_map<uint32_t, struct uid_info> get_uid_io_stats(); 1015b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian // called by dumpsys 1028157775d791c124fcd84cdbeb7a751226bcb285bJin Qian std::map<uint64_t, struct uid_records> dump( 103dd41d6b17115f5592f184b17351383c1b06d6336Jin Qian double hours, uint64_t threshold, bool force_report); 1045b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian // called by battery properties listener 1055b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian void set_charger_state(charger_stat_t stat); 1061275b1b6aaf417243ff3be17a400a21e26c42f39Jin Qian // called by storaged periodic_chore or dump with force_report 107bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian void report(); 108bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian}; 109bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian 110bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#endif /* _STORAGED_UID_MONITOR_H_ */ 111