From bf0df8cc8370ddcdb096356d2218979acad2a00e Mon Sep 17 00:00:00 2001 From: YZBruh Date: Wed, 13 Aug 2025 10:58:48 +0300 Subject: [PATCH] pmt: add memory test function and some new functions to libhelper --- src/CMakeLists.txt | 1 + src/PartitionManager.cpp | 8 +++++--- src/functions/MemoryTestFunction.cpp | 21 ++++++++++++--------- src/functions/functions.hpp | 2 +- srclib/libhelper/include/libhelper/lib.hpp | 3 +++ srclib/libhelper/src/Classes.cpp | 5 +++++ srclib/libhelper/src/Utilities.cpp | 6 ++++++ 7 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a0bcae6..1597b24 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,6 +22,7 @@ set(PMT_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/functions/EraseFunction.cpp ${CMAKE_CURRENT_SOURCE_DIR}/functions/FlashFunction.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/RealPathFunction.cpp ${CMAKE_CURRENT_SOURCE_DIR}/functions/RealLinkPathFunction.cpp diff --git a/src/PartitionManager.cpp b/src/PartitionManager.cpp index 78c2fc7..8d8f017 100644 --- a/src/PartitionManager.cpp +++ b/src/PartitionManager.cpp @@ -100,8 +100,8 @@ int Main(int argc, char **argv) { AppMain); FuncManager.registerFunction(std::make_unique(), AppMain); FuncManager.registerFunction(std::make_unique(), AppMain); - // FuncManager.registerFunction(std::make_unique(), - // AppMain); + FuncManager.registerFunction(std::make_unique(), + AppMain); CLI11_PARSE(AppMain, argc, argv); @@ -119,7 +119,9 @@ int Main(int argc, char **argv) { "(--search-path)"); if (!Helper::hasSuperUser()) { - if (!((FuncManager.isUsed("rebootFunction") /* || FuncManager.isUsed("memoryTestFunction") */) && Helper::hasAdbPermissions())) + if (!((FuncManager.isUsed("rebootFunction") || + FuncManager.isUsed("memoryTestFunction")) && + Helper::hasAdbPermissions())) throw Error( "Partition Manager Tool is requires super-user privileges!\n"); } diff --git a/src/functions/MemoryTestFunction.cpp b/src/functions/MemoryTestFunction.cpp index ca88056..e1a8099 100644 --- a/src/functions/MemoryTestFunction.cpp +++ b/src/functions/MemoryTestFunction.cpp @@ -39,10 +39,6 @@ bool memoryTestFunction::init(CLI::App &_app) { ", no root? Try executing in ADB shell."); 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") ->transform(CLI::AsSizeValue(false)) ->default_val("1GB"); @@ -69,11 +65,13 @@ bool memoryTestFunction::run() { auto *buffer = new (std::nothrow) char[bufferSize]; collector.delAfterProgress(buffer); std::mt19937 rng(std::random_device{}()); - std::uniform_int_distribution dist(0, 255); + std::uniform_int_distribution dist(0, 255); for (size_t i = 0; i < bufferSize; i++) buffer[i] = static_cast(dist(rng)); + collector.delFileAfterProgress(test); + if (!doNotWriteTest) { const int wfd = Helper::openAndAddToCloseList( test, collector, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0644); @@ -99,25 +97,30 @@ bool memoryTestFunction::run() { } if (!doNotReadTest) { + auto *rawBuffer = new char[bufferSize + 4096]; + collector.delAfterProgress(rawBuffer); + auto *bufferRead = reinterpret_cast((reinterpret_cast(rawBuffer) + 4096 - 1) & ~(4096 - 1)); 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)); LOGN(MTFUN, INFO) << "Sequential read test started!" << std::endl; 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 double read_time = std::chrono::duration(endRead - startRead).count(); println("Sequential read speed: %f MB/s", - (static_cast(testFileSize) / (1024.0 * 1024.0)) / + (static_cast(total) / (1024.0 * 1024.0)) / read_time); LOGN(MTFUN, INFO) << "Sequential read test done!" << std::endl; } - Helper::eraseEntry(test); return true; } diff --git a/src/functions/functions.hpp b/src/functions/functions.hpp index ffd8ef1..180793b 100644 --- a/src/functions/functions.hpp +++ b/src/functions/functions.hpp @@ -173,7 +173,7 @@ public: class memoryTestFunction final : public FunctionBase { private: - uint64_t bufferSize = 0, testFileSize = 0; + uint64_t bufferSize = MB(4), /* bufferSizeRandom = KB(4),*/ testFileSize = 0; std::string testPath; bool doNotWriteTest = false, doNotReadTest = false; diff --git a/srclib/libhelper/include/libhelper/lib.hpp b/srclib/libhelper/include/libhelper/lib.hpp index 2c43444..fc210be 100644 --- a/srclib/libhelper/include/libhelper/lib.hpp +++ b/srclib/libhelper/include/libhelper/lib.hpp @@ -81,12 +81,14 @@ private: std::vector _ptrs_u; std::vector _fps; std::vector _fds; + std::vector _files; public: ~garbageCollector(); void delAfterProgress(char *&_ptr); void delAfterProgress(uint8_t *&_ptr); + void delFileAfterProgress(std::string_view path); void closeAfterProgress(FILE *&_fp); 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 pathBasename(std::string_view entry); std::string pathDirname(std::string_view entry); +uint64_t getRandomOffset(uint64_t size, uint64_t bufferSize); // Android std::string getProperty(std::string_view prop); diff --git a/srclib/libhelper/src/Classes.cpp b/srclib/libhelper/src/Classes.cpp index 6aeb702..b833421 100644 --- a/srclib/libhelper/src/Classes.cpp +++ b/srclib/libhelper/src/Classes.cpp @@ -95,6 +95,8 @@ garbageCollector::~garbageCollector() { close(fd); for (const auto &fp : _fps) fclose(fp); + for (const auto &file: _files) + eraseEntry(file); } void garbageCollector::delAfterProgress(char *&_ptr) { @@ -103,6 +105,9 @@ void garbageCollector::delAfterProgress(char *&_ptr) { void garbageCollector::delAfterProgress(uint8_t *&_ptr) { _ptrs_u.push_back(_ptr); } +void garbageCollector::delFileAfterProgress(const std::string_view path) { + _files.push_back(path); +} void garbageCollector::closeAfterProgress(const int _fd) { _fds.push_back(_fd); } diff --git a/srclib/libhelper/src/Utilities.cpp b/srclib/libhelper/src/Utilities.cpp index 554d772..959b4ce 100644 --- a/srclib/libhelper/src/Utilities.cpp +++ b/srclib/libhelper/src/Utilities.cpp @@ -216,5 +216,11 @@ bool reboot(const std::string_view arg) { 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"); } } // namespace Helper