From 0a54596bc63cf53a861a6b53a0e99f52e44a7c86 Mon Sep 17 00:00:00 2001 From: Kondo Takeo Date: Tue, 16 Feb 2021 22:42:47 +0900 Subject: [PATCH] Issue: #96 - Garbage collect inodeproc on each ui refresh. --- src/inode2prog.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++++++ src/inode2prog.h | 2 ++ src/main.cpp | 1 + src/process.cpp | 2 ++ src/process.h | 2 ++ 5 files changed, 76 insertions(+) diff --git a/src/inode2prog.cpp b/src/inode2prog.cpp index dec0568..2fc473c 100644 --- a/src/inode2prog.cpp +++ b/src/inode2prog.cpp @@ -20,6 +20,7 @@ * */ +#include #include #include #include @@ -30,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -224,6 +226,73 @@ void get_info_for_pid(const char *pid) { closedir(dir); } +static quad_t get_ms() { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return static_cast(ts.tv_sec) * 1000 + ts.tv_nsec / 1000000; +} + +static void get_pids(std::set *pids) { + DIR *proc = opendir("/proc"); + if (proc == 0) { + std::cerr << "Error reading /proc, needed to get inode-to-pid-maping\n"; + exit(1); + } + dirent *entry; + + while ((entry = readdir(proc))) { + if (entry->d_type != DT_DIR) + continue; + + if (!is_number(entry->d_name)) + continue; + + pids->insert(str2int(entry->d_name)); + } + closedir(proc); +} + +void garbage_collect_inodeproc() { + static quad_t last_ms = 0; + quad_t start_ms = 0; + if (bughuntmode) { + start_ms = get_ms(); + if (last_ms) { + std::cout << "PERF: GC interval: " << start_ms - last_ms << "[ms]" + << std::endl; + } + } + + std::set pids; + get_pids(&pids); + if (pids.size() == 0) { + return; + } + + for (std::map::iterator it = inodeproc.begin(); + it != inodeproc.end();) { + if (!it->second || pids.find(it->second->pid) != pids.end()) { + ++it; + continue; + } + + if (bughuntmode) { + std::cout << "GC prg_node (inode=" << it->first + << ", pid=" << it->second->pid + << ", cmdline=" << it->second->cmdline.c_str() << ")" + << std::endl; + } + delete it->second; + inodeproc.erase(it++); + } + + if (bughuntmode) { + last_ms = get_ms(); + std::cout << "PERF: GC proctime: " << last_ms - start_ms << "[ms]" + << std::endl; + } +} + /* updates the `inodeproc' inode-to-prg_node mapping * for all processes in /proc */ void reread_mapping() { diff --git a/src/inode2prog.h b/src/inode2prog.h index c9b0244..d79fd5f 100644 --- a/src/inode2prog.h +++ b/src/inode2prog.h @@ -41,4 +41,6 @@ void prg_cache_clear(); // reread the inode-to-prg_node-mapping void reread_mapping(); +void garbage_collect_inodeproc(); + #endif diff --git a/src/main.cpp b/src/main.cpp index f81819e..d32b8d8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -322,6 +322,7 @@ int main(int argc, char **argv) { ui_tick(); } do_refresh(); + garbage_collect_processes(); } // if not packets, do a select() until next packet diff --git a/src/process.cpp b/src/process.cpp index 6e2b324..0c8f03e 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -424,3 +424,5 @@ void remove_timed_out_processes() { previousproc = curproc; } } + +void garbage_collect_processes() { garbage_collect_inodeproc(); } diff --git a/src/process.h b/src/process.h index 8aa7710..577146e 100644 --- a/src/process.h +++ b/src/process.h @@ -145,4 +145,6 @@ void procclean(); void remove_timed_out_processes(); +void garbage_collect_processes(); + #endif