Skip to content

Commit

Permalink
Merge branch 'hili-new-old' of adsr/htop into highlight-new-old-proce…
Browse files Browse the repository at this point in the history
…sses
  • Loading branch information
Daniel Lange authored and Daniel Lange committed Nov 16, 2020
2 parents 0411fdb + a83f515 commit 0951090
Show file tree
Hide file tree
Showing 14 changed files with 166 additions and 37 deletions.
12 changes: 12 additions & 0 deletions CRT.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, Black),
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, Black),
[PROCESS_LOW_PRIORITY] = ColorPair(Green, Black),
[PROCESS_NEW] = ColorPair(Black,Green),
[PROCESS_TOMB] = ColorPair(Black,Red),
[PROCESS_THREAD] = ColorPair(Green, Black),
[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Green, Black),
[BAR_BORDER] = A_BOLD,
Expand Down Expand Up @@ -191,6 +193,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[PROCESS_D_STATE] = A_BOLD,
[PROCESS_HIGH_PRIORITY] = A_BOLD,
[PROCESS_LOW_PRIORITY] = A_DIM,
[PROCESS_NEW] = A_BOLD,
[PROCESS_TOMB] = A_DIM,
[PROCESS_THREAD] = A_BOLD,
[PROCESS_THREAD_BASENAME] = A_REVERSE,
[BAR_BORDER] = A_BOLD,
Expand Down Expand Up @@ -270,6 +274,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, White),
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, White),
[PROCESS_LOW_PRIORITY] = ColorPair(Green, White),
[PROCESS_NEW] = ColorPair(White,Green),
[PROCESS_TOMB] = ColorPair(White,Red),
[PROCESS_THREAD] = ColorPair(Blue, White),
[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Blue, White),
[BAR_BORDER] = ColorPair(Blue, White),
Expand Down Expand Up @@ -349,6 +355,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, Black),
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, Black),
[PROCESS_LOW_PRIORITY] = ColorPair(Green, Black),
[PROCESS_NEW] = ColorPair(Black,Green),
[PROCESS_TOMB] = ColorPair(Black,Red),
[PROCESS_THREAD] = ColorPair(Blue, Black),
[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Blue, Black),
[BAR_BORDER] = ColorPair(Blue, Black),
Expand Down Expand Up @@ -428,6 +436,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, Blue),
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, Blue),
[PROCESS_LOW_PRIORITY] = ColorPair(Green, Blue),
[PROCESS_NEW] = ColorPair(Blue,Green),
[PROCESS_TOMB] = ColorPair(Blue,Red),
[PROCESS_THREAD] = ColorPair(Green, Blue),
[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Green, Blue),
[BAR_BORDER] = A_BOLD | ColorPair(Yellow, Blue),
Expand Down Expand Up @@ -509,6 +519,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, Black),
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, Black),
[PROCESS_LOW_PRIORITY] = ColorPair(Green, Black),
[PROCESS_NEW] = ColorPair(Black,Green),
[PROCESS_TOMB] = ColorPair(Black,Red),
[BAR_BORDER] = A_BOLD | ColorPair(Green, Black),
[BAR_SHADOW] = ColorPair(Cyan, Black),
[SWAP] = ColorPair(Red, Black),
Expand Down
2 changes: 2 additions & 0 deletions CRT.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ typedef enum ColorElements_ {
PROCESS_BASENAME,
PROCESS_HIGH_PRIORITY,
PROCESS_LOW_PRIORITY,
PROCESS_NEW,
PROCESS_TOMB,
PROCESS_THREAD,
PROCESS_THREAD_BASENAME,
BAR_BORDER,
Expand Down
1 change: 1 addition & 0 deletions DisplayOptionsPanel.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager*
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Also show CPU percentage numerically"), &(settings->showCPUUsage)));
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Also show CPU frequency"), &(settings->showCPUFrequency)));
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Enable the mouse"), &(settings->enableMouse)));
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Highlight new and old processes"), &(settings->highlightChanges)));
#ifdef HAVE_LIBHWLOC
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Show topology when selecting affinity by default"), &(settings->topologyAffinity)));
#endif
Expand Down
12 changes: 7 additions & 5 deletions Panel.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,16 +273,18 @@ void Panel_draw(Panel* this, bool focus) {
Object_display(itemObj, &item);
int itemLen = RichString_sizeVal(item);
int amt = MINIMUM(itemLen - scrollH, this->w);
bool selected = (i == this->selected);
if (selected) {
attrset(selectionColor);
RichString_setAttr(&item, selectionColor);
if (i == this->selected) {
item.highlightAttr = selectionColor;
}
if (item.highlightAttr) {
attrset(item.highlightAttr);
RichString_setAttr(&item, item.highlightAttr);
this->selectedLen = itemLen;
}
mvhline(y + line, x, ' ', this->w);
if (amt > 0)
RichString_printoffnVal(item, y + line, x, scrollH, amt);
if (selected)
if (item.highlightAttr)
attrset(CRT_colors[RESET_COLOR]);
RichString_end(item);
line++;
Expand Down
48 changes: 34 additions & 14 deletions Process.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ void Process_humanNumber(RichString* str, unsigned long long number, bool colori
RichString_appendn(str, processColor, buffer, len);
} else if (number < 100000) {
//2 digit MB, 3 digit KB
len = snprintf(buffer, 10, "%2llu", number / 1000);
len = snprintf(buffer, 10, "%2llu", number/1000);
RichString_appendn(str, processMegabytesColor, buffer, len);
number %= 1000;
len = snprintf(buffer, 10, "%03llu ", number);
Expand All @@ -89,15 +89,15 @@ void Process_humanNumber(RichString* str, unsigned long long number, bool colori
} else if (number < 10000 * ONE_K) {
//1 digit GB, 3 digit MB
number /= ONE_K;
len = snprintf(buffer, 10, "%1llu", number / 1000);
len = snprintf(buffer, 10, "%1llu", number/1000);
RichString_appendn(str, processGigabytesColor, buffer, len);
number %= 1000;
len = snprintf(buffer, 10, "%03lluM ", number);
RichString_appendn(str, processMegabytesColor, buffer, len);
} else if (number < 100000 * ONE_K) {
//2 digit GB, 1 digit MB
number /= 100 * ONE_K;
len = snprintf(buffer, 10, "%2llu", number / 10);
len = snprintf(buffer, 10, "%2llu", number/10);
RichString_appendn(str, processGigabytesColor, buffer, len);
number %= 10;
len = snprintf(buffer, 10, ".%1lluG ", number);
Expand All @@ -110,14 +110,14 @@ void Process_humanNumber(RichString* str, unsigned long long number, bool colori
} else if (number < 10000ULL * ONE_M) {
//1 digit TB, 3 digit GB
number /= ONE_M;
len = snprintf(buffer, 10, "%1llu", number / 1000);
len = snprintf(buffer, 10, "%1llu", number/1000);
RichString_appendn(str, largeNumberColor, buffer, len);
number %= 1000;
len = snprintf(buffer, 10, "%03lluG ", number);
RichString_appendn(str, processGigabytesColor, buffer, len);
} else {
//2 digit TB and above
len = snprintf(buffer, 10, "%4.1lfT ", (double)number / ONE_G);
len = snprintf(buffer, 10, "%4.1lfT ", (double)number/ONE_G);
RichString_appendn(str, largeNumberColor, buffer, len);
}
}
Expand All @@ -144,18 +144,18 @@ void Process_colorNumber(RichString* str, unsigned long long number, bool colori
} else if (number >= 100LL * ONE_DECIMAL_T) {
xSnprintf(buffer, 13, "%11llu ", number / ONE_DECIMAL_M);
RichString_appendn(str, largeNumberColor, buffer, 8);
RichString_appendn(str, processMegabytesColor, buffer + 8, 4);
RichString_appendn(str, processMegabytesColor, buffer+8, 4);
} else if (number >= 10LL * ONE_DECIMAL_G) {
xSnprintf(buffer, 13, "%11llu ", number / ONE_DECIMAL_K);
RichString_appendn(str, largeNumberColor, buffer, 5);
RichString_appendn(str, processMegabytesColor, buffer + 5, 3);
RichString_appendn(str, processColor, buffer + 8, 4);
RichString_appendn(str, processMegabytesColor, buffer+5, 3);
RichString_appendn(str, processColor, buffer+8, 4);
} else {
xSnprintf(buffer, 13, "%11llu ", number);
RichString_appendn(str, largeNumberColor, buffer, 2);
RichString_appendn(str, processMegabytesColor, buffer + 2, 3);
RichString_appendn(str, processColor, buffer + 5, 3);
RichString_appendn(str, processShadowColor, buffer + 8, 4);
RichString_appendn(str, processMegabytesColor, buffer+2, 3);
RichString_appendn(str, processColor, buffer+5, 3);
RichString_appendn(str, processShadowColor, buffer+8, 4);
}
}

Expand Down Expand Up @@ -291,11 +291,11 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field

for (int i = 0; i < 32; i++) {
if (indent & (1U << i)) {
maxIndent = i + 1;
maxIndent = i+1;
}
}

for (int i = 0; i < maxIndent - 1; i++) {
for (int i = 0; i < maxIndent - 1; i++) {
int written, ret;
if (indent & (1 << i)) {
ret = snprintf(buf, n, "%s ", CRT_treeStr[TREE_STR_VERT]);
Expand Down Expand Up @@ -333,7 +333,7 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field
case PID: xSnprintf(buffer, n, Process_pidFormat, this->pid); break;
case PPID: xSnprintf(buffer, n, Process_pidFormat, this->ppid); break;
case PRIORITY: {
if (this->priority <= -100)
if(this->priority <= -100)
xSnprintf(buffer, n, " RT ");
else
xSnprintf(buffer, n, "%3ld ", this->priority);
Expand Down Expand Up @@ -394,6 +394,14 @@ void Process_display(const Object* cast, RichString* out) {
RichString_setAttr(out, CRT_colors[PROCESS_TAG]);
}

if (this->settings->highlightChanges) {
if (Process_isTomb(this)) {
out->highlightAttr = CRT_colors[PROCESS_TOMB];
} else if (Process_isNew(this)) {
out->highlightAttr = CRT_colors[PROCESS_NEW];
}
}

assert(out->chlen > 0);
}

Expand Down Expand Up @@ -429,6 +437,18 @@ void Process_toggleTag(Process* this) {
this->tag = this->tag == true ? false : true;
}

bool Process_isNew(const Process* this) {
assert(this->processList);
if (this->processList->scanTs >= this->seenTs) {
return this->processList->scanTs - this->seenTs <= this->processList->settings->highlightDelaySecs;
}
return false;
}

bool Process_isTomb(const Process* this) {
return this->tombTs > 0;
}

bool Process_setPriority(Process* this, int priority) {
CRT_dropPrivileges();
int old_prio = getpriority(PRIO_PROCESS, this->pid);
Expand Down
14 changes: 12 additions & 2 deletions Process.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@ in the source distribution for its full text.
*/

#include <stdbool.h>
#include <time.h>
#include <sys/types.h>

#include "Object.h"
#include "RichString.h"


#ifdef __ANDROID__
#define SYS_ioprio_get __NR_ioprio_get
#define SYS_ioprio_set __NR_ioprio_set
#endif

#define PROCESS_FLAG_IO 0x0001
#define DEFAULT_HIGHLIGHT_SECS 5

typedef enum ProcessFields {
NULL_PROCESSFIELD = 0,
Expand Down Expand Up @@ -59,6 +60,7 @@ struct Settings_;
typedef struct Process_ {
Object super;

const struct ProcessList_* processList;
const struct Settings_* settings;

unsigned long long int time;
Expand All @@ -76,6 +78,7 @@ typedef struct Process_ {
bool tag;
bool showChildren;
bool show;
bool wasShown;
unsigned int pgrp;
unsigned int session;
unsigned int tty_nr;
Expand All @@ -99,6 +102,9 @@ typedef struct Process_ {

int exit_signal;

time_t seenTs;
time_t tombTs;

unsigned long int minflt;
unsigned long int majflt;
} Process;
Expand All @@ -119,7 +125,7 @@ extern ProcessFieldData Process_fields[];
extern ProcessPidColumn Process_pidColumns[];
extern char Process_pidFormat[20];

typedef Process* (* Process_New)(const struct Settings_*);
typedef Process*(*Process_New)(const struct Settings_*);
typedef void (*Process_WriteField)(const Process*, RichString*, ProcessField);

typedef struct ProcessClass_ {
Expand Down Expand Up @@ -172,6 +178,10 @@ void Process_init(Process* this, const struct Settings_* settings);

void Process_toggleTag(Process* this);

bool Process_isNew(const Process* this);

bool Process_isTomb(const Process* this);

bool Process_setPriority(Process* this, int priority);

bool Process_changePriorityBy(Process* this, Arg delta);
Expand Down
45 changes: 40 additions & 5 deletions ProcessList.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ in the source distribution for its full text.

#include <assert.h>
#include <string.h>
#include <time.h>

#include "CRT.h"
#include "XUtils.h"
Expand All @@ -27,6 +28,9 @@ ProcessList* ProcessList_init(ProcessList* this, const ObjectClass* klass, Users
// set later by platform-specific code
this->cpuCount = 0;

this->scanTs = 0;
this->firstScanTs = 0;

#ifdef HAVE_LIBHWLOC
this->topologyOk = false;
if (hwloc_topology_init(&this->topology) == 0) {
Expand Down Expand Up @@ -85,6 +89,14 @@ void ProcessList_printHeader(ProcessList* this, RichString* header) {
void ProcessList_add(ProcessList* this, Process* p) {
assert(Vector_indexOf(this->processes, p, Process_pidCompare) == -1);
assert(Hashtable_get(this->processTable, p->pid) == NULL);
p->processList = this;

if (this->scanTs == this->firstScanTs) {
// prevent highlighting processes found in first scan
p->seenTs = this->firstScanTs - this->settings->highlightDelaySecs - 1;
} else {
p->seenTs = this->scanTs;
}

Vector_add(this->processes, p);
Hashtable_put(this->processTable, p->pid, p);
Expand Down Expand Up @@ -145,10 +157,10 @@ static void ProcessList_buildTree(ProcessList* this, pid_t pid, int level, int i
Vector_insert(this->processes2, 0, process);
}

assert(Vector_size(this->processes2) == s + 1); (void)s;
assert(Vector_size(this->processes2) == s+1); (void)s;

int nextIndent = indent | (1 << level);
ProcessList_buildTree(this, process->pid, level + 1, (i < size - 1) ? nextIndent : indent, direction, show ? process->showChildren : false);
ProcessList_buildTree(this, process->pid, level+1, (i < size - 1) ? nextIndent : indent, direction, show ? process->showChildren : false);

if (i == size - 1) {
process->indent = -nextIndent;
Expand All @@ -160,8 +172,8 @@ static void ProcessList_buildTree(ProcessList* this, pid_t pid, int level, int i
}

static long ProcessList_treeProcessCompare(const void* v1, const void* v2) {
const Process* p1 = (const Process*)v1;
const Process* p2 = (const Process*)v2;
const Process *p1 = (const Process*)v1;
const Process *p2 = (const Process*)v2;

return p1->pid - p2->pid;
}
Expand Down Expand Up @@ -304,6 +316,7 @@ Process* ProcessList_getProcess(ProcessList* this, pid_t pid, bool* preExisting,
}

void ProcessList_scan(ProcessList* this, bool pauseProcessUpdate) {
struct timespec now;

// in pause mode only gather global data for meters (CPU/memory/...)
if (pauseProcessUpdate) {
Expand All @@ -315,6 +328,7 @@ void ProcessList_scan(ProcessList* this, bool pauseProcessUpdate) {
for (int i = 0; i < Vector_size(this->processes); i++) {
Process* p = (Process*) Vector_get(this->processes, i);
p->updated = false;
p->wasShown = p->show;
p->show = true;
}

Expand All @@ -323,12 +337,33 @@ void ProcessList_scan(ProcessList* this, bool pauseProcessUpdate) {
this->kernelThreads = 0;
this->runningTasks = 0;


// set scanTs
if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) {
if (this->firstScanTs == 0) {
this->firstScanTs = now.tv_sec;
}
this->scanTs = now.tv_sec;
}

ProcessList_goThroughEntries(this, false);

for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
Process* p = (Process*) Vector_get(this->processes, i);
if (p->updated == false) {
if (p->tombTs > 0) {
// remove tombed process
if (this->scanTs >= p->tombTs) {
ProcessList_remove(this, p);
}
} else if (p->updated == false) {
// process no longer exists
if (this->settings->highlightChanges && p->wasShown) {
// mark tombed
p->tombTs = this->scanTs + this->settings->highlightDelaySecs;
} else {
// immediately remove
ProcessList_remove(this, p);
}
} else {
p->updated = false;
}
Expand Down
Loading

0 comments on commit 0951090

Please sign in to comment.