pmt: add memory test function and some new functions to libhelper
This commit is contained in:
@@ -22,6 +22,7 @@ set(PMT_SOURCES
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/functions/EraseFunction.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/functions/EraseFunction.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/functions/FlashFunction.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/functions/FlashFunction.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/functions/InfoFunction.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/functions/InfoFunction.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/functions/MemoryTestFunction.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/functions/PartitionSizeFunction.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/functions/PartitionSizeFunction.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/functions/RealPathFunction.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/functions/RealPathFunction.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/functions/RealLinkPathFunction.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/functions/RealLinkPathFunction.cpp
|
||||||
|
|||||||
@@ -100,8 +100,8 @@ int Main(int argc, char **argv) {
|
|||||||
AppMain);
|
AppMain);
|
||||||
FuncManager.registerFunction(std::make_unique<typeFunction>(), AppMain);
|
FuncManager.registerFunction(std::make_unique<typeFunction>(), AppMain);
|
||||||
FuncManager.registerFunction(std::make_unique<rebootFunction>(), AppMain);
|
FuncManager.registerFunction(std::make_unique<rebootFunction>(), AppMain);
|
||||||
// FuncManager.registerFunction(std::make_unique<memoryTestFunction>(),
|
FuncManager.registerFunction(std::make_unique<memoryTestFunction>(),
|
||||||
// AppMain);
|
AppMain);
|
||||||
|
|
||||||
CLI11_PARSE(AppMain, argc, argv);
|
CLI11_PARSE(AppMain, argc, argv);
|
||||||
|
|
||||||
@@ -119,7 +119,9 @@ int Main(int argc, char **argv) {
|
|||||||
"(--search-path)");
|
"(--search-path)");
|
||||||
|
|
||||||
if (!Helper::hasSuperUser()) {
|
if (!Helper::hasSuperUser()) {
|
||||||
if (!((FuncManager.isUsed("rebootFunction") /* || FuncManager.isUsed("memoryTestFunction") */) && Helper::hasAdbPermissions()))
|
if (!((FuncManager.isUsed("rebootFunction") ||
|
||||||
|
FuncManager.isUsed("memoryTestFunction")) &&
|
||||||
|
Helper::hasAdbPermissions()))
|
||||||
throw Error(
|
throw Error(
|
||||||
"Partition Manager Tool is requires super-user privileges!\n");
|
"Partition Manager Tool is requires super-user privileges!\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,10 +39,6 @@ bool memoryTestFunction::init(CLI::App &_app) {
|
|||||||
", no root? Try executing in ADB shell.");
|
", no root? Try executing in ADB shell.");
|
||||||
return std::string();
|
return std::string();
|
||||||
});
|
});
|
||||||
cmd->add_option("-b,--buffer-size", bufferSize,
|
|
||||||
"Buffer size for reading partition(s) and writing to file(s)")
|
|
||||||
->transform(CLI::AsSizeValue(false))
|
|
||||||
->default_val("4MB");
|
|
||||||
cmd->add_option("-s,--file-size", testFileSize, "File size of test file")
|
cmd->add_option("-s,--file-size", testFileSize, "File size of test file")
|
||||||
->transform(CLI::AsSizeValue(false))
|
->transform(CLI::AsSizeValue(false))
|
||||||
->default_val("1GB");
|
->default_val("1GB");
|
||||||
@@ -69,11 +65,13 @@ bool memoryTestFunction::run() {
|
|||||||
auto *buffer = new (std::nothrow) char[bufferSize];
|
auto *buffer = new (std::nothrow) char[bufferSize];
|
||||||
collector.delAfterProgress(buffer);
|
collector.delAfterProgress(buffer);
|
||||||
std::mt19937 rng(std::random_device{}());
|
std::mt19937 rng(std::random_device{}());
|
||||||
std::uniform_int_distribution<int> dist(0, 255);
|
std::uniform_int_distribution dist(0, 255);
|
||||||
|
|
||||||
for (size_t i = 0; i < bufferSize; i++)
|
for (size_t i = 0; i < bufferSize; i++)
|
||||||
buffer[i] = static_cast<char>(dist(rng));
|
buffer[i] = static_cast<char>(dist(rng));
|
||||||
|
|
||||||
|
collector.delFileAfterProgress(test);
|
||||||
|
|
||||||
if (!doNotWriteTest) {
|
if (!doNotWriteTest) {
|
||||||
const int wfd = Helper::openAndAddToCloseList(
|
const int wfd = Helper::openAndAddToCloseList(
|
||||||
test, collector, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0644);
|
test, collector, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0644);
|
||||||
@@ -99,25 +97,30 @@ bool memoryTestFunction::run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!doNotReadTest) {
|
if (!doNotReadTest) {
|
||||||
|
auto *rawBuffer = new char[bufferSize + 4096];
|
||||||
|
collector.delAfterProgress(rawBuffer);
|
||||||
|
auto *bufferRead = reinterpret_cast<char*>((reinterpret_cast<uintptr_t>(rawBuffer) + 4096 - 1) & ~(4096 - 1));
|
||||||
const int rfd =
|
const int rfd =
|
||||||
Helper::openAndAddToCloseList(test, collector, O_RDONLY | O_SYNC);
|
Helper::openAndAddToCloseList(test, collector, O_RDONLY | O_DIRECT);
|
||||||
if (rfd < 0) throw Error("Can't open test file: %s", strerror(errno));
|
if (rfd < 0) throw Error("Can't open test file: %s", strerror(errno));
|
||||||
|
|
||||||
LOGN(MTFUN, INFO) << "Sequential read test started!" << std::endl;
|
LOGN(MTFUN, INFO) << "Sequential read test started!" << std::endl;
|
||||||
const auto startRead = std::chrono::high_resolution_clock::now();
|
const auto startRead = std::chrono::high_resolution_clock::now();
|
||||||
while (read(rfd, buffer, bufferSize) > 0) {
|
size_t total = 0;
|
||||||
|
ssize_t bytesRead;
|
||||||
|
while ((bytesRead = read(rfd, bufferRead, bufferSize)) > 0) {
|
||||||
|
total += bytesRead;
|
||||||
}
|
}
|
||||||
const auto endRead = std::chrono::high_resolution_clock::now();
|
const auto endRead = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
const double read_time =
|
const double read_time =
|
||||||
std::chrono::duration<double>(endRead - startRead).count();
|
std::chrono::duration<double>(endRead - startRead).count();
|
||||||
println("Sequential read speed: %f MB/s",
|
println("Sequential read speed: %f MB/s",
|
||||||
(static_cast<double>(testFileSize) / (1024.0 * 1024.0)) /
|
(static_cast<double>(total) / (1024.0 * 1024.0)) /
|
||||||
read_time);
|
read_time);
|
||||||
LOGN(MTFUN, INFO) << "Sequential read test done!" << std::endl;
|
LOGN(MTFUN, INFO) << "Sequential read test done!" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Helper::eraseEntry(test);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ public:
|
|||||||
|
|
||||||
class memoryTestFunction final : public FunctionBase {
|
class memoryTestFunction final : public FunctionBase {
|
||||||
private:
|
private:
|
||||||
uint64_t bufferSize = 0, testFileSize = 0;
|
uint64_t bufferSize = MB(4), /* bufferSizeRandom = KB(4),*/ testFileSize = 0;
|
||||||
std::string testPath;
|
std::string testPath;
|
||||||
bool doNotWriteTest = false, doNotReadTest = false;
|
bool doNotWriteTest = false, doNotReadTest = false;
|
||||||
|
|
||||||
|
|||||||
@@ -81,12 +81,14 @@ private:
|
|||||||
std::vector<uint8_t *> _ptrs_u;
|
std::vector<uint8_t *> _ptrs_u;
|
||||||
std::vector<FILE *> _fps;
|
std::vector<FILE *> _fps;
|
||||||
std::vector<int> _fds;
|
std::vector<int> _fds;
|
||||||
|
std::vector<std::string_view> _files;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~garbageCollector();
|
~garbageCollector();
|
||||||
|
|
||||||
void delAfterProgress(char *&_ptr);
|
void delAfterProgress(char *&_ptr);
|
||||||
void delAfterProgress(uint8_t *&_ptr);
|
void delAfterProgress(uint8_t *&_ptr);
|
||||||
|
void delFileAfterProgress(std::string_view path);
|
||||||
void closeAfterProgress(FILE *&_fp);
|
void closeAfterProgress(FILE *&_fp);
|
||||||
void closeAfterProgress(int _fd);
|
void closeAfterProgress(int _fd);
|
||||||
};
|
};
|
||||||
@@ -151,6 +153,7 @@ std::string runCommandWithOutput(std::string_view cmd);
|
|||||||
std::string pathJoin(std::string base, std::string relative);
|
std::string pathJoin(std::string base, std::string relative);
|
||||||
std::string pathBasename(std::string_view entry);
|
std::string pathBasename(std::string_view entry);
|
||||||
std::string pathDirname(std::string_view entry);
|
std::string pathDirname(std::string_view entry);
|
||||||
|
uint64_t getRandomOffset(uint64_t size, uint64_t bufferSize);
|
||||||
|
|
||||||
// Android
|
// Android
|
||||||
std::string getProperty(std::string_view prop);
|
std::string getProperty(std::string_view prop);
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ garbageCollector::~garbageCollector() {
|
|||||||
close(fd);
|
close(fd);
|
||||||
for (const auto &fp : _fps)
|
for (const auto &fp : _fps)
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
for (const auto &file: _files)
|
||||||
|
eraseEntry(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCollector::delAfterProgress(char *&_ptr) {
|
void garbageCollector::delAfterProgress(char *&_ptr) {
|
||||||
@@ -103,6 +105,9 @@ void garbageCollector::delAfterProgress(char *&_ptr) {
|
|||||||
void garbageCollector::delAfterProgress(uint8_t *&_ptr) {
|
void garbageCollector::delAfterProgress(uint8_t *&_ptr) {
|
||||||
_ptrs_u.push_back(_ptr);
|
_ptrs_u.push_back(_ptr);
|
||||||
}
|
}
|
||||||
|
void garbageCollector::delFileAfterProgress(const std::string_view path) {
|
||||||
|
_files.push_back(path);
|
||||||
|
}
|
||||||
void garbageCollector::closeAfterProgress(const int _fd) {
|
void garbageCollector::closeAfterProgress(const int _fd) {
|
||||||
_fds.push_back(_fd);
|
_fds.push_back(_fd);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,5 +216,11 @@ bool reboot(const std::string_view arg) {
|
|||||||
return android_reboot(cmd, 0, arg.empty() ? nullptr : arg.data()) != -1;
|
return android_reboot(cmd, 0, arg.empty() ? nullptr : arg.data()) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t getRandomOffset(const uint64_t size, const uint64_t bufferSize) {
|
||||||
|
if (size <= bufferSize) return 0;
|
||||||
|
const uint64_t maxOffset = size - bufferSize;
|
||||||
|
return rand() % maxOffset;
|
||||||
|
}
|
||||||
|
|
||||||
std::string getLibVersion() { MKVERSION("libhelper"); }
|
std::string getLibVersion() { MKVERSION("libhelper"); }
|
||||||
} // namespace Helper
|
} // namespace Helper
|
||||||
|
|||||||
Reference in New Issue
Block a user