diff options
author | Alexander Schlarb <alexander@ninetailed.ninja> | 2018-10-16 20:08:23 +0200 |
---|---|---|
committer | Alexander Schlarb <alexander@ninetailed.ninja> | 2019-03-20 17:00:49 +0100 |
commit | 078c2ddde5a64a8a9b3bcf40d62e1f81477db029 (patch) | |
tree | bc5e6472b98b5eba4a281dccaf86b254dbffeeb6 /linux | |
parent | fc0bf546c3ceb03fedb08253756cae63d15499b5 (diff) |
Linux: Use /proc/*/smaps_rollup for improved PSS parsing speed
Diffstat (limited to 'linux')
-rw-r--r-- | linux/LinuxProcessList.c | 20 | ||||
-rw-r--r-- | linux/LinuxProcessList.h | 1 |
2 files changed, 18 insertions, 3 deletions
diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index a02da072..c1ccd420 100644 --- a/linux/LinuxProcessList.c +++ b/linux/LinuxProcessList.c @@ -89,6 +89,7 @@ typedef struct LinuxProcessList_ { CPUData* cpus; TtyDriver* ttyDrivers; + bool haveSmapsRollup; #ifdef HAVE_DELAYACCT struct nl_sock *netlink_socket; @@ -240,8 +241,17 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, ui LinuxProcessList_initNetlinkSocket(this); #endif + // Check for /proc/*/smaps_rollup availability (improves smaps parsing speed, Linux 4.14+) + FILE* file = fopen(PROCDIR "/self/smaps_rollup", "r"); + if(file != NULL) { + this->haveSmapsRollup = true; + fclose(file); + } else { + this->haveSmapsRollup = false; + } + // Update CPU count: - FILE* file = fopen(PROCSTATFILE, "r"); + file = fopen(PROCSTATFILE, "r"); if (file == NULL) { CRT_fatalError("Cannot open " PROCSTATFILE); } @@ -486,7 +496,7 @@ static bool LinuxProcessList_readStatmFile(LinuxProcess* process, const char* di return (errno == 0); } -static bool LinuxProcessList_readSmapsFile(LinuxProcess* process, const char* dirname, const char* name) { +static bool LinuxProcessList_readSmapsFile(LinuxProcess* process, const char* dirname, const char* name, bool haveSmapsRollup) { //http://elixir.free-electrons.com/linux/v4.10/source/fs/proc/task_mmu.c#L719 //kernel will return data in chunks of size PAGE_SIZE or less. @@ -494,7 +504,11 @@ static bool LinuxProcessList_readSmapsFile(LinuxProcess* process, const char* di char *start,*end; ssize_t nread=0; int tmp=0; + if(haveSmapsRollup) {// only available in Linux 4.14+ + snprintf(buffer, MAX_NAME, "%s/%s/smaps_rollup", dirname, name); + } else { snprintf(buffer, MAX_NAME, "%s/%s/smaps", dirname, name); + } int fd = open(buffer, O_RDONLY); if (fd == -1) return false; @@ -872,7 +886,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char* // Read smaps file of each process only every second pass to improve performance static int smaps_flag = 0; if ((pid & 1) == smaps_flag){ - LinuxProcessList_readSmapsFile(lp, dirname, name); + LinuxProcessList_readSmapsFile(lp, dirname, name, this->haveSmapsRollup); } if (pid == 1) { smaps_flag = !smaps_flag; diff --git a/linux/LinuxProcessList.h b/linux/LinuxProcessList.h index f30b487d..59e83bcb 100644 --- a/linux/LinuxProcessList.h +++ b/linux/LinuxProcessList.h @@ -62,6 +62,7 @@ typedef struct LinuxProcessList_ { CPUData* cpus; TtyDriver* ttyDrivers; + bool haveSmapsRollup; #ifdef HAVE_DELAYACCT struct nl_sock *netlink_socket; |