diff --git a/ChangeLog b/ChangeLog index c6623763..2ddc2b36 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,8 @@ What's new in version 1.0.3 * Performance improvements (thanks to Jann Horn) +* Further performance improvements due to conditional parsing + of IO data depending on selected fields. What's new in version 1.0.2 diff --git a/ColumnsPanel.c b/ColumnsPanel.c index 639d5e6d..f4eed99e 100644 --- a/ColumnsPanel.c +++ b/ColumnsPanel.c @@ -122,11 +122,14 @@ void ColumnsPanel_update(Panel* super) { // FIXME: this is crappily inefficient free(this->settings->pl->fields); this->settings->pl->fields = (ProcessField*) malloc(sizeof(ProcessField) * (size+1)); + this->settings->pl->flags = 0; for (int i = 0; i < size; i++) { char* text = ((ListItem*) Panel_get(super, i))->value; int j = ColumnsPanel_fieldNameToIndex(text); - if (j > 0) + if (j > 0) { this->settings->pl->fields[i] = j; + this->settings->pl->flags |= Process_fieldFlags[j]; + } } this->settings->pl->fields[size] = 0; } diff --git a/Process.c b/Process.c index af56b704..6765be7a 100644 --- a/Process.c +++ b/Process.c @@ -45,6 +45,12 @@ in the source distribution for its full text. #include "IOPriority.h" #include +#define PROCESS_FLAG_IO 1 +#define PROCESS_FLAG_IOPRIO 2 +#define PROCESS_FLAG_OPENVZ 4 +#define PROCESS_FLAG_VSERVER 8 +#define PROCESS_FLAG_CGROUP 16 + #ifndef Process_isKernelThread #define Process_isKernelThread(_process) (_process->pgrp == 0) #endif @@ -201,6 +207,31 @@ const char *Process_fieldNames[] = { "*** report bug! ***" }; +const int Process_fieldFlags[] = { + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, +#ifdef HAVE_OPENVZ + PROCESS_FLAG_OPENVZ, PROCESS_FLAG_OPENVZ, +#endif +#ifdef HAVE_VSERVER + PROCESS_FLAG_VSERVER, +#endif +#ifdef HAVE_TASKSTATS + PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, + PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, +#endif +#ifdef HAVE_CGROUP + PROCESS_FLAG_CGROUP, +#endif + PROCESS_FLAG_IOPRIO +}; + const char *Process_fieldTitles[] = { "", " PID ", "Command ", "S ", " PPID ", " PGRP ", " SESN ", " TTY ", " TPGID ", "- ", "- ", "- ", "- ", "- ", diff --git a/Process.h b/Process.h index c875d86e..a24c7c04 100644 --- a/Process.h +++ b/Process.h @@ -24,6 +24,12 @@ in the source distribution for its full text. #include "IOPriority.h" #include +#define PROCESS_FLAG_IO 1 +#define PROCESS_FLAG_IOPRIO 2 +#define PROCESS_FLAG_OPENVZ 4 +#define PROCESS_FLAG_VSERVER 8 +#define PROCESS_FLAG_CGROUP 16 + #ifndef Process_isKernelThread #define Process_isKernelThread(_process) (_process->pgrp == 0) #endif @@ -155,6 +161,8 @@ typedef struct Process_ { extern const char *Process_fieldNames[]; +extern const int Process_fieldFlags[]; + extern const char *Process_fieldTitles[]; diff --git a/ProcessList.c b/ProcessList.c index ca96b883..ce1319a3 100644 --- a/ProcessList.c +++ b/ProcessList.c @@ -133,6 +133,7 @@ typedef struct ProcessList_ { unsigned long long int usedSwap; unsigned long long int freeSwap; + int flags; ProcessField* fields; ProcessField sortKey; int direction; @@ -235,8 +236,10 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList) { this->fields = calloc(sizeof(ProcessField), LAST_PROCESSFIELD+1); // TODO: turn 'fields' into a Vector, // (and ProcessFields into proper objects). + this->flags = 0; for (int i = 0; defaultHeaders[i]; i++) { this->fields[i] = defaultHeaders[i]; + this->fields[i] |= Process_fieldFlags[defaultHeaders[i]]; } this->sortKey = PERCENT_CPU; this->direction = 1; @@ -738,7 +741,8 @@ static bool ProcessList_processEntries(ProcessList* this, const char* dirname, P ProcessList_processEntries(this, subdirname, process, period, tv); #ifdef HAVE_TASKSTATS - ProcessList_readIoFile(process, dirname, name, now); + if (this->flags & PROCESS_FLAG_IO) + ProcessList_readIoFile(process, dirname, name, now); #endif if (! ProcessList_readStatmFile(process, dirname, name)) @@ -750,7 +754,8 @@ static bool ProcessList_processEntries(ProcessList* this, const char* dirname, P unsigned long long int lasttimes = (process->utime + process->stime); if (! ProcessList_readStatFile(process, dirname, name, command)) goto errorReadingProcess; - Process_updateIOPriority(process); + if (this->flags & PROCESS_FLAG_IOPRIO) + Process_updateIOPriority(process); float percent_cpu = (process->utime + process->stime - lasttimes) / period * 100.0; process->percent_cpu = MAX(MIN(percent_cpu, cpus*100.0), 0.0); if (isnan(process->percent_cpu)) process->percent_cpu = 0.0; @@ -764,15 +769,18 @@ static bool ProcessList_processEntries(ProcessList* this, const char* dirname, P process->user = UsersTable_getRef(this->usersTable, process->st_uid); #ifdef HAVE_OPENVZ - ProcessList_readOpenVZData(process, dirname, name); + if (this->flags & PROCESS_FLAG_OPENVZ) + ProcessList_readOpenVZData(process, dirname, name); #endif #ifdef HAVE_CGROUP - ProcessList_readCGroupFile(process, dirname, name); + if (this->flags & PROCESS_FLAG_CGROUP) + ProcessList_readCGroupFile(process, dirname, name); #endif #ifdef HAVE_VSERVER - ProcessList_readVServerData(process, dirname, name); + if (this->flags & PROCESS_FLAG_VSERVER) + ProcessList_readVServerData(process, dirname, name); #endif if (! ProcessList_readCmdlineFile(process, dirname, name)) diff --git a/ProcessList.h b/ProcessList.h index 95d32b7c..af202c87 100644 --- a/ProcessList.h +++ b/ProcessList.h @@ -113,6 +113,7 @@ typedef struct ProcessList_ { unsigned long long int usedSwap; unsigned long long int freeSwap; + int flags; ProcessField* fields; ProcessField sortKey; int direction; diff --git a/Settings.c b/Settings.c index fd200a7c..46b3a971 100644 --- a/Settings.c +++ b/Settings.c @@ -82,11 +82,13 @@ static bool Settings_read(Settings* this, char* fileName, int cpuCount) { char** ids = String_split(trim, ' ', &nIds); free(trim); int i, j; + this->pl->flags = 0; for (j = 0, i = 0; i < LAST_PROCESSFIELD && ids[i]; i++) { // This "+1" is for compatibility with the older enum format. int id = atoi(ids[i]) + 1; if (id > 0 && id < LAST_PROCESSFIELD) { this->pl->fields[j] = id; + this->pl->flags |= Process_fieldFlags[id]; j++; } }