1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #ifndef _IO_USAGE_H_ 17 #define _IO_USAGE_H_ 18 19 #include <statstype.h> 20 #include <chrono> 21 #include <sstream> 22 #include <string> 23 24 #include <unordered_map> 25 26 #define IO_USAGE_BUFFER_SIZE (6 * 30) 27 #define IO_TOP_MAX 5 28 29 namespace android { 30 namespace pixel { 31 namespace perfstatsd { 32 33 class ProcPidIoStats { 34 private: 35 std::chrono::system_clock::time_point mCheckTime; 36 std::vector<uint32_t> mPrevPids; 37 std::vector<uint32_t> mCurrPids; 38 std::unordered_map<uint32_t, std::string> mUidNameMapping; 39 // functions 40 std::vector<uint32_t> getNewPids(); 41 42 public: 43 void update(bool forceAll); 44 bool getNameForUid(uint32_t uid, std::string *name); 45 }; 46 47 struct UserIo { 48 uint32_t uid; 49 uint64_t fgRead; 50 uint64_t bgRead; 51 uint64_t fgWrite; 52 uint64_t bgWrite; 53 uint64_t fgFsync; 54 uint64_t bgFsync; 55 56 UserIo &operator=(const UserIo &other) { 57 uid = other.uid; 58 fgRead = other.fgRead; 59 bgRead = other.bgRead; 60 fgWrite = other.fgWrite; 61 bgWrite = other.bgWrite; 62 fgFsync = other.fgFsync; 63 bgFsync = other.bgFsync; 64 return *this; 65 } 66 67 UserIo operator-(const UserIo &other) const { 68 UserIo r; 69 r.uid = uid; 70 r.fgRead = fgRead - other.fgRead; 71 r.bgRead = bgRead - other.bgRead; 72 r.fgWrite = fgWrite - other.fgWrite; 73 r.bgWrite = bgWrite - other.bgWrite; 74 r.fgFsync = fgFsync - other.fgFsync; 75 r.bgFsync = bgFsync - other.bgFsync; 76 return r; 77 } 78 79 UserIo operator+(const UserIo &other) const { 80 UserIo r; 81 r.uid = uid; 82 r.fgRead = fgRead + other.fgRead; 83 r.bgRead = bgRead + other.bgRead; 84 r.fgWrite = fgWrite + other.fgWrite; 85 r.bgWrite = bgWrite + other.bgWrite; 86 r.fgFsync = fgFsync + other.fgFsync; 87 r.bgFsync = bgFsync + other.bgFsync; 88 return r; 89 } 90 sumWriteUserIo91 uint64_t sumWrite() { return fgWrite + bgWrite; } 92 sumReadUserIo93 uint64_t sumRead() { return fgRead + bgRead; } 94 resetUserIo95 void reset() { 96 uid = 0; 97 fgRead = 0; 98 bgRead = 0; 99 fgWrite = 0; 100 bgWrite = 0; 101 fgFsync = 0; 102 bgFsync = 0; 103 } 104 }; 105 106 class ScopeTimer { 107 private: 108 bool mDisabled; 109 std::string mName; 110 std::chrono::system_clock::time_point mStart; 111 112 public: ScopeTimer()113 ScopeTimer() : ScopeTimer("") {} ScopeTimer(std::string name)114 ScopeTimer(std::string name) : mDisabled(false), mName(name) { 115 mStart = std::chrono::system_clock::now(); 116 } ~ScopeTimer()117 ~ScopeTimer() { 118 if (!mDisabled) { 119 std::string msg; 120 dump(&msg); 121 LOG(INFO) << msg; 122 } 123 } setEnabled(bool enabled)124 void setEnabled(bool enabled) { mDisabled = !enabled; } 125 void dump(std::string *outAppend); 126 }; 127 128 constexpr uint64_t IO_USAGE_DUMP_THRESHOLD = 50L * 1000L * 1000L; // 50MB 129 class IoStats { 130 private: 131 uint64_t mMinSizeOfTotalRead = IO_USAGE_DUMP_THRESHOLD; 132 uint64_t mMinSizeOfTotalWrite = IO_USAGE_DUMP_THRESHOLD; 133 std::chrono::system_clock::time_point mLast; 134 std::chrono::system_clock::time_point mNow; 135 std::unordered_map<uint32_t, UserIo> mPrevious; 136 UserIo mTotal; 137 UserIo mWriteTop[IO_TOP_MAX]; 138 UserIo mReadTop[IO_TOP_MAX]; 139 std::vector<uint32_t> mUnknownUidList; 140 std::unordered_map<uint32_t, std::string> mUidNameMap; 141 ProcPidIoStats mProcIoStats; 142 // Functions 143 std::unordered_map<uint32_t, UserIo> calcIncrement( 144 const std::unordered_map<uint32_t, UserIo> &data); 145 void updateTopWrite(UserIo usage); 146 void updateTopRead(UserIo usage); 147 void updateUnknownUidList(); 148 149 public: IoStats()150 IoStats() { 151 mNow = std::chrono::system_clock::now(); 152 mLast = mNow; 153 } 154 void calcAll(std::unordered_map<uint32_t, UserIo> &&data); setDumpThresholdSizeForRead(uint64_t size)155 void setDumpThresholdSizeForRead(uint64_t size) { mMinSizeOfTotalRead = size; } setDumpThresholdSizeForWrite(uint64_t size)156 void setDumpThresholdSizeForWrite(uint64_t size) { mMinSizeOfTotalWrite = size; } 157 bool dump(std::stringstream *output); 158 }; 159 160 class IoUsage : public StatsType { 161 private: 162 bool mDisabled; 163 IoStats mStats; 164 165 public: IoUsage()166 IoUsage() : mDisabled(false) {} 167 void refresh(void); 168 void setOptions(const std::string &key, const std::string &value); 169 }; 170 171 } // namespace perfstatsd 172 } // namespace pixel 173 } // namespace android 174 175 #endif /* _IO_USAGE_H_ */ 176