Change Proc::collect to return a reference to Proc::current_procs instead of a new vector

This commit is contained in:
aristocratos 2021-06-06 22:49:24 +02:00
parent deec8f20e0
commit 9667fe65b4
4 changed files with 31 additions and 38 deletions

View file

@ -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<long long> mydata;

View file

@ -126,19 +126,19 @@ namespace Config {
//* Set config value <name> to bool <value>
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 <name> to int <value>
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 <name> to string <value>
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);

View file

@ -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<bool> stop (false);
atomic<bool> running (false);
atomic<bool> collecting (false);
atomic<bool> drawing (false);
array<string, 8> sort_array = {
"pid",
"name",
@ -90,7 +90,7 @@ namespace Proc {
"cpu direct",
"cpu lazy",
};
unordered_flat_map<string, uint> sort_map;
unordered_flat_map<string, int> 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<proc_info> 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<proc_info> 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<uint, p_cache> 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!";

View file

@ -441,7 +441,7 @@ namespace Tools {
#endif
//* Waits for <atom> to not be <val> and then sets it to <val> again
void atomic_wait_set(atomic<bool>& atom, bool val){
void atomic_wait_set(atomic<bool>& atom, bool val=true){
atomic_wait(atom, val);
atom.store(val);
}