From 889623874ef6233610ed529bff18e1ba2c407e14 Mon Sep 17 00:00:00 2001 From: crestfalln Date: Wed, 27 Sep 2023 23:57:06 +0530 Subject: [PATCH 1/3] made disks stat logic async --- src/linux/btop_collect.cpp | 59 ++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/src/linux/btop_collect.cpp b/src/linux/btop_collect.cpp index 8a475e2..d26405a 100644 --- a/src/linux/btop_collect.cpp +++ b/src/linux/btop_collect.cpp @@ -29,6 +29,7 @@ tab-size = 4 #include #include // for inet_ntop() #include +#include #if !(defined(STATIC_BUILD) && defined(__GLIBC__)) #include @@ -48,12 +49,17 @@ using std::numeric_limits; using std::round; using std::streamsize; using std::vector; +using std::future; +using std::async; +using std::pair; + namespace fs = std::filesystem; namespace rng = std::ranges; using namespace Tools; using namespace std::literals; // for operator""s +using namespace std::chrono_literals; //? --------------------------------------------------- FUNCTIONS ----------------------------------------------------- namespace Cpu { @@ -939,6 +945,7 @@ namespace Mem { auto only_physical = Config::getB("only_physical"); auto zfs_hide_datasets = Config::getB("zfs_hide_datasets"); auto& disks = mem.disks; + static unordered_flat_map>> disks_stats_promises; ifstream diskread; vector filter; @@ -1078,31 +1085,41 @@ namespace Mem { diskread.close(); //? Get disk/partition stats - bool new_ignored = false; - for (auto& [mountpoint, disk] : disks) { - if (std::error_code ec; not fs::exists(mountpoint, ec) or v_contains(ignore_list, mountpoint)) continue; - struct statvfs vfs; - if (statvfs(mountpoint.c_str(), &vfs) < 0) { - Logger::warning("Failed to get disk/partition stats for mount \""+ mountpoint + "\" with statvfs error code: " + to_string(errno) + ". Ignoring..."); - ignore_list.push_back(mountpoint); - new_ignored = true; + for (auto it = disks.begin(); it != disks.end(); ) { + auto &[mountpoint, disk] = *it; + if (v_contains(ignore_list, mountpoint)) { + it = disks.erase(it); continue; } - disk.total = vfs.f_blocks * vfs.f_frsize; - disk.free = (free_priv ? vfs.f_bfree : vfs.f_bavail) * vfs.f_frsize; - disk.used = disk.total - disk.free; - disk.used_percent = round((double)disk.used * 100 / disk.total); - disk.free_percent = 100 - disk.used_percent; - } - - //? Remove any problematic disks added to the ignore_list - if (new_ignored) { - for (auto it = disks.begin(); it != disks.end();) { - if (v_contains(ignore_list, it->first)) + if(auto promises_it = disks_stats_promises.find(mountpoint); promises_it != disks_stats_promises.end()){ + auto& promise = promises_it->second; + if(promise.valid() && + promise.wait_for(0s) == std::future_status::timeout) { + ++it; + continue; + } + auto promise_res = promises_it->second.get(); + if(promise_res.second != -1){ + ignore_list.push_back(mountpoint); + Logger::warning("Failed to get disk/partition stats for mount \""+ mountpoint + "\" with statvfs error code: " + to_string(promise_res.second) + ". Ignoring..."); it = disks.erase(it); - else - it++; + continue; + } + disk = promise_res.first; } + disks_stats_promises[mountpoint] = async(std::launch::async, [mountpoint, &free_priv](disk_info disk) -> pair { + struct statvfs vfs; + if (statvfs(mountpoint.c_str(), &vfs) < 0) { + return pair{disk, errno}; + } + disk.total = vfs.f_blocks * vfs.f_frsize; + disk.free = (free_priv ? vfs.f_bfree : vfs.f_bavail) * vfs.f_frsize; + disk.used = disk.total - disk.free; + disk.used_percent = round((double)disk.used * 100 / disk.total); + disk.free_percent = 100 - disk.used_percent; + return pair{disk, -1}; + }, disk); + ++it; } //? Setup disks order in UI and add swap if enabled From 9b4e85f08dc3be40d8f4904093cd2bdd096e60fa Mon Sep 17 00:00:00 2001 From: crestfalln Date: Thu, 28 Sep 2023 04:57:05 +0530 Subject: [PATCH 2/3] fixed bug where updated disks stats overrided disk io data --- src/btop_shared.hpp | 1 + src/linux/btop_collect.cpp | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/btop_shared.hpp b/src/btop_shared.hpp index ecf97f2..6f0dee5 100644 --- a/src/btop_shared.hpp +++ b/src/btop_shared.hpp @@ -147,6 +147,7 @@ namespace Mem { int64_t free{}; // defaults to 0 int used_percent{}; // defaults to 0 int free_percent{}; // defaults to 0 + bool is_ready = false; array old_io = {0, 0, 0}; deque io_read = {}; diff --git a/src/linux/btop_collect.cpp b/src/linux/btop_collect.cpp index d26405a..1d449f5 100644 --- a/src/linux/btop_collect.cpp +++ b/src/linux/btop_collect.cpp @@ -1105,10 +1105,17 @@ namespace Mem { it = disks.erase(it); continue; } - disk = promise_res.first; + auto &updated_stats = promise_res.first; + disk.total = updated_stats.total; + disk.free = updated_stats.free; + disk.used = updated_stats.used; + disk.used_percent = updated_stats.used_percent; + disk.free_percent = updated_stats.free_percent; + disk.is_ready = true; } - disks_stats_promises[mountpoint] = async(std::launch::async, [mountpoint, &free_priv](disk_info disk) -> pair { + disks_stats_promises[mountpoint] = async(std::launch::async, [mountpoint, &free_priv]() -> pair { struct statvfs vfs; + disk_info disk; if (statvfs(mountpoint.c_str(), &vfs) < 0) { return pair{disk, errno}; } @@ -1118,7 +1125,7 @@ namespace Mem { disk.used_percent = round((double)disk.used * 100 / disk.total); disk.free_percent = 100 - disk.used_percent; return pair{disk, -1}; - }, disk); + }); ++it; } @@ -1149,6 +1156,7 @@ namespace Mem { int64_t sectors_read, sectors_write, io_ticks, io_ticks_temp; disk_ios = 0; for (auto& [ignored, disk] : disks) { + if(!disk.is_ready) continue; if (disk.stat.empty() or access(disk.stat.c_str(), R_OK) != 0) continue; if (disk.fstype == "zfs" && zfs_hide_datasets && zfs_collect_pool_total_stats(disk)) { disk_ios++; From cdcf8bc92978c826d9c1768b547df3b7484003f2 Mon Sep 17 00:00:00 2001 From: crestfalln Date: Fri, 29 Sep 2023 09:07:27 +0530 Subject: [PATCH 3/3] fixed bug where updated disks stats overrided disk io data --- src/btop_shared.hpp | 1 - src/linux/btop_collect.cpp | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/btop_shared.hpp b/src/btop_shared.hpp index 6f0dee5..ecf97f2 100644 --- a/src/btop_shared.hpp +++ b/src/btop_shared.hpp @@ -147,7 +147,6 @@ namespace Mem { int64_t free{}; // defaults to 0 int used_percent{}; // defaults to 0 int free_percent{}; // defaults to 0 - bool is_ready = false; array old_io = {0, 0, 0}; deque io_read = {}; diff --git a/src/linux/btop_collect.cpp b/src/linux/btop_collect.cpp index 1d449f5..b5b1cea 100644 --- a/src/linux/btop_collect.cpp +++ b/src/linux/btop_collect.cpp @@ -1111,7 +1111,6 @@ namespace Mem { disk.used = updated_stats.used; disk.used_percent = updated_stats.used_percent; disk.free_percent = updated_stats.free_percent; - disk.is_ready = true; } disks_stats_promises[mountpoint] = async(std::launch::async, [mountpoint, &free_priv]() -> pair { struct statvfs vfs; @@ -1156,7 +1155,6 @@ namespace Mem { int64_t sectors_read, sectors_write, io_ticks, io_ticks_temp; disk_ios = 0; for (auto& [ignored, disk] : disks) { - if(!disk.is_ready) continue; if (disk.stat.empty() or access(disk.stat.c_str(), R_OK) != 0) continue; if (disk.fstype == "zfs" && zfs_hide_datasets && zfs_collect_pool_total_stats(disk)) { disk_ios++;