mirror of https://github.com/xzeldon/htop.git
show custom thread names
This commit is contained in:
parent
aff118ab39
commit
8f230920cd
|
@ -69,6 +69,7 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager*
|
||||||
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("Display threads in a different color"), &(settings->pl->highlightThreads), false));
|
||||||
|
Panel_add(super, (Object*) CheckItem_new(String_copy("Show custom thread names"), &(settings->pl->showThreadNames), 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));
|
||||||
|
|
102
ProcessList.c
102
ProcessList.c
|
@ -114,6 +114,8 @@ typedef struct ProcessList_ {
|
||||||
int direction;
|
int direction;
|
||||||
bool hideThreads;
|
bool hideThreads;
|
||||||
bool shadowOtherUsers;
|
bool shadowOtherUsers;
|
||||||
|
bool showThreadNames;
|
||||||
|
bool showingThreadNames;
|
||||||
bool hideKernelThreads;
|
bool hideKernelThreads;
|
||||||
bool hideUserlandThreads;
|
bool hideUserlandThreads;
|
||||||
bool treeView;
|
bool treeView;
|
||||||
|
@ -246,6 +248,8 @@ ProcessList* ProcessList_new(UsersTable* usersTable) {
|
||||||
this->direction = 1;
|
this->direction = 1;
|
||||||
this->hideThreads = false;
|
this->hideThreads = false;
|
||||||
this->shadowOtherUsers = false;
|
this->shadowOtherUsers = false;
|
||||||
|
this->showThreadNames = true;
|
||||||
|
this->showingThreadNames = true;
|
||||||
this->hideKernelThreads = false;
|
this->hideKernelThreads = false;
|
||||||
this->hideUserlandThreads = false;
|
this->hideUserlandThreads = false;
|
||||||
this->treeView = false;
|
this->treeView = false;
|
||||||
|
@ -286,7 +290,7 @@ RichString ProcessList_printHeader(ProcessList* this) {
|
||||||
RichString_initVal(out);
|
RichString_initVal(out);
|
||||||
ProcessField* fields = this->fields;
|
ProcessField* fields = this->fields;
|
||||||
for (int i = 0; fields[i]; i++) {
|
for (int i = 0; fields[i]; i++) {
|
||||||
char* field = Process_fieldTitles[fields[i]];
|
const char* field = Process_fieldTitles[fields[i]];
|
||||||
if (this->sortKey == fields[i])
|
if (this->sortKey == fields[i])
|
||||||
RichString_append(&out, CRT_colors[PANEL_HIGHLIGHT_FOCUS], field);
|
RichString_append(&out, CRT_colors[PANEL_HIGHLIGHT_FOCUS], field);
|
||||||
else
|
else
|
||||||
|
@ -311,28 +315,28 @@ static void ProcessList_remove(ProcessList* this, Process* p) {
|
||||||
Process* pp = Hashtable_remove(this->processTable, p->pid);
|
Process* pp = Hashtable_remove(this->processTable, p->pid);
|
||||||
assert(pp == p); (void)pp;
|
assert(pp == p); (void)pp;
|
||||||
unsigned int pid = p->pid;
|
unsigned int pid = p->pid;
|
||||||
int index = Vector_indexOf(this->processes, p, Process_pidCompare);
|
int idx = Vector_indexOf(this->processes, p, Process_pidCompare);
|
||||||
assert(index != -1);
|
assert(idx != -1);
|
||||||
if (index >= 0) Vector_remove(this->processes, index);
|
if (idx >= 0) Vector_remove(this->processes, idx);
|
||||||
assert(Hashtable_get(this->processTable, pid) == NULL); (void)pid;
|
assert(Hashtable_get(this->processTable, pid) == NULL); (void)pid;
|
||||||
assert(Hashtable_count(this->processTable) == Vector_count(this->processes));
|
assert(Hashtable_count(this->processTable) == Vector_count(this->processes));
|
||||||
}
|
}
|
||||||
|
|
||||||
Process* ProcessList_get(ProcessList* this, int index) {
|
Process* ProcessList_get(ProcessList* this, int idx) {
|
||||||
return (Process*) (Vector_get(this->processes, index));
|
return (Process*) (Vector_get(this->processes, idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
int ProcessList_size(ProcessList* this) {
|
int ProcessList_size(ProcessList* this) {
|
||||||
return (Vector_size(this->processes));
|
return (Vector_size(this->processes));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ProcessList_buildTree(ProcessList* this, int pid, int level, int indent, int direction) {
|
static void ProcessList_buildTree(ProcessList* this, pid_t pid, int level, int indent, int direction) {
|
||||||
Vector* children = Vector_new(PROCESS_CLASS, false, DEFAULT_SIZE, Process_compare);
|
Vector* children = Vector_new(PROCESS_CLASS, false, DEFAULT_SIZE, Process_compare);
|
||||||
|
|
||||||
for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
|
for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
|
||||||
Process* process = (Process*) (Vector_get(this->processes, i));
|
Process* process = (Process*) (Vector_get(this->processes, i));
|
||||||
if (process->tgid == pid || (process->tgid == process->pid && process->ppid == pid)) {
|
if (process->tgid == pid || (process->tgid == process->pid && process->ppid == pid)) {
|
||||||
Process* process = (Process*) (Vector_take(this->processes, i));
|
process = (Process*) (Vector_take(this->processes, i));
|
||||||
Vector_add(children, process);
|
Vector_add(children, process);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -394,7 +398,7 @@ void ProcessList_sort(ProcessList* this) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, char *command) {
|
static int ProcessList_readStatFile(Process *proc, FILE *f, char *command) {
|
||||||
static char buf[MAX_READ];
|
static char buf[MAX_READ];
|
||||||
unsigned long int zero;
|
unsigned long int zero;
|
||||||
|
|
||||||
|
@ -434,7 +438,7 @@ static int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, c
|
||||||
#else
|
#else
|
||||||
long int uzero;
|
long int uzero;
|
||||||
int num = ProcessList_read(this, location,
|
int num = ProcessList_read(this, location,
|
||||||
"%c %u %u %u %u %d %lu %lu %lu %lu "
|
"%c %d %u %u %u %d %lu %lu %lu %lu "
|
||||||
"%lu %lu %lu %ld %ld %ld %ld %ld %ld "
|
"%lu %lu %lu %ld %ld %ld %ld %ld %ld "
|
||||||
"%lu %lu %ld %lu %lu %lu %lu %lu "
|
"%lu %lu %ld %lu %lu %lu %lu %lu "
|
||||||
"%lu %lu %lu %lu %lu %lu %lu %lu "
|
"%lu %lu %lu %lu %lu %lu %lu %lu "
|
||||||
|
@ -459,7 +463,7 @@ static int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, c
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* dirname, char* name) {
|
static bool ProcessList_readStatusFile(Process* proc, const char* dirname, char* name) {
|
||||||
char statusfilename[MAX_NAME+1];
|
char statusfilename[MAX_NAME+1];
|
||||||
statusfilename[MAX_NAME] = '\0';
|
statusfilename[MAX_NAME] = '\0';
|
||||||
|
|
||||||
|
@ -474,7 +478,7 @@ static bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* d
|
||||||
|
|
||||||
#ifdef HAVE_TASKSTATS
|
#ifdef HAVE_TASKSTATS
|
||||||
|
|
||||||
static void ProcessList_readIoFile(ProcessList* this, Process* proc, char* dirname, char* name) {
|
static void ProcessList_readIoFile(Process* proc, const char* dirname, char* name) {
|
||||||
char iofilename[MAX_NAME+1];
|
char iofilename[MAX_NAME+1];
|
||||||
iofilename[MAX_NAME] = '\0';
|
iofilename[MAX_NAME] = '\0';
|
||||||
|
|
||||||
|
@ -513,11 +517,10 @@ static void ProcessList_readIoFile(ProcessList* this, Process* proc, char* dirna
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process* parent, float period) {
|
static bool ProcessList_processEntries(ProcessList* this, const char* dirname, Process* parent, pid_t parentPid, float period) {
|
||||||
DIR* dir;
|
DIR* dir;
|
||||||
struct dirent* entry;
|
struct dirent* entry;
|
||||||
Process* prototype = this->prototype;
|
Process* prototype = this->prototype;
|
||||||
int parentPid = parent ? parent->pid : 0;
|
|
||||||
|
|
||||||
dir = opendir(dirname);
|
dir = opendir(dirname);
|
||||||
if (!dir) return false;
|
if (!dir) return false;
|
||||||
|
@ -567,18 +570,18 @@ static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process
|
||||||
char subdirname[MAX_NAME+1];
|
char subdirname[MAX_NAME+1];
|
||||||
snprintf(subdirname, MAX_NAME, "%s/%s/task", dirname, name);
|
snprintf(subdirname, MAX_NAME, "%s/%s/task", dirname, name);
|
||||||
|
|
||||||
if (ProcessList_processEntries(this, subdirname, process, period))
|
if (ProcessList_processEntries(this, subdirname, process, pid, period))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_TASKSTATS
|
#ifdef HAVE_TASKSTATS
|
||||||
ProcessList_readIoFile(this, process, dirname, name);
|
ProcessList_readIoFile(process, dirname, name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
process->updated = true;
|
process->updated = true;
|
||||||
|
|
||||||
if (!existingProcess)
|
if (!existingProcess)
|
||||||
if (! ProcessList_readStatusFile(this, process, dirname, name))
|
if (! ProcessList_readStatusFile(process, dirname, name))
|
||||||
goto errorReadingProcess;
|
goto errorReadingProcess;
|
||||||
|
|
||||||
snprintf(statusfilename, MAX_NAME, "%s/%s/statm", dirname, name);
|
snprintf(statusfilename, MAX_NAME, "%s/%s/statm", dirname, name);
|
||||||
|
@ -607,7 +610,7 @@ static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process
|
||||||
if (status == NULL)
|
if (status == NULL)
|
||||||
goto errorReadingProcess;
|
goto errorReadingProcess;
|
||||||
|
|
||||||
int success = ProcessList_readStatFile(this, process, status, command);
|
int success = ProcessList_readStatFile(process, status, command);
|
||||||
fclose(status);
|
fclose(status);
|
||||||
if(!success) {
|
if(!success) {
|
||||||
goto errorReadingProcess;
|
goto errorReadingProcess;
|
||||||
|
@ -668,6 +671,10 @@ static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process
|
||||||
fclose(status);
|
fclose(status);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ((!existingProcess) && (!showUserlandThreads || pid == parentPid || !this->showThreadNames))
|
||||||
|
|| (this->showingThreadNames && !this->showThreadNames) ) {
|
||||||
|
|
||||||
snprintf(statusfilename, MAX_NAME, "%s/%s/cmdline", dirname, name);
|
snprintf(statusfilename, MAX_NAME, "%s/%s/cmdline", dirname, name);
|
||||||
status = ProcessList_fopen(this, statusfilename, "r");
|
status = ProcessList_fopen(this, statusfilename, "r");
|
||||||
|
@ -683,9 +690,10 @@ static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process
|
||||||
command[amtRead] = '\0';
|
command[amtRead] = '\0';
|
||||||
}
|
}
|
||||||
fclose(status);
|
fclose(status);
|
||||||
|
|
||||||
command[PROCESS_COMM_LEN] = '\0';
|
command[PROCESS_COMM_LEN] = '\0';
|
||||||
process->comm = String_copy(command);
|
process->comm = String_copy(command);
|
||||||
|
} else if (pid != parentPid && this->showThreadNames) {
|
||||||
|
process->comm = String_copy(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
int percent_cpu = (process->utime + process->stime - lasttimes) /
|
int percent_cpu = (process->utime + process->stime - lasttimes) /
|
||||||
|
@ -729,35 +737,37 @@ void ProcessList_scan(ProcessList* this) {
|
||||||
unsigned long long int swapFree = 0;
|
unsigned long long int swapFree = 0;
|
||||||
|
|
||||||
FILE* status;
|
FILE* status;
|
||||||
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;
|
int processors = this->processorCount;
|
||||||
while (fgets(buffer, 128, status)) {
|
{
|
||||||
|
char buffer[128];
|
||||||
|
while (fgets(buffer, 128, status)) {
|
||||||
|
|
||||||
switch (buffer[0]) {
|
switch (buffer[0]) {
|
||||||
case 'M':
|
case 'M':
|
||||||
if (String_startsWith(buffer, "MemTotal:"))
|
if (String_startsWith(buffer, "MemTotal:"))
|
||||||
ProcessList_read(this, buffer, "MemTotal: %llu kB", &this->totalMem);
|
ProcessList_read(this, buffer, "MemTotal: %llu kB", &this->totalMem);
|
||||||
else if (String_startsWith(buffer, "MemFree:"))
|
else if (String_startsWith(buffer, "MemFree:"))
|
||||||
ProcessList_read(this, buffer, "MemFree: %llu kB", &this->freeMem);
|
ProcessList_read(this, buffer, "MemFree: %llu kB", &this->freeMem);
|
||||||
else if (String_startsWith(buffer, "MemShared:"))
|
else if (String_startsWith(buffer, "MemShared:"))
|
||||||
ProcessList_read(this, buffer, "MemShared: %llu kB", &this->sharedMem);
|
ProcessList_read(this, buffer, "MemShared: %llu kB", &this->sharedMem);
|
||||||
break;
|
break;
|
||||||
case 'B':
|
case 'B':
|
||||||
if (String_startsWith(buffer, "Buffers:"))
|
if (String_startsWith(buffer, "Buffers:"))
|
||||||
ProcessList_read(this, buffer, "Buffers: %llu kB", &this->buffersMem);
|
ProcessList_read(this, buffer, "Buffers: %llu kB", &this->buffersMem);
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
if (String_startsWith(buffer, "Cached:"))
|
if (String_startsWith(buffer, "Cached:"))
|
||||||
ProcessList_read(this, buffer, "Cached: %llu kB", &this->cachedMem);
|
ProcessList_read(this, buffer, "Cached: %llu kB", &this->cachedMem);
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
if (String_startsWith(buffer, "SwapTotal:"))
|
if (String_startsWith(buffer, "SwapTotal:"))
|
||||||
ProcessList_read(this, buffer, "SwapTotal: %llu kB", &this->totalSwap);
|
ProcessList_read(this, buffer, "SwapTotal: %llu kB", &this->totalSwap);
|
||||||
if (String_startsWith(buffer, "SwapFree:"))
|
if (String_startsWith(buffer, "SwapFree:"))
|
||||||
ProcessList_read(this, buffer, "SwapFree: %llu kB", &swapFree);
|
ProcessList_read(this, buffer, "SwapFree: %llu kB", &swapFree);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,7 +844,9 @@ void ProcessList_scan(ProcessList* this) {
|
||||||
this->totalTasks = 0;
|
this->totalTasks = 0;
|
||||||
this->runningTasks = 0;
|
this->runningTasks = 0;
|
||||||
|
|
||||||
ProcessList_processEntries(this, PROCDIR, NULL, period);
|
ProcessList_processEntries(this, PROCDIR, NULL, 0, period);
|
||||||
|
|
||||||
|
this->showingThreadNames = this->showThreadNames;
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -114,6 +114,8 @@ typedef struct ProcessList_ {
|
||||||
int direction;
|
int direction;
|
||||||
bool hideThreads;
|
bool hideThreads;
|
||||||
bool shadowOtherUsers;
|
bool shadowOtherUsers;
|
||||||
|
bool showThreadNames;
|
||||||
|
bool showingThreadNames;
|
||||||
bool hideKernelThreads;
|
bool hideKernelThreads;
|
||||||
bool hideUserlandThreads;
|
bool hideUserlandThreads;
|
||||||
bool treeView;
|
bool treeView;
|
||||||
|
@ -150,7 +152,7 @@ void ProcessList_invertSortOrder(ProcessList* this);
|
||||||
|
|
||||||
RichString ProcessList_printHeader(ProcessList* this);
|
RichString ProcessList_printHeader(ProcessList* this);
|
||||||
|
|
||||||
Process* ProcessList_get(ProcessList* this, int index);
|
Process* ProcessList_get(ProcessList* this, int idx);
|
||||||
|
|
||||||
int ProcessList_size(ProcessList* this);
|
int ProcessList_size(ProcessList* this);
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,8 @@ static bool Settings_read(Settings* this, char* fileName) {
|
||||||
this->pl->hideUserlandThreads = atoi(option[1]);
|
this->pl->hideUserlandThreads = atoi(option[1]);
|
||||||
} else if (String_eq(option[0], "shadow_other_users")) {
|
} else if (String_eq(option[0], "shadow_other_users")) {
|
||||||
this->pl->shadowOtherUsers = atoi(option[1]);
|
this->pl->shadowOtherUsers = atoi(option[1]);
|
||||||
|
} else if (String_eq(option[0], "show_thread_names")) {
|
||||||
|
this->pl->showThreadNames = atoi(option[1]);
|
||||||
} else if (String_eq(option[0], "highlight_base_name")) {
|
} else if (String_eq(option[0], "highlight_base_name")) {
|
||||||
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")) {
|
||||||
|
@ -163,6 +165,7 @@ bool Settings_write(Settings* this) {
|
||||||
fprintf(fd, "hide_kernel_threads=%d\n", (int) this->pl->hideKernelThreads);
|
fprintf(fd, "hide_kernel_threads=%d\n", (int) this->pl->hideKernelThreads);
|
||||||
fprintf(fd, "hide_userland_threads=%d\n", (int) this->pl->hideUserlandThreads);
|
fprintf(fd, "hide_userland_threads=%d\n", (int) this->pl->hideUserlandThreads);
|
||||||
fprintf(fd, "shadow_other_users=%d\n", (int) this->pl->shadowOtherUsers);
|
fprintf(fd, "shadow_other_users=%d\n", (int) this->pl->shadowOtherUsers);
|
||||||
|
fprintf(fd, "show_thread_names=%d\n", (int) this->pl->showThreadNames);
|
||||||
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, "highlight_threads=%d\n", (int) this->pl->highlightThreads);
|
||||||
|
@ -201,7 +204,7 @@ Settings* Settings_new(ProcessList* pl, Header* header) {
|
||||||
Settings* this = malloc(sizeof(Settings));
|
Settings* this = malloc(sizeof(Settings));
|
||||||
this->pl = pl;
|
this->pl = pl;
|
||||||
this->header = header;
|
this->header = header;
|
||||||
char* home;
|
const char* home;
|
||||||
char* rcfile;
|
char* rcfile;
|
||||||
home = getenv("HOME_ETC");
|
home = getenv("HOME_ETC");
|
||||||
if (!home) home = getenv("HOME");
|
if (!home) home = getenv("HOME");
|
||||||
|
|
Loading…
Reference in New Issue