mirror of https://github.com/xzeldon/htop.git
BUGFIX: Fix display of CPU count for threaded processes.
When user threads are hidden, process now shows the sum of processor usage for all processors. When user threads are displayed, each thread shows its own processor usage, including the root thread. (thanks to Bert Wesarg for the report) Also, add option to display thread colors differently.
This commit is contained in:
parent
52840406ac
commit
93f091c47e
24
CRT.c
24
CRT.c
|
@ -68,6 +68,8 @@ typedef enum ColorElements_ {
|
||||||
PROCESS_BASENAME,
|
PROCESS_BASENAME,
|
||||||
PROCESS_HIGH_PRIORITY,
|
PROCESS_HIGH_PRIORITY,
|
||||||
PROCESS_LOW_PRIORITY,
|
PROCESS_LOW_PRIORITY,
|
||||||
|
PROCESS_THREAD,
|
||||||
|
PROCESS_THREAD_BASENAME,
|
||||||
BAR_BORDER,
|
BAR_BORDER,
|
||||||
BAR_SHADOW,
|
BAR_SHADOW,
|
||||||
GRAPH_1,
|
GRAPH_1,
|
||||||
|
@ -210,8 +212,8 @@ void CRT_setColors(int colorScheme) {
|
||||||
CRT_colors[FUNCTION_KEY] = A_NORMAL;
|
CRT_colors[FUNCTION_KEY] = A_NORMAL;
|
||||||
CRT_colors[PANEL_HEADER_FOCUS] = A_REVERSE;
|
CRT_colors[PANEL_HEADER_FOCUS] = A_REVERSE;
|
||||||
CRT_colors[PANEL_HEADER_UNFOCUS] = A_REVERSE;
|
CRT_colors[PANEL_HEADER_UNFOCUS] = A_REVERSE;
|
||||||
CRT_colors[PANEL_HIGHLIGHT_FOCUS] = A_REVERSE | A_BOLD;
|
CRT_colors[PANEL_HIGHLIGHT_FOCUS] = A_REVERSE;
|
||||||
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = A_REVERSE;
|
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = A_BOLD;
|
||||||
CRT_colors[FAILED_SEARCH] = A_REVERSE | A_BOLD;
|
CRT_colors[FAILED_SEARCH] = A_REVERSE | A_BOLD;
|
||||||
CRT_colors[UPTIME] = A_BOLD;
|
CRT_colors[UPTIME] = A_BOLD;
|
||||||
CRT_colors[LARGE_NUMBER] = A_BOLD;
|
CRT_colors[LARGE_NUMBER] = A_BOLD;
|
||||||
|
@ -228,6 +230,8 @@ void CRT_setColors(int colorScheme) {
|
||||||
CRT_colors[PROCESS_R_STATE] = A_BOLD;
|
CRT_colors[PROCESS_R_STATE] = A_BOLD;
|
||||||
CRT_colors[PROCESS_HIGH_PRIORITY] = A_BOLD;
|
CRT_colors[PROCESS_HIGH_PRIORITY] = A_BOLD;
|
||||||
CRT_colors[PROCESS_LOW_PRIORITY] = A_DIM;
|
CRT_colors[PROCESS_LOW_PRIORITY] = A_DIM;
|
||||||
|
CRT_colors[PROCESS_THREAD] = A_BOLD;
|
||||||
|
CRT_colors[PROCESS_THREAD_BASENAME] = A_REVERSE;
|
||||||
CRT_colors[BAR_BORDER] = A_BOLD;
|
CRT_colors[BAR_BORDER] = A_BOLD;
|
||||||
CRT_colors[BAR_SHADOW] = A_DIM;
|
CRT_colors[BAR_SHADOW] = A_DIM;
|
||||||
CRT_colors[SWAP] = A_BOLD;
|
CRT_colors[SWAP] = A_BOLD;
|
||||||
|
@ -278,11 +282,13 @@ void CRT_setColors(int colorScheme) {
|
||||||
CRT_colors[PROCESS_SHADOW] = A_BOLD | ColorPair(Black,White);
|
CRT_colors[PROCESS_SHADOW] = A_BOLD | ColorPair(Black,White);
|
||||||
CRT_colors[PROCESS_TAG] = ColorPair(White,Blue);
|
CRT_colors[PROCESS_TAG] = ColorPair(White,Blue);
|
||||||
CRT_colors[PROCESS_MEGABYTES] = ColorPair(Blue,White);
|
CRT_colors[PROCESS_MEGABYTES] = ColorPair(Blue,White);
|
||||||
CRT_colors[PROCESS_BASENAME] = ColorPair(Green,White);
|
CRT_colors[PROCESS_BASENAME] = ColorPair(Blue,White);
|
||||||
CRT_colors[PROCESS_TREE] = ColorPair(Blue,White);
|
CRT_colors[PROCESS_TREE] = ColorPair(Green,White);
|
||||||
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,White);
|
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,White);
|
||||||
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,White);
|
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,White);
|
||||||
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,White);
|
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,White);
|
||||||
|
CRT_colors[PROCESS_THREAD] = ColorPair(Blue,White);
|
||||||
|
CRT_colors[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Blue,White);
|
||||||
CRT_colors[BAR_BORDER] = ColorPair(Blue,White);
|
CRT_colors[BAR_BORDER] = ColorPair(Blue,White);
|
||||||
CRT_colors[BAR_SHADOW] = ColorPair(Black,White);
|
CRT_colors[BAR_SHADOW] = ColorPair(Black,White);
|
||||||
CRT_colors[SWAP] = ColorPair(Red,White);
|
CRT_colors[SWAP] = ColorPair(Red,White);
|
||||||
|
@ -338,6 +344,8 @@ void CRT_setColors(int colorScheme) {
|
||||||
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Black);
|
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Black);
|
||||||
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Black);
|
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Black);
|
||||||
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Black);
|
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Black);
|
||||||
|
CRT_colors[PROCESS_THREAD] = ColorPair(Blue,Black);
|
||||||
|
CRT_colors[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Blue,Black);
|
||||||
CRT_colors[BAR_BORDER] = ColorPair(Blue,Black);
|
CRT_colors[BAR_BORDER] = ColorPair(Blue,Black);
|
||||||
CRT_colors[BAR_SHADOW] = ColorPair(Black,Black);
|
CRT_colors[BAR_SHADOW] = ColorPair(Black,Black);
|
||||||
CRT_colors[SWAP] = ColorPair(Red,Black);
|
CRT_colors[SWAP] = ColorPair(Red,Black);
|
||||||
|
@ -393,6 +401,8 @@ void CRT_setColors(int colorScheme) {
|
||||||
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Blue);
|
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Blue);
|
||||||
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Blue);
|
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Blue);
|
||||||
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Blue);
|
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Blue);
|
||||||
|
CRT_colors[PROCESS_THREAD] = ColorPair(Green,Blue);
|
||||||
|
CRT_colors[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Green,Blue);
|
||||||
CRT_colors[BAR_BORDER] = A_BOLD | ColorPair(Yellow,Blue);
|
CRT_colors[BAR_BORDER] = A_BOLD | ColorPair(Yellow,Blue);
|
||||||
CRT_colors[BAR_SHADOW] = ColorPair(Cyan,Blue);
|
CRT_colors[BAR_SHADOW] = ColorPair(Cyan,Blue);
|
||||||
CRT_colors[SWAP] = ColorPair(Red,Blue);
|
CRT_colors[SWAP] = ColorPair(Red,Blue);
|
||||||
|
@ -445,6 +455,8 @@ void CRT_setColors(int colorScheme) {
|
||||||
CRT_colors[PROCESS_MEGABYTES] = A_BOLD | ColorPair(Green,Black);
|
CRT_colors[PROCESS_MEGABYTES] = A_BOLD | ColorPair(Green,Black);
|
||||||
CRT_colors[PROCESS_BASENAME] = A_BOLD | ColorPair(Green,Black);
|
CRT_colors[PROCESS_BASENAME] = A_BOLD | ColorPair(Green,Black);
|
||||||
CRT_colors[PROCESS_TREE] = ColorPair(Cyan,Black);
|
CRT_colors[PROCESS_TREE] = ColorPair(Cyan,Black);
|
||||||
|
CRT_colors[PROCESS_THREAD] = ColorPair(Green,Black);
|
||||||
|
CRT_colors[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Blue,Black);
|
||||||
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Black);
|
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Black);
|
||||||
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Black);
|
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Black);
|
||||||
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Black);
|
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Black);
|
||||||
|
@ -471,7 +483,7 @@ void CRT_setColors(int colorScheme) {
|
||||||
CRT_colors[CPU_NICE] = ColorPair(Blue,Black);
|
CRT_colors[CPU_NICE] = ColorPair(Blue,Black);
|
||||||
CRT_colors[CPU_NORMAL] = ColorPair(Green,Black);
|
CRT_colors[CPU_NORMAL] = ColorPair(Green,Black);
|
||||||
CRT_colors[CPU_KERNEL] = ColorPair(Red,Black);
|
CRT_colors[CPU_KERNEL] = ColorPair(Red,Black);
|
||||||
CRT_colors[CLOCK] = A_BOLD;
|
CRT_colors[CLOCK] = ColorPair(Green,Black);
|
||||||
CRT_colors[CHECK_BOX] = ColorPair(Green,Black);
|
CRT_colors[CHECK_BOX] = ColorPair(Green,Black);
|
||||||
CRT_colors[CHECK_MARK] = A_BOLD | ColorPair(Green,Black);
|
CRT_colors[CHECK_MARK] = A_BOLD | ColorPair(Green,Black);
|
||||||
CRT_colors[CHECK_TEXT] = ColorPair(Cyan,Black);
|
CRT_colors[CHECK_TEXT] = ColorPair(Cyan,Black);
|
||||||
|
@ -504,6 +516,8 @@ void CRT_setColors(int colorScheme) {
|
||||||
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Black);
|
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Black);
|
||||||
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Black);
|
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Black);
|
||||||
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Black);
|
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Black);
|
||||||
|
CRT_colors[PROCESS_THREAD] = ColorPair(Green,Black);
|
||||||
|
CRT_colors[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Green,Black);
|
||||||
CRT_colors[BAR_BORDER] = A_BOLD;
|
CRT_colors[BAR_BORDER] = A_BOLD;
|
||||||
CRT_colors[BAR_SHADOW] = A_BOLD | ColorPair(Black,Black);
|
CRT_colors[BAR_SHADOW] = A_BOLD | ColorPair(Black,Black);
|
||||||
CRT_colors[SWAP] = ColorPair(Red,Black);
|
CRT_colors[SWAP] = ColorPair(Red,Black);
|
||||||
|
|
2
CRT.h
2
CRT.h
|
@ -70,6 +70,8 @@ typedef enum ColorElements_ {
|
||||||
PROCESS_BASENAME,
|
PROCESS_BASENAME,
|
||||||
PROCESS_HIGH_PRIORITY,
|
PROCESS_HIGH_PRIORITY,
|
||||||
PROCESS_LOW_PRIORITY,
|
PROCESS_LOW_PRIORITY,
|
||||||
|
PROCESS_THREAD,
|
||||||
|
PROCESS_THREAD_BASENAME,
|
||||||
BAR_BORDER,
|
BAR_BORDER,
|
||||||
BAR_SHADOW,
|
BAR_SHADOW,
|
||||||
GRAPH_1,
|
GRAPH_1,
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
|
|
||||||
What's new in version 0.7.1
|
What's new in version 0.7.1
|
||||||
|
|
||||||
|
* BUGFIX: Fix display of CPU count for threaded processes.
|
||||||
|
When user threads are hidden, process now shows the
|
||||||
|
sum of processor usage for all processors. When user
|
||||||
|
threads are displayed, each thread shows its own
|
||||||
|
processor usage, including the root thread.
|
||||||
|
(thanks to Bert Wesarg for the report)
|
||||||
* BUGFIX: avoid crashing when using many meters
|
* BUGFIX: avoid crashing when using many meters
|
||||||
(thanks to David Cho for the report)
|
(thanks to David Cho for the report)
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager*
|
||||||
Panel_add(super, (Object*) CheckItem_new(String_copy("Shadow other users' processes"), &(settings->pl->shadowOtherUsers), false));
|
Panel_add(super, (Object*) CheckItem_new(String_copy("Shadow other users' processes"), &(settings->pl->shadowOtherUsers), false));
|
||||||
Panel_add(super, (Object*) CheckItem_new(String_copy("Hide kernel threads"), &(settings->pl->hideKernelThreads), false));
|
Panel_add(super, (Object*) CheckItem_new(String_copy("Hide kernel threads"), &(settings->pl->hideKernelThreads), false));
|
||||||
Panel_add(super, (Object*) CheckItem_new(String_copy("Hide userland threads"), &(settings->pl->hideUserlandThreads), false));
|
Panel_add(super, (Object*) CheckItem_new(String_copy("Hide userland threads"), &(settings->pl->hideUserlandThreads), false));
|
||||||
|
Panel_add(super, (Object*) CheckItem_new(String_copy("Display threads in a different color"), &(settings->pl->highlightThreads), false));
|
||||||
Panel_add(super, (Object*) CheckItem_new(String_copy("Highlight program \"basename\""), &(settings->pl->highlightBaseName), false));
|
Panel_add(super, (Object*) CheckItem_new(String_copy("Highlight program \"basename\""), &(settings->pl->highlightBaseName), false));
|
||||||
Panel_add(super, (Object*) CheckItem_new(String_copy("Highlight megabytes in memory counters"), &(settings->pl->highlightMegabytes), false));
|
Panel_add(super, (Object*) CheckItem_new(String_copy("Highlight megabytes in memory counters"), &(settings->pl->highlightMegabytes), false));
|
||||||
Panel_add(super, (Object*) CheckItem_new(String_copy("Leave a margin around header"), &(settings->header->margin), false));
|
Panel_add(super, (Object*) CheckItem_new(String_copy("Leave a margin around header"), &(settings->header->margin), false));
|
||||||
|
|
21
Process.c
21
Process.c
|
@ -264,7 +264,7 @@ static void Process_printTime(RichString* str, unsigned long t) {
|
||||||
RichString_append(str, CRT_colors[DEFAULT_COLOR], buffer);
|
RichString_append(str, CRT_colors[DEFAULT_COLOR], buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void Process_writeCommand(Process* this, int attr, RichString* str) {
|
static inline void Process_writeCommand(Process* this, int attr, int baseattr, RichString* str) {
|
||||||
if (this->pl->highlightBaseName) {
|
if (this->pl->highlightBaseName) {
|
||||||
char* firstSpace = strchr(this->comm, ' ');
|
char* firstSpace = strchr(this->comm, ' ');
|
||||||
if (firstSpace) {
|
if (firstSpace) {
|
||||||
|
@ -275,10 +275,10 @@ static inline void Process_writeCommand(Process* this, int attr, RichString* str
|
||||||
slash++;
|
slash++;
|
||||||
RichString_appendn(str, attr, this->comm, slash - this->comm);
|
RichString_appendn(str, attr, this->comm, slash - this->comm);
|
||||||
}
|
}
|
||||||
RichString_appendn(str, CRT_colors[PROCESS_BASENAME], slash, firstSpace - slash);
|
RichString_appendn(str, baseattr, slash, firstSpace - slash);
|
||||||
RichString_append(str, attr, firstSpace);
|
RichString_append(str, attr, firstSpace);
|
||||||
} else {
|
} else {
|
||||||
RichString_append(str, CRT_colors[PROCESS_BASENAME], this->comm);
|
RichString_append(str, baseattr, this->comm);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
RichString_append(str, attr, this->comm);
|
RichString_append(str, attr, this->comm);
|
||||||
|
@ -288,6 +288,7 @@ static inline void Process_writeCommand(Process* this, int attr, RichString* str
|
||||||
void Process_writeField(Process* this, RichString* str, ProcessField field) {
|
void Process_writeField(Process* this, RichString* str, ProcessField field) {
|
||||||
char buffer[PROCESS_COMM_LEN];
|
char buffer[PROCESS_COMM_LEN];
|
||||||
int attr = CRT_colors[DEFAULT_COLOR];
|
int attr = CRT_colors[DEFAULT_COLOR];
|
||||||
|
int baseattr = CRT_colors[PROCESS_BASENAME];
|
||||||
int n = PROCESS_COMM_LEN;
|
int n = PROCESS_COMM_LEN;
|
||||||
|
|
||||||
switch (field) {
|
switch (field) {
|
||||||
|
@ -301,8 +302,12 @@ void Process_writeField(Process* this, RichString* str, ProcessField field) {
|
||||||
case PROCESSOR: snprintf(buffer, n, "%3d ", this->processor+1); break;
|
case PROCESSOR: snprintf(buffer, n, "%3d ", this->processor+1); break;
|
||||||
case NLWP: snprintf(buffer, n, "%4ld ", this->nlwp); break;
|
case NLWP: snprintf(buffer, n, "%4ld ", this->nlwp); break;
|
||||||
case COMM: {
|
case COMM: {
|
||||||
|
if (this->pl->highlightThreads && (this->pid != this->tgid || this->m_size == 0)) {
|
||||||
|
attr = CRT_colors[PROCESS_THREAD];
|
||||||
|
baseattr = CRT_colors[PROCESS_THREAD_BASENAME];
|
||||||
|
}
|
||||||
if (!this->pl->treeView || this->indent == 0) {
|
if (!this->pl->treeView || this->indent == 0) {
|
||||||
Process_writeCommand(this, attr, str);
|
Process_writeCommand(this, attr, baseattr, str);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
char* buf = buffer;
|
char* buf = buffer;
|
||||||
|
@ -323,7 +328,7 @@ void Process_writeField(Process* this, RichString* str, ProcessField field) {
|
||||||
else
|
else
|
||||||
snprintf(buf, n, " ,- ");
|
snprintf(buf, n, " ,- ");
|
||||||
RichString_append(str, CRT_colors[PROCESS_TREE], buffer);
|
RichString_append(str, CRT_colors[PROCESS_TREE], buffer);
|
||||||
Process_writeCommand(this, attr, str);
|
Process_writeCommand(this, attr, baseattr, str);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -376,8 +381,10 @@ void Process_writeField(Process* this, RichString* str, ProcessField field) {
|
||||||
case CSTIME: Process_printTime(str, this->cstime); return;
|
case CSTIME: Process_printTime(str, this->cstime); return;
|
||||||
case TIME: Process_printTime(str, this->utime + this->stime); return;
|
case TIME: Process_printTime(str, this->utime + this->stime); return;
|
||||||
case PERCENT_CPU: {
|
case PERCENT_CPU: {
|
||||||
if (this->percent_cpu > 99.9) {
|
if (this->percent_cpu > 999.9) {
|
||||||
snprintf(buffer, n, "100. ");
|
snprintf(buffer, n, "%4d ", (unsigned int)this->percent_cpu);
|
||||||
|
} else if (this->percent_cpu > 99.9) {
|
||||||
|
snprintf(buffer, n, "%3d. ", (unsigned int)this->percent_cpu);
|
||||||
} else {
|
} else {
|
||||||
snprintf(buffer, n, "%4.1f ", this->percent_cpu);
|
snprintf(buffer, n, "%4.1f ", this->percent_cpu);
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,7 @@ typedef struct ProcessList_ {
|
||||||
bool treeView;
|
bool treeView;
|
||||||
bool highlightBaseName;
|
bool highlightBaseName;
|
||||||
bool highlightMegabytes;
|
bool highlightMegabytes;
|
||||||
|
bool highlightThreads;
|
||||||
bool detailedCPUTime;
|
bool detailedCPUTime;
|
||||||
#ifdef DEBUG_PROC
|
#ifdef DEBUG_PROC
|
||||||
FILE* traceFile;
|
FILE* traceFile;
|
||||||
|
@ -498,13 +499,15 @@ bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* dirname,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, float period) {
|
bool ProcessList_processEntries(ProcessList* this, char* dirname, Process* parent, float period) {
|
||||||
DIR* dir;
|
DIR* dir;
|
||||||
struct dirent* entry;
|
struct dirent* entry;
|
||||||
Process* prototype = this->prototype;
|
Process* prototype = this->prototype;
|
||||||
|
|
||||||
dir = opendir(dirname);
|
dir = opendir(dirname);
|
||||||
if (!dir) return;
|
if (!dir) return false;
|
||||||
|
int processors = this->processorCount;
|
||||||
|
bool showUserlandThreads = !this->hideUserlandThreads;
|
||||||
while ((entry = readdir(dir)) != NULL) {
|
while ((entry = readdir(dir)) != NULL) {
|
||||||
char* name = entry->d_name;
|
char* name = entry->d_name;
|
||||||
int pid;
|
int pid;
|
||||||
|
@ -521,34 +524,42 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
|
||||||
isThread = true;
|
isThread = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pid > 0 && pid != parent) {
|
if (pid > 0) {
|
||||||
if (!this->hideUserlandThreads) {
|
|
||||||
char subdirname[MAX_NAME+1];
|
|
||||||
snprintf(subdirname, MAX_NAME, "%s/%s/task", dirname, name);
|
|
||||||
|
|
||||||
ProcessList_processEntries(this, subdirname, pid, period);
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE* status;
|
FILE* status;
|
||||||
char statusfilename[MAX_NAME+1];
|
char statusfilename[MAX_NAME+1];
|
||||||
char command[PROCESS_COMM_LEN + 1];
|
char command[PROCESS_COMM_LEN + 1];
|
||||||
|
|
||||||
Process* process = NULL;
|
Process* process = NULL;
|
||||||
|
|
||||||
assert(Hashtable_count(this->processTable) == Vector_count(this->processes));
|
|
||||||
Process* existingProcess = (Process*) Hashtable_get(this->processTable, pid);
|
Process* existingProcess = (Process*) Hashtable_get(this->processTable, pid);
|
||||||
|
|
||||||
if (existingProcess) {
|
if (existingProcess) {
|
||||||
assert(Vector_indexOf(this->processes, existingProcess, Process_pidCompare) != -1);
|
assert(Vector_indexOf(this->processes, existingProcess, Process_pidCompare) != -1);
|
||||||
process = existingProcess;
|
process = existingProcess;
|
||||||
assert(process->pid == pid);
|
assert(process->pid == pid);
|
||||||
|
} else {
|
||||||
|
if (parent && parent->pid == pid) {
|
||||||
|
process = parent;
|
||||||
} else {
|
} else {
|
||||||
process = prototype;
|
process = prototype;
|
||||||
assert(process->comm == NULL);
|
assert(process->comm == NULL);
|
||||||
process->pid = pid;
|
process->pid = pid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showUserlandThreads && (!parent || pid != parent->pid)) {
|
||||||
|
char subdirname[MAX_NAME+1];
|
||||||
|
snprintf(subdirname, MAX_NAME, "%s/%s/task", dirname, name);
|
||||||
|
|
||||||
|
if (ProcessList_processEntries(this, subdirname, process, period))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
process->updated = true;
|
||||||
|
|
||||||
|
if (!existingProcess)
|
||||||
if (! ProcessList_readStatusFile(this, process, dirname, name))
|
if (! ProcessList_readStatusFile(this, process, dirname, name))
|
||||||
goto errorReadingProcess;
|
goto errorReadingProcess;
|
||||||
}
|
|
||||||
process->updated = true;
|
|
||||||
|
|
||||||
snprintf(statusfilename, MAX_NAME, "%s/%s/statm", dirname, name);
|
snprintf(statusfilename, MAX_NAME, "%s/%s/statm", dirname, name);
|
||||||
status = ProcessList_fopen(this, statusfilename, "r");
|
status = ProcessList_fopen(this, statusfilename, "r");
|
||||||
|
@ -578,8 +589,9 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
|
||||||
|
|
||||||
int success = ProcessList_readStatFile(this, process, status, command);
|
int success = ProcessList_readStatFile(this, process, status, command);
|
||||||
fclose(status);
|
fclose(status);
|
||||||
if(!success)
|
if(!success) {
|
||||||
goto errorReadingProcess;
|
goto errorReadingProcess;
|
||||||
|
}
|
||||||
|
|
||||||
if(!existingProcess) {
|
if(!existingProcess) {
|
||||||
process->user = UsersTable_getRef(this->usersTable, process->st_uid);
|
process->user = UsersTable_getRef(this->usersTable, process->st_uid);
|
||||||
|
@ -624,8 +636,9 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
|
||||||
fclose(status);
|
fclose(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
process->percent_cpu = (process->utime + process->stime - lasttimes) /
|
int percent_cpu = (process->utime + process->stime - lasttimes) /
|
||||||
period * 100.0;
|
period * 100.0;
|
||||||
|
process->percent_cpu = MAX(MIN(percent_cpu, processors*100.0), 0.0);
|
||||||
|
|
||||||
process->percent_mem = (process->m_resident * PAGE_SIZE) /
|
process->percent_mem = (process->m_resident * PAGE_SIZE) /
|
||||||
(float)(this->totalMem) *
|
(float)(this->totalMem) *
|
||||||
|
@ -637,7 +650,8 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!existingProcess) {
|
if (!existingProcess) {
|
||||||
ProcessList_add(this, Process_clone(process));
|
process = Process_clone(process);
|
||||||
|
ProcessList_add(this, process);
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
@ -655,6 +669,7 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessList_scan(ProcessList* this) {
|
void ProcessList_scan(ProcessList* this) {
|
||||||
|
@ -665,6 +680,7 @@ void ProcessList_scan(ProcessList* this) {
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
status = ProcessList_fopen(this, PROCMEMINFOFILE, "r");
|
status = ProcessList_fopen(this, PROCMEMINFOFILE, "r");
|
||||||
assert(status != NULL);
|
assert(status != NULL);
|
||||||
|
int processors = this->processorCount;
|
||||||
while (!feof(status)) {
|
while (!feof(status)) {
|
||||||
fgets(buffer, 128, status);
|
fgets(buffer, 128, status);
|
||||||
|
|
||||||
|
@ -701,7 +717,7 @@ void ProcessList_scan(ProcessList* this) {
|
||||||
status = ProcessList_fopen(this, PROCSTATFILE, "r");
|
status = ProcessList_fopen(this, PROCSTATFILE, "r");
|
||||||
|
|
||||||
assert(status != NULL);
|
assert(status != NULL);
|
||||||
for (int i = 0; i <= this->processorCount; i++) {
|
for (int i = 0; i <= processors; i++) {
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
int cpuid;
|
int cpuid;
|
||||||
unsigned long long int ioWait, irq, softIrq, steal;
|
unsigned long long int ioWait, irq, softIrq, steal;
|
||||||
|
@ -755,7 +771,7 @@ void ProcessList_scan(ProcessList* this) {
|
||||||
this->stealTime[i] = steal;
|
this->stealTime[i] = steal;
|
||||||
this->totalTime[i] = totaltime;
|
this->totalTime[i] = totaltime;
|
||||||
}
|
}
|
||||||
float period = (float)this->totalPeriod[0] / this->processorCount;
|
float period = (float)this->totalPeriod[0] / processors;
|
||||||
fclose(status);
|
fclose(status);
|
||||||
|
|
||||||
// mark all process as "dirty"
|
// mark all process as "dirty"
|
||||||
|
@ -767,7 +783,7 @@ void ProcessList_scan(ProcessList* this) {
|
||||||
this->totalTasks = 0;
|
this->totalTasks = 0;
|
||||||
this->runningTasks = 0;
|
this->runningTasks = 0;
|
||||||
|
|
||||||
ProcessList_processEntries(this, PROCDIR, 0, period);
|
ProcessList_processEntries(this, PROCDIR, NULL, period);
|
||||||
|
|
||||||
for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
|
for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
|
||||||
Process* p = (Process*) Vector_get(this->processes, i);
|
Process* p = (Process*) Vector_get(this->processes, i);
|
||||||
|
|
|
@ -119,6 +119,7 @@ typedef struct ProcessList_ {
|
||||||
bool treeView;
|
bool treeView;
|
||||||
bool highlightBaseName;
|
bool highlightBaseName;
|
||||||
bool highlightMegabytes;
|
bool highlightMegabytes;
|
||||||
|
bool highlightThreads;
|
||||||
bool detailedCPUTime;
|
bool detailedCPUTime;
|
||||||
#ifdef DEBUG_PROC
|
#ifdef DEBUG_PROC
|
||||||
FILE* traceFile;
|
FILE* traceFile;
|
||||||
|
@ -164,7 +165,7 @@ void ProcessList_sort(ProcessList* this);
|
||||||
|
|
||||||
bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* dirname, char* name);
|
bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* dirname, char* name);
|
||||||
|
|
||||||
void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, float period);
|
bool ProcessList_processEntries(ProcessList* this, char* dirname, Process* parent, float period);
|
||||||
|
|
||||||
void ProcessList_scan(ProcessList* this);
|
void ProcessList_scan(ProcessList* this);
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@ Settings* Settings_new(ProcessList* pl, Header* header) {
|
||||||
Header_defaultMeters(this->header);
|
Header_defaultMeters(this->header);
|
||||||
pl->hideKernelThreads = true;
|
pl->hideKernelThreads = true;
|
||||||
pl->highlightMegabytes = true;
|
pl->highlightMegabytes = true;
|
||||||
|
pl->highlightThreads = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
@ -137,6 +138,8 @@ bool Settings_read(Settings* this, char* fileName) {
|
||||||
this->pl->highlightBaseName = atoi(option[1]);
|
this->pl->highlightBaseName = atoi(option[1]);
|
||||||
} else if (String_eq(option[0], "highlight_megabytes")) {
|
} else if (String_eq(option[0], "highlight_megabytes")) {
|
||||||
this->pl->highlightMegabytes = atoi(option[1]);
|
this->pl->highlightMegabytes = atoi(option[1]);
|
||||||
|
} else if (String_eq(option[0], "highlight_threads")) {
|
||||||
|
this->pl->highlightThreads = atoi(option[1]);
|
||||||
} else if (String_eq(option[0], "header_margin")) {
|
} else if (String_eq(option[0], "header_margin")) {
|
||||||
this->header->margin = atoi(option[1]);
|
this->header->margin = atoi(option[1]);
|
||||||
} else if (String_eq(option[0], "expand_system_time")) {
|
} else if (String_eq(option[0], "expand_system_time")) {
|
||||||
|
@ -198,6 +201,7 @@ bool Settings_write(Settings* this) {
|
||||||
fprintf(fd, "shadow_other_users=%d\n", (int) this->pl->shadowOtherUsers);
|
fprintf(fd, "shadow_other_users=%d\n", (int) this->pl->shadowOtherUsers);
|
||||||
fprintf(fd, "highlight_base_name=%d\n", (int) this->pl->highlightBaseName);
|
fprintf(fd, "highlight_base_name=%d\n", (int) this->pl->highlightBaseName);
|
||||||
fprintf(fd, "highlight_megabytes=%d\n", (int) this->pl->highlightMegabytes);
|
fprintf(fd, "highlight_megabytes=%d\n", (int) this->pl->highlightMegabytes);
|
||||||
|
fprintf(fd, "highlight_threads=%d\n", (int) this->pl->highlightThreads);
|
||||||
fprintf(fd, "tree_view=%d\n", (int) this->pl->treeView);
|
fprintf(fd, "tree_view=%d\n", (int) this->pl->treeView);
|
||||||
fprintf(fd, "header_margin=%d\n", (int) this->header->margin);
|
fprintf(fd, "header_margin=%d\n", (int) this->header->margin);
|
||||||
fprintf(fd, "detailed_cpu_time=%d\n", (int) this->pl->detailedCPUTime);
|
fprintf(fd, "detailed_cpu_time=%d\n", (int) this->pl->detailedCPUTime);
|
||||||
|
|
Loading…
Reference in New Issue