You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
4.7 KiB

/*
* 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 <statstype.h>
#include <chrono>
#include <sstream>
#include <string>
#include <unordered_map>
#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<uint32_t> mPrevPids;
std::vector<uint32_t> mCurrPids;
std::unordered_map<uint32_t, std::string> mUidNameMapping;
// functions
std::vector<uint32_t> 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(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<uint32_t, UserIo> mPrevious;
UserIo mTotal;
UserIo mWriteTop[IO_TOP_MAX];
UserIo mReadTop[IO_TOP_MAX];
std::vector<uint32_t> mUnknownUidList;
std::unordered_map<uint32_t, std::string> mUidNameMap;
ProcPidIoStats mProcIoStats;
// Functions
std::unordered_map<uint32_t, UserIo> calcIncrement(
const std::unordered_map<uint32_t, UserIo> &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<uint32_t, UserIo> &&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_ */