mirror of https://github.com/xzeldon/htop.git
Perform RichString operations by hand.
Avoid unnecessary operations when processing entries on ProcessList.
This commit is contained in:
parent
e46f1426b9
commit
dbe2670b69
|
@ -81,7 +81,7 @@ void CPUMeter_setValues(Meter* this, char* buffer, int size) {
|
|||
void CPUMeter_display(Object* cast, RichString* out) {
|
||||
char buffer[50];
|
||||
Meter* this = (Meter*)cast;
|
||||
RichString_prune(out);
|
||||
RichString_init(out);
|
||||
sprintf(buffer, "%5.1f%% ", this->values[1]);
|
||||
RichString_append(out, CRT_colors[METER_TEXT], ":");
|
||||
RichString_append(out, CRT_colors[CPU_NORMAL], buffer);
|
||||
|
|
13
Hashtable.c
13
Hashtable.c
|
@ -16,7 +16,6 @@ in the source distribution for its full text.
|
|||
typedef struct Hashtable_ Hashtable;
|
||||
|
||||
typedef void(*Hashtable_PairFunction)(int, void*, void*);
|
||||
typedef int(*Hashtable_HashAlgorithm)(Hashtable*, int);
|
||||
|
||||
typedef struct HashtableItem {
|
||||
int key;
|
||||
|
@ -28,7 +27,6 @@ struct Hashtable_ {
|
|||
int size;
|
||||
HashtableItem** buckets;
|
||||
int items;
|
||||
Hashtable_HashAlgorithm hashAlgorithm;
|
||||
bool owner;
|
||||
};
|
||||
}*/
|
||||
|
@ -49,15 +47,10 @@ Hashtable* Hashtable_new(int size, bool owner) {
|
|||
this = (Hashtable*) malloc(sizeof(Hashtable));
|
||||
this->size = size;
|
||||
this->buckets = (HashtableItem**) calloc(sizeof(HashtableItem*), size);
|
||||
this->hashAlgorithm = Hashtable_hashAlgorithm;
|
||||
this->owner = owner;
|
||||
return this;
|
||||
}
|
||||
|
||||
int Hashtable_hashAlgorithm(Hashtable* this, int key) {
|
||||
return key % this->size;
|
||||
}
|
||||
|
||||
void Hashtable_delete(Hashtable* this) {
|
||||
for (int i = 0; i < this->size; i++) {
|
||||
HashtableItem* walk = this->buckets[i];
|
||||
|
@ -78,7 +71,7 @@ inline int Hashtable_size(Hashtable* this) {
|
|||
}
|
||||
|
||||
void Hashtable_put(Hashtable* this, int key, void* value) {
|
||||
int index = this->hashAlgorithm(this, key);
|
||||
int index = key % this->size;
|
||||
HashtableItem** bucketPtr = &(this->buckets[index]);
|
||||
while (true)
|
||||
if (*bucketPtr == NULL) {
|
||||
|
@ -95,7 +88,7 @@ void Hashtable_put(Hashtable* this, int key, void* value) {
|
|||
}
|
||||
|
||||
void* Hashtable_remove(Hashtable* this, int key) {
|
||||
int index = this->hashAlgorithm(this, key);
|
||||
int index = key % this->size;
|
||||
HashtableItem** bucketPtr = &(this->buckets[index]);
|
||||
while (true)
|
||||
if (*bucketPtr == NULL) {
|
||||
|
@ -118,7 +111,7 @@ void* Hashtable_remove(Hashtable* this, int key) {
|
|||
}
|
||||
//#include <stdio.h>
|
||||
inline void* Hashtable_get(Hashtable* this, int key) {
|
||||
int index = this->hashAlgorithm(this, key);
|
||||
int index = key % this->size;
|
||||
HashtableItem* bucketPtr = this->buckets[index];
|
||||
// fprintf(stderr, "%d -> %d\n", key, index);
|
||||
while (true) {
|
||||
|
|
|
@ -18,7 +18,6 @@ in the source distribution for its full text.
|
|||
typedef struct Hashtable_ Hashtable;
|
||||
|
||||
typedef void(*Hashtable_PairFunction)(int, void*, void*);
|
||||
typedef int(*Hashtable_HashAlgorithm)(Hashtable*, int);
|
||||
|
||||
typedef struct HashtableItem {
|
||||
int key;
|
||||
|
@ -30,7 +29,6 @@ struct Hashtable_ {
|
|||
int size;
|
||||
HashtableItem** buckets;
|
||||
int items;
|
||||
Hashtable_HashAlgorithm hashAlgorithm;
|
||||
bool owner;
|
||||
};
|
||||
|
||||
|
@ -38,8 +36,6 @@ HashtableItem* HashtableItem_new(int key, void* value);
|
|||
|
||||
Hashtable* Hashtable_new(int size, bool owner);
|
||||
|
||||
int Hashtable_hashAlgorithm(Hashtable* this, int key);
|
||||
|
||||
void Hashtable_delete(Hashtable* this);
|
||||
|
||||
inline int Hashtable_size(Hashtable* this);
|
||||
|
|
|
@ -60,7 +60,7 @@ void LoadAverageMeter_setValues(Meter* this, char* buffer, int size) {
|
|||
void LoadAverageMeter_display(Object* cast, RichString* out) {
|
||||
Meter* this = (Meter*)cast;
|
||||
char buffer[20];
|
||||
RichString_prune(out);
|
||||
RichString_init(out);
|
||||
sprintf(buffer, "%.2f ", this->values[2]);
|
||||
RichString_append(out, CRT_colors[LOAD_AVERAGE_FIFTEEN], buffer);
|
||||
sprintf(buffer, "%.2f ", this->values[1]);
|
||||
|
@ -81,7 +81,7 @@ void LoadMeter_setValues(Meter* this, char* buffer, int size) {
|
|||
void LoadMeter_display(Object* cast, RichString* out) {
|
||||
Meter* this = (Meter*)cast;
|
||||
char buffer[20];
|
||||
RichString_prune(out);
|
||||
RichString_init(out);
|
||||
sprintf(buffer, "%.2f ", ((Meter*)this)->values[0]);
|
||||
RichString_append(out, CRT_colors[LOAD], buffer);
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ void MemoryMeter_display(Object* cast, RichString* out) {
|
|||
long int usedMem = this->values[0] / div;
|
||||
long int buffersMem = this->values[1] / div;
|
||||
long int cachedMem = this->values[2] / div;
|
||||
RichString_prune(out);
|
||||
RichString_init(out);
|
||||
RichString_append(out, CRT_colors[METER_TEXT], ":");
|
||||
sprintf(buffer, format, totalMem);
|
||||
RichString_append(out, CRT_colors[METER_VALUE], buffer);
|
||||
|
|
2
Meter.c
2
Meter.c
|
@ -206,7 +206,7 @@ static inline void Meter_displayToStringBuffer(Meter* this, char* buffer) {
|
|||
if (display) {
|
||||
display((Object*)this, &Meter_stringBuffer);
|
||||
} else {
|
||||
RichString_prune(&Meter_stringBuffer);
|
||||
RichString_initVal(Meter_stringBuffer);
|
||||
RichString_append(&Meter_stringBuffer, CRT_colors[type->attributes[0]], buffer);
|
||||
}
|
||||
}
|
||||
|
|
13
Panel.c
13
Panel.c
|
@ -96,16 +96,12 @@ void Panel_init(Panel* this, int x, int y, int w, int h, char* type, bool owner)
|
|||
|
||||
void Panel_done(Panel* this) {
|
||||
assert (this != NULL);
|
||||
RichString_delete(this->header);
|
||||
Vector_delete(this->items);
|
||||
}
|
||||
|
||||
inline void Panel_setRichHeader(Panel* this, RichString header) {
|
||||
assert (this != NULL);
|
||||
|
||||
if (this->header.len > 0) {
|
||||
RichString_delete(this->header);
|
||||
}
|
||||
this->header = header;
|
||||
this->needsRedraw = true;
|
||||
}
|
||||
|
@ -274,7 +270,8 @@ void Panel_draw(Panel* this, bool focus) {
|
|||
|
||||
for(int i = first, j = 0; j < this->h && i < last; i++, j++) {
|
||||
Object* itemObj = Vector_get(this->items, i);
|
||||
RichString itemRef = RichString_new();
|
||||
RichString itemRef;
|
||||
RichString_initVal(itemRef);
|
||||
itemObj->display(itemObj, &itemRef);
|
||||
int amt = MIN(itemRef.len - scrollH, this->w);
|
||||
if (i == this->selected) {
|
||||
|
@ -296,10 +293,12 @@ void Panel_draw(Panel* this, bool focus) {
|
|||
|
||||
} else {
|
||||
Object* oldObj = Vector_get(this->items, this->oldSelected);
|
||||
RichString oldRef = RichString_new();
|
||||
RichString oldRef;
|
||||
RichString_initVal(oldRef);
|
||||
oldObj->display(oldObj, &oldRef);
|
||||
Object* newObj = Vector_get(this->items, this->selected);
|
||||
RichString newRef = RichString_new();
|
||||
RichString newRef;
|
||||
RichString_initVal(newRef);
|
||||
newObj->display(newObj, &newRef);
|
||||
mvhline(y+ this->oldSelected - this->scrollV, x+0, ' ', this->w);
|
||||
if (scrollH < oldRef.len)
|
||||
|
|
|
@ -150,7 +150,7 @@ void Process_delete(Object* cast) {
|
|||
void Process_display(Object* cast, RichString* out) {
|
||||
Process* this = (Process*) cast;
|
||||
ProcessField* fields = this->pl->fields;
|
||||
RichString_prune(out);
|
||||
RichString_init(out);
|
||||
for (int i = 0; fields[i]; i++)
|
||||
Process_writeField(this, out, fields[i]);
|
||||
if (this->pl->shadowOtherUsers && this->st_uid != getuid())
|
||||
|
|
|
@ -177,7 +177,7 @@ ProcessList* ProcessList_new(UsersTable* usersTable) {
|
|||
ProcessList* this;
|
||||
this = malloc(sizeof(ProcessList));
|
||||
this->processes = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE, Process_compare);
|
||||
this->processTable = Hashtable_new(20, false);
|
||||
this->processTable = Hashtable_new(70, false);
|
||||
this->prototype = Process_new(this);
|
||||
this->usersTable = usersTable;
|
||||
|
||||
|
@ -265,7 +265,8 @@ void ProcessList_invertSortOrder(ProcessList* this) {
|
|||
}
|
||||
|
||||
RichString ProcessList_printHeader(ProcessList* this) {
|
||||
RichString out = RichString_new();
|
||||
RichString out;
|
||||
RichString_init(&out);
|
||||
ProcessField* fields = this->fields;
|
||||
for (int i = 0; fields[i]; i++) {
|
||||
char* field = Process_printField(fields[i]);
|
||||
|
@ -505,31 +506,9 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
|
|||
process->pid = pid;
|
||||
if (! ProcessList_readStatusFile(this, process, dirname, name))
|
||||
goto errorReadingProcess;
|
||||
char* username = UsersTable_getRef(this->usersTable, process->st_uid);
|
||||
if (username) {
|
||||
strncpy(process->user, username, PROCESS_USER_LEN);
|
||||
} else {
|
||||
snprintf(process->user, PROCESS_USER_LEN, "%d", process->st_uid);
|
||||
}
|
||||
}
|
||||
process->updated = true;
|
||||
|
||||
int lasttimes = (process->utime + process->stime);
|
||||
|
||||
snprintf(statusfilename, MAX_NAME, "%s/%s/stat", dirname, name);
|
||||
|
||||
status = ProcessList_fopen(this, statusfilename, "r");
|
||||
if (status == NULL)
|
||||
goto errorReadingProcess;
|
||||
|
||||
int success = ProcessList_readStatFile(this, process, status, command);
|
||||
fclose(status);
|
||||
if(!success)
|
||||
goto errorReadingProcess;
|
||||
|
||||
process->percent_cpu = (process->utime + process->stime - lasttimes) /
|
||||
period * 100.0;
|
||||
|
||||
snprintf(statusfilename, MAX_NAME, "%s/%s/statm", dirname, name);
|
||||
status = ProcessList_fopen(this, statusfilename, "r");
|
||||
|
||||
|
@ -548,7 +527,27 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
|
|||
if (this->hideKernelThreads && process->m_size == 0)
|
||||
goto errorReadingProcess;
|
||||
|
||||
int lasttimes = (process->utime + process->stime);
|
||||
|
||||
snprintf(statusfilename, MAX_NAME, "%s/%s/stat", dirname, name);
|
||||
|
||||
status = ProcessList_fopen(this, statusfilename, "r");
|
||||
if (status == NULL)
|
||||
goto errorReadingProcess;
|
||||
|
||||
int success = ProcessList_readStatFile(this, process, status, command);
|
||||
fclose(status);
|
||||
if(!success)
|
||||
goto errorReadingProcess;
|
||||
|
||||
if(!existingProcess) {
|
||||
char* username = UsersTable_getRef(this->usersTable, process->st_uid);
|
||||
if (username) {
|
||||
strncpy(process->user, username, PROCESS_USER_LEN);
|
||||
} else {
|
||||
snprintf(process->user, PROCESS_USER_LEN, "%d", process->st_uid);
|
||||
}
|
||||
|
||||
snprintf(statusfilename, MAX_NAME, "%s/%s/cmdline", dirname, name);
|
||||
status = ProcessList_fopen(this, statusfilename, "r");
|
||||
if (!status) {
|
||||
|
@ -567,6 +566,9 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
|
|||
fclose(status);
|
||||
}
|
||||
|
||||
process->percent_cpu = (process->utime + process->stime - lasttimes) /
|
||||
period * 100.0;
|
||||
|
||||
process->percent_mem = process->m_resident /
|
||||
(float)(this->usedMem - this->cachedMem - this->buffersMem) *
|
||||
100.0;
|
||||
|
|
51
RichString.c
51
RichString.c
|
@ -12,6 +12,9 @@
|
|||
|
||||
/*{
|
||||
|
||||
#define RichString_init(this) (this)->len = 0
|
||||
#define RichString_initVal(this) (this).len = 0
|
||||
|
||||
typedef struct RichString_ {
|
||||
int len;
|
||||
chtype chstr[RICHSTRING_MAXLEN+1];
|
||||
|
@ -23,23 +26,8 @@ typedef struct RichString_ {
|
|||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
#endif
|
||||
|
||||
static WINDOW* workArea = NULL;
|
||||
|
||||
RichString RichString_new() {
|
||||
RichString this;
|
||||
this.len = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
void RichString_delete(RichString this) {
|
||||
}
|
||||
|
||||
void RichString_prune(RichString* this) {
|
||||
this->len = 0;
|
||||
}
|
||||
|
||||
void RichString_write(RichString* this, int attrs, char* data) {
|
||||
this->len = 0;
|
||||
RichString_init(this);
|
||||
RichString_append(this, attrs, data);
|
||||
}
|
||||
|
||||
|
@ -48,35 +36,32 @@ inline void RichString_append(RichString* this, int attrs, char* data) {
|
|||
}
|
||||
|
||||
inline void RichString_appendn(RichString* this, int attrs, char* data, int len) {
|
||||
if (!workArea) {
|
||||
workArea = newpad(1, RICHSTRING_MAXLEN);
|
||||
}
|
||||
assert(workArea);
|
||||
wattrset(workArea, attrs);
|
||||
int maxToWrite = (RICHSTRING_MAXLEN - 1) - this->len;
|
||||
int wrote = MIN(maxToWrite, len);
|
||||
mvwaddnstr(workArea, 0, 0, data, maxToWrite);
|
||||
int oldstrlen = this->len;
|
||||
this->len += wrote;
|
||||
mvwinchnstr(workArea, 0, 0, this->chstr + oldstrlen, wrote);
|
||||
wattroff(workArea, attrs);
|
||||
int last = MIN(RICHSTRING_MAXLEN - 1, len + this->len);
|
||||
for (int i = this->len, j = 0; i < last; i++, j++)
|
||||
this->chstr[i] = data[j] | attrs;
|
||||
this->chstr[last] = 0;
|
||||
this->len = last;
|
||||
}
|
||||
|
||||
void RichString_setAttr(RichString *this, int attrs) {
|
||||
chtype* ch = this->chstr;
|
||||
for (int i = 0; i < this->len; i++) {
|
||||
char c = this->chstr[i];
|
||||
this->chstr[i] = c | attrs;
|
||||
*ch = (*ch & 0xff) | attrs;
|
||||
ch++;
|
||||
}
|
||||
}
|
||||
|
||||
void RichString_applyAttr(RichString *this, int attrs) {
|
||||
for (int i = 0; i < this->len - 1; i++) {
|
||||
this->chstr[i] |= attrs;
|
||||
chtype* ch = this->chstr;
|
||||
for (int i = 0; i < this->len; i++) {
|
||||
*ch |= attrs;
|
||||
ch++;
|
||||
}
|
||||
}
|
||||
|
||||
RichString RichString_quickString(int attrs, char* data) {
|
||||
RichString str = RichString_new();
|
||||
RichString str;
|
||||
RichString_initVal(str);
|
||||
RichString_write(&str, attrs, data);
|
||||
return str;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
#define RICHSTRING_MAXLEN 300
|
||||
|
||||
|
||||
#define RichString_init(this) (this)->len = 0
|
||||
#define RichString_initVal(this) (this).len = 0
|
||||
|
||||
typedef struct RichString_ {
|
||||
int len;
|
||||
chtype chstr[RICHSTRING_MAXLEN+1];
|
||||
|
@ -24,12 +27,6 @@ typedef struct RichString_ {
|
|||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
#endif
|
||||
|
||||
RichString RichString_new();
|
||||
|
||||
void RichString_delete(RichString this);
|
||||
|
||||
void RichString_prune(RichString* this);
|
||||
|
||||
void RichString_write(RichString* this, int attrs, char* data);
|
||||
|
||||
inline void RichString_append(RichString* this, int attrs, char* data);
|
||||
|
|
|
@ -46,7 +46,7 @@ void SwapMeter_display(Object* cast, RichString* out) {
|
|||
char buffer[50];
|
||||
Meter* this = (Meter*)cast;
|
||||
long int swap = (long int) this->values[0];
|
||||
RichString_prune(out);
|
||||
RichString_init(out);
|
||||
RichString_append(out, CRT_colors[METER_TEXT], ":");
|
||||
sprintf(buffer, "%ldM ", (long int) this->total / 1024);
|
||||
RichString_append(out, CRT_colors[METER_VALUE], buffer);
|
||||
|
|
|
@ -38,7 +38,7 @@ void TasksMeter_setValues(Meter* this, char* buffer, int len) {
|
|||
|
||||
void TasksMeter_display(Object* cast, RichString* out) {
|
||||
Meter* this = (Meter*)cast;
|
||||
RichString_prune(out);
|
||||
RichString_init(out);
|
||||
char buffer[20];
|
||||
sprintf(buffer, "%d", (int)this->total);
|
||||
RichString_append(out, CRT_colors[METER_VALUE], buffer);
|
||||
|
|
Loading…
Reference in New Issue