From 9667fe65b45b6cdf3f645ebfc45e7d458ed3232c Mon Sep 17 00:00:00 2001 From: aristocratos Date: Sun, 6 Jun 2021 22:49:24 +0200 Subject: [PATCH] Change Proc::collect to return a reference to Proc::current_procs instead of a new vector --- btop.cpp | 6 ------ src/btop_config.h | 18 +++++++++--------- src/btop_linux.h | 43 +++++++++++++++++++++---------------------- src/btop_tools.h | 2 +- 4 files changed, 31 insertions(+), 38 deletions(-) diff --git a/btop.cpp b/btop.cpp index 20c62c5..2430645 100644 --- a/btop.cpp +++ b/btop.cpp @@ -332,12 +332,6 @@ int main(int argc, char **argv){ exit(0); } - if (false) { - string a = "⣿ ⣿\n⣿⣿⣿⣿ ⣿\n⣿⣿⣿⣿ ⣿\n⣿⣿⣿⣿ ⣿\n⣿⣿⣿"; - cout << a << endl; - exit(0); - } - if (false) { vector mydata; diff --git a/src/btop_config.h b/src/btop_config.h index e1463b0..54c6eeb 100644 --- a/src/btop_config.h +++ b/src/btop_config.h @@ -126,19 +126,19 @@ namespace Config { //* Set config value to bool void set(string name, bool value){ - if (_locked()) boolsTmp[name] = value; + if (_locked()) boolsTmp.insert_or_assign(name, value); else bools.at(name) = value; } //* Set config value to int void set(string name, int value){ - if (_locked()) intsTmp[name] = value; + if (_locked()) intsTmp.insert_or_assign(name, value); ints.at(name) = value; } //* Set config value to string void set(string name, string value){ - if (_locked()) stringsTmp[name] = value; + if (_locked()) stringsTmp.insert_or_assign(name, value); else strings.at(name) = value; } @@ -146,36 +146,36 @@ namespace Config { void flip(string name){ if (_locked()) { if (boolsTmp.contains(name)) boolsTmp.at(name) = !boolsTmp.at(name); - else boolsTmp[name] = !bools.at(name); + else boolsTmp.insert_or_assign(name, (!bools.at(name))); } else bools.at(name) = !bools.at(name); } //* Wait if locked then lock config and cache changes until unlock void lock(){ - atomic_wait_set(locked, true); + atomic_wait_set(locked); } //* Unlock config and write any cached values to config void unlock(){ - atomic_wait_set(writelock, true); + atomic_wait_set(writelock); if (stringsTmp.size() > 0) { for (auto& item : stringsTmp){ strings.at(item.first) = item.second; } - stringsTmp.clear(); stringsTmp.compact(); + stringsTmp.clear(); } if (intsTmp.size() > 0) { for (auto& item : intsTmp){ ints.at(item.first) = item.second; } - intsTmp.clear(); intsTmp.compact(); + intsTmp.clear(); } if (boolsTmp.size() > 0) { for (auto& item : boolsTmp){ bools.at(item.first) = item.second; } - boolsTmp.clear(); boolsTmp.compact(); + boolsTmp.clear(); } writelock.store(false); locked.store(false); diff --git a/src/btop_linux.h b/src/btop_linux.h index d1ce554..cbd3f1f 100644 --- a/src/btop_linux.h +++ b/src/btop_linux.h @@ -60,7 +60,6 @@ namespace Tools { namespace Proc { namespace { - uint64_t tstamp; struct p_cache { string name, cmd, user; uint64_t cpu_t = 0, cpu_s = 0; @@ -79,7 +78,8 @@ namespace Proc { uint64_t old_cputimes = 0; size_t numpids = 500; atomic stop (false); - atomic running (false); + atomic collecting (false); + atomic drawing (false); array sort_array = { "pid", "name", @@ -90,7 +90,7 @@ namespace Proc { "cpu direct", "cpu lazy", }; - unordered_flat_map sort_map; + unordered_flat_map sort_map; //* proc_info: pid, name, cmd, threads, user, mem, cpu_p, cpu_c, state, cpu_n, p_nice, ppid struct proc_info { @@ -105,16 +105,17 @@ namespace Proc { uint ppid = 0; }; + vector current_procs; - //* Collects process information from /proc and returns a vector of proc_info structs - auto collect(string sorting="pid", bool reverse=false, string filter="", bool per_core=true){ - running.store(true); + + //* Collects process information from /proc, saves to and returns reference to Proc::current_procs; + auto& collect(string sorting="pid", bool reverse=false, string filter="", bool per_core=true){ + atomic_wait_set(collecting); ifstream pread; auto uptime = system_uptime(); - auto sortint = (sort_map.contains(sorting)) ? sort_map[sorting] : 7; vector procs; procs.reserve((numpids + 10)); - numpids = 0; + int npids = 0; int cmult = (per_core) ? Global::coreCount : 1; //* Update uid_user map if /etc/passwd changed since last run @@ -143,22 +144,21 @@ namespace Proc { for (uint64_t times; pread >> times; cputimes += times); pread.close(); } - else return procs; + else return current_procs; //* Iterate over all pids in /proc for (auto& d: fs::directory_iterator(proc_path)){ if (pread.is_open()) pread.close(); if (stop.load()) { - procs.clear(); - running.store(false); + collecting.store(false); stop.store(false); - return procs; + return current_procs; } string pid_str = d.path().filename(); bool new_cache = false; if (d.is_directory() && isdigit(pid_str[0])) { - numpids++; + npids++; proc_info new_proc (stoul(pid_str)); //* Cache program name, command and username @@ -298,7 +298,7 @@ namespace Proc { //* Sort processes vector - std::ranges::sort(procs, [&sortint, &reverse](proc_info& a, proc_info& b) { + std::ranges::sort(procs, [sortint = sort_map.at(sorting), &reverse](proc_info& a, proc_info& b) { switch (sortint) { case 0: return (reverse) ? a.pid < b.pid : a.pid > b.pid; case 1: return (reverse) ? a.name < b.name : a.name > b.name; @@ -314,7 +314,7 @@ namespace Proc { ); //* When using "cpu lazy" sorting push processes with high cpu usage to the front regardless of cumulative usage - if (sortint == 7 && !reverse) { + if (sort_map.at(sorting) == 7 && !reverse) { double max = 10.0, target = 30.0; for (size_t i = 0, offset = 0; i < procs.size(); i++) { if (i <= 5 && procs[i].cpu_p > max) max = procs[i].cpu_p; @@ -325,11 +325,10 @@ namespace Proc { } //* Clear dead processes from cache at a regular interval - if (++counter >= 10000 || (filter.empty() && cache.size() > procs.size() + 100)) { + if (++counter >= 10000 || ((int)cache.size() > npids + 100)) { unordered_flat_map r_cache; r_cache.reserve(procs.size()); counter = 0; - Logger::debug("Cleared proc cache"); if (filter.empty()) { for (auto& p : procs) r_cache[p.pid] = cache[p.pid]; cache.swap(r_cache); @@ -337,15 +336,15 @@ namespace Proc { else cache.clear(); } old_cputimes = cputimes; - tstamp = time_ms(); - running.store(false); - return procs; + atomic_wait(drawing); + current_procs.swap(procs); + numpids = npids; + collecting.store(false); + return current_procs; } //* Initialize needed variables for collect void init(){ - tstamp = time_ms(); - proc_path = (fs::is_directory(fs::path("/proc")) && access("/proc", R_OK) != -1) ? "/proc" : ""; if (proc_path.empty()) { string errmsg = "Proc filesystem not found or no permission to read from it!"; diff --git a/src/btop_tools.h b/src/btop_tools.h index ad6abe9..71a83d0 100644 --- a/src/btop_tools.h +++ b/src/btop_tools.h @@ -441,7 +441,7 @@ namespace Tools { #endif //* Waits for to not be and then sets it to again - void atomic_wait_set(atomic& atom, bool val){ + void atomic_wait_set(atomic& atom, bool val=true){ atomic_wait(atom, val); atom.store(val); }