/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef _IO_USAGE_H_ #define _IO_USAGE_H_ #include #include #include #include #include #define IO_USAGE_BUFFER_SIZE (6 * 30) #define IO_TOP_MAX 5 namespace android { namespace pixel { namespace perfstatsd { class ProcPidIoStats { private: std::chrono::system_clock::time_point mCheckTime; std::vector mPrevPids; std::vector mCurrPids; std::unordered_map mUidNameMapping; // functions std::vector getNewPids(); public: void update(bool forceAll); bool getNameForUid(uint32_t uid, std::string *name); }; struct UserIo { uint32_t uid; uint64_t fgRead; uint64_t bgRead; uint64_t fgWrite; uint64_t bgWrite; uint64_t fgFsync; uint64_t bgFsync; UserIo &operator=(const UserIo &other) { uid = other.uid; fgRead = other.fgRead; bgRead = other.bgRead; fgWrite = other.fgWrite; bgWrite = other.bgWrite; fgFsync = other.fgFsync; bgFsync = other.bgFsync; return *this; } UserIo operator-(const UserIo &other) const { UserIo r; r.uid = uid; r.fgRead = fgRead - other.fgRead; r.bgRead = bgRead - other.bgRead; r.fgWrite = fgWrite - other.fgWrite; r.bgWrite = bgWrite - other.bgWrite; r.fgFsync = fgFsync - other.fgFsync; r.bgFsync = bgFsync - other.bgFsync; return r; } UserIo operator+(const UserIo &other) const { UserIo r; r.uid = uid; r.fgRead = fgRead + other.fgRead; r.bgRead = bgRead + other.bgRead; r.fgWrite = fgWrite + other.fgWrite; r.bgWrite = bgWrite + other.bgWrite; r.fgFsync = fgFsync + other.fgFsync; r.bgFsync = bgFsync + other.bgFsync; return r; } uint64_t sumWrite() { return fgWrite + bgWrite; } uint64_t sumRead() { return fgRead + bgRead; } void reset() { uid = 0; fgRead = 0; bgRead = 0; fgWrite = 0; bgWrite = 0; fgFsync = 0; bgFsync = 0; } }; class ScopeTimer { private: bool mDisabled; std::string mName; std::chrono::system_clock::time_point mStart; public: ScopeTimer() : ScopeTimer("") {} ScopeTimer(std::string name) : mDisabled(false), mName(name) { mStart = std::chrono::system_clock::now(); } ~ScopeTimer() { if (!mDisabled) { std::string msg; dump(&msg); LOG_TO(SYSTEM, INFO) << msg; } } void setEnabled(bool enabled) { mDisabled = !enabled; } void dump(std::string *outAppend); }; constexpr uint64_t IO_USAGE_DUMP_THRESHOLD = 50L * 1000L * 1000L; // 50MB class IoStats { private: uint64_t mMinSizeOfTotalRead = IO_USAGE_DUMP_THRESHOLD; uint64_t mMinSizeOfTotalWrite = IO_USAGE_DUMP_THRESHOLD; std::chrono::system_clock::time_point mLast; std::chrono::system_clock::time_point mNow; std::unordered_map mPrevious; UserIo mTotal; UserIo mWriteTop[IO_TOP_MAX]; UserIo mReadTop[IO_TOP_MAX]; std::vector mUnknownUidList; std::unordered_map mUidNameMap; ProcPidIoStats mProcIoStats; // Functions std::unordered_map calcIncrement( const std::unordered_map &data); void updateTopWrite(UserIo usage); void updateTopRead(UserIo usage); void updateUnknownUidList(); public: IoStats() { mNow = std::chrono::system_clock::now(); mLast = mNow; } void calcAll(std::unordered_map &&data); void setDumpThresholdSizeForRead(uint64_t size) { mMinSizeOfTotalRead = size; } void setDumpThresholdSizeForWrite(uint64_t size) { mMinSizeOfTotalWrite = size; } bool dump(std::stringstream *output); }; class IoUsage : public StatsType { private: bool mDisabled; IoStats mStats; public: IoUsage() : mDisabled(false) {} void refresh(void); void setOptions(const std::string &key, const std::string &value); }; } // namespace perfstatsd } // namespace pixel } // namespace android #endif /* _IO_USAGE_H_ */