summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2006-07-11 06:13:32 +0000
committerHisham Muhammad <hisham@gobolinux.org>2006-07-11 06:13:32 +0000
commit5d48ab8c28925f892e8e7f432f7d2b78c86e95c5 (patch)
tree13a209d132be00e28d24f9ce750a873055cfbd98
parent4c41e78bbfe34c67db16bbce8e0241ba583e8572 (diff)
Performance improvement hackathon: improve process comparison routines,
disable useless code in release builds such as runtime type-checking on dynamic data structures and process fields that are not being computed, faster(?) method for verifying the process owner (still need to ensure correctness), don't destroy and create process objects for hidden kernel threads over and over. Phew. I shouldn't be doing all this today, but I could not resist.
-rw-r--r--ChangeLog4
-rw-r--r--CheckItem.c6
-rw-r--r--CheckItem.h4
-rw-r--r--FunctionBar.c6
-rw-r--r--FunctionBar.h4
-rw-r--r--Hashtable.c9
-rw-r--r--Hashtable.h2
-rw-r--r--Header.c4
-rw-r--r--ListItem.c9
-rw-r--r--ListItem.h6
-rw-r--r--Makefile.am3
-rw-r--r--Meter.c10
-rw-r--r--Meter.h5
-rw-r--r--Object.c36
-rw-r--r--Object.h23
-rw-r--r--Panel.c13
-rw-r--r--Panel.h7
-rw-r--r--Process.c68
-rw-r--r--Process.h12
-rw-r--r--ProcessList.c140
-rw-r--r--ProcessList.h7
-rw-r--r--ScreenManager.c6
-rw-r--r--SignalItem.c6
-rw-r--r--SignalItem.h4
-rw-r--r--String.c8
-rw-r--r--String.h4
-rw-r--r--TraceScreen.c2
-rw-r--r--Vector.c39
-rw-r--r--Vector.h9
-rw-r--r--htop.c6
30 files changed, 302 insertions, 160 deletions
diff --git a/ChangeLog b/ChangeLog
index 2fe7fb80..e5670533 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,12 @@
What's new in version 0.6.3
+* Performance improvements; uses much less CPU than the
+ previous release with the default setup.
* Use 64-bit values when storing processor times to
avoid overflow.
+* Memory consumption improvements, compensating storage
+ of 64-bit values.
* Internal change: rename TypedVector to Vector and
ListBox (and related classes) to Panel.
diff --git a/CheckItem.c b/CheckItem.c
index 73148f32..83261237 100644
--- a/CheckItem.c
+++ b/CheckItem.c
@@ -21,11 +21,15 @@ typedef struct CheckItem_ {
}*/
+#ifdef DEBUG
char* CHECKITEM_CLASS = "CheckItem";
+#else
+#define CHECKITEM_CLASS NULL
+#endif
CheckItem* CheckItem_new(char* text, bool* value) {
CheckItem* this = malloc(sizeof(CheckItem));
- ((Object*)this)->class = CHECKITEM_CLASS;
+ Object_setClass(this, CHECKITEM_CLASS);
((Object*)this)->display = CheckItem_display;
((Object*)this)->delete = CheckItem_delete;
this->text = text;
diff --git a/CheckItem.h b/CheckItem.h
index eaf43ba6..e1ad4c9b 100644
--- a/CheckItem.h
+++ b/CheckItem.h
@@ -22,7 +22,11 @@ typedef struct CheckItem_ {
} CheckItem;
+#ifdef DEBUG
extern char* CHECKITEM_CLASS;
+#else
+#define CHECKITEM_CLASS NULL
+#endif
CheckItem* CheckItem_new(char* text, bool* value);
diff --git a/FunctionBar.c b/FunctionBar.c
index 7764136c..1140267b 100644
--- a/FunctionBar.c
+++ b/FunctionBar.c
@@ -30,7 +30,11 @@ typedef struct FunctionBar_ {
}*/
+#ifdef DEBUG
char* FUNCTIONBAR_CLASS = "FunctionBar";
+#else
+#define FUNCTIONBAR_CLASS NULL
+#endif
static char* FunctionBar_FKeys[10] = {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10"};
@@ -40,7 +44,7 @@ static int FunctionBar_FEvents[10] = {KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KE
FunctionBar* FunctionBar_new(int size, char** functions, char** keys, int* events) {
FunctionBar* this = malloc(sizeof(FunctionBar));
- ((Object*) this)->class = FUNCTIONBAR_CLASS;
+ Object_setClass(this, FUNCTIONBAR_CLASS);
((Object*) this)->delete = FunctionBar_delete;
this->functions = functions;
this->size = size;
diff --git a/FunctionBar.h b/FunctionBar.h
index 2998cf7a..dfdef606 100644
--- a/FunctionBar.h
+++ b/FunctionBar.h
@@ -31,7 +31,11 @@ typedef struct FunctionBar_ {
} FunctionBar;
+#ifdef DEBUG
extern char* FUNCTIONBAR_CLASS;
+#else
+#define FUNCTIONBAR_CLASS NULL
+#endif
FunctionBar* FunctionBar_new(int size, char** functions, char** keys, int* events);
diff --git a/Hashtable.c b/Hashtable.c
index 759cbef7..f971c8c2 100644
--- a/Hashtable.c
+++ b/Hashtable.c
@@ -55,7 +55,7 @@ Hashtable* Hashtable_new(int size, bool owner) {
}
int Hashtable_hashAlgorithm(Hashtable* this, int key) {
- return (key % this->size);
+ return key % this->size;
}
void Hashtable_delete(Hashtable* this) {
@@ -116,17 +116,20 @@ void* Hashtable_remove(Hashtable* this, int key) {
} else
bucketPtr = &((*bucketPtr)->next);
}
-
+//#include <stdio.h>
inline void* Hashtable_get(Hashtable* this, int key) {
int index = this->hashAlgorithm(this, key);
HashtableItem* bucketPtr = this->buckets[index];
- while (true)
+ // fprintf(stderr, "%d -> %d\n", key, index);
+ while (true) {
if (bucketPtr == NULL) {
return NULL;
} else if (bucketPtr->key == key) {
return bucketPtr->value;
} else
bucketPtr = bucketPtr->next;
+ // fprintf(stderr, "*\n");
+ }
}
void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData) {
diff --git a/Hashtable.h b/Hashtable.h
index 99e06d1b..a5f2434d 100644
--- a/Hashtable.h
+++ b/Hashtable.h
@@ -47,7 +47,7 @@ inline int Hashtable_size(Hashtable* this);
void Hashtable_put(Hashtable* this, int key, void* value);
void* Hashtable_remove(Hashtable* this, int key);
-
+//#include <stdio.h>
inline void* Hashtable_get(Hashtable* this, int key);
void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData);
diff --git a/Header.c b/Header.c
index ddd35e81..b55b557b 100644
--- a/Header.c
+++ b/Header.c
@@ -35,8 +35,8 @@ typedef struct Header_ {
Header* Header_new(ProcessList* pl) {
Header* this = malloc(sizeof(Header));
- this->leftMeters = Vector_new(METER_CLASS, true, DEFAULT_SIZE);
- this->rightMeters = Vector_new(METER_CLASS, true, DEFAULT_SIZE);
+ this->leftMeters = Vector_new(METER_CLASS, true, DEFAULT_SIZE, NULL);
+ this->rightMeters = Vector_new(METER_CLASS, true, DEFAULT_SIZE, NULL);
this->margin = true;
this->pl = pl;
return this;
diff --git a/ListItem.c b/ListItem.c
index 13d94d00..90107e4b 100644
--- a/ListItem.c
+++ b/ListItem.c
@@ -23,14 +23,17 @@ typedef struct ListItem_ {
}*/
+#ifdef DEBUG
char* LISTITEM_CLASS = "ListItem";
+#else
+#define LISTITEM_CLASS NULL
+#endif
ListItem* ListItem_new(char* value, int key) {
ListItem* this = malloc(sizeof(ListItem));
- ((Object*)this)->class = LISTITEM_CLASS;
+ Object_setClass(this, LISTITEM_CLASS);
((Object*)this)->display = ListItem_display;
((Object*)this)->delete = ListItem_delete;
- ((Object*)this)->compare = ListItem_compare;
this->value = String_copy(value);
this->key = key;
return this;
@@ -62,7 +65,7 @@ const char* ListItem_getRef(ListItem* this) {
return this->value;
}
-int ListItem_compare(const Object* cast1, const Object* cast2) {
+int ListItem_compare(const void* cast1, const void* cast2) {
ListItem* obj1 = (ListItem*) cast1;
ListItem* obj2 = (ListItem*) cast2;
return strcmp(obj1->value, obj2->value);
diff --git a/ListItem.h b/ListItem.h
index 84d01027..a58db3a3 100644
--- a/ListItem.h
+++ b/ListItem.h
@@ -24,7 +24,11 @@ typedef struct ListItem_ {
} ListItem;
+#ifdef DEBUG
extern char* LISTITEM_CLASS;
+#else
+#define LISTITEM_CLASS NULL
+#endif
ListItem* ListItem_new(char* value, int key);
@@ -36,7 +40,7 @@ void ListItem_display(Object* cast, RichString* out);
const char* ListItem_getRef(ListItem* this);
-int ListItem_compare(const Object* cast1, const Object* cast2);
+int ListItem_compare(const void* cast1, const void* cast2);
#endif
diff --git a/Makefile.am b/Makefile.am
index ccaa95fc..3cc4d916 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -27,6 +27,9 @@ ColorsPanel.c ColorsPanel.h TraceScreen.c TraceScreen.h \
AvailableColumnsPanel.c AvailableColumnsPanel.h ColumnsPanel.c \
ColumnsPanel.h
+profile:
+ $(MAKE) all CFLAGS="-pg -O2"
+
debug:
$(MAKE) all CFLAGS="-g -DDEBUG"
diff --git a/Meter.c b/Meter.c
index 437dd681..1d447f87 100644
--- a/Meter.c
+++ b/Meter.c
@@ -104,7 +104,11 @@ typedef enum {
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
+#ifdef DEBUG
char* METER_CLASS = "Meter";
+#else
+#define METER_CLASS NULL
+#endif
MeterType* Meter_types[] = {
&CPUMeter,
@@ -162,6 +166,9 @@ static RichString Meter_stringBuffer;
Meter* Meter_new(ProcessList* pl, int param, MeterType* type) {
Meter* this = calloc(sizeof(Meter), 1);
+ Object_setClass(this, METER_CLASS);
+ ((Object*)this)->delete = Meter_delete;
+ ((Object*)this)->display = type->display;
this->h = 1;
this->type = type;
this->param = param;
@@ -169,9 +176,6 @@ Meter* Meter_new(ProcessList* pl, int param, MeterType* type) {
this->values = calloc(sizeof(double), type->items);
this->total = type->total;
this->caption = strdup(type->caption);
- ((Object*)this)->delete = Meter_delete;
- ((Object*)this)->class = METER_CLASS;
- ((Object*)this)->display = type->display;
Meter_setMode(this, type->mode);
if (this->type->init)
this->type->init(this);
diff --git a/Meter.h b/Meter.h
index c8cb703d..e564d3c3 100644
--- a/Meter.h
+++ b/Meter.h
@@ -96,6 +96,7 @@ typedef enum {
#include "TasksMeter.h"
#include "LoadAverageMeter.h"
#include "UptimeMeter.h"
+#include "ClockMeter.h"
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
@@ -104,7 +105,11 @@ typedef enum {
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
+#ifdef DEBUG
extern char* METER_CLASS;
+#else
+#define METER_CLASS NULL
+#endif
extern MeterType* Meter_types[];
diff --git a/Object.c b/Object.c
index 62a1c3a3..15b9a6ec 100644
--- a/Object.c
+++ b/Object.c
@@ -15,37 +15,37 @@ in the source distribution for its full text.
#include "debug.h"
/*{
+
+#ifndef DEBUG
+#define Object_setClass(obj, class)
+#endif
+
typedef struct Object_ Object;
typedef void(*Object_Display)(Object*, RichString*);
-typedef int(*Object_Compare)(const Object*, const Object*);
+typedef int(*Object_Compare)(const void*, const void*);
typedef void(*Object_Delete)(Object*);
struct Object_ {
+ #ifdef DEBUG
char* class;
+ #endif
Object_Display display;
- Object_Compare compare;
Object_Delete delete;
};
}*/
-static char* OBJECT_CLASS = "Object";
+#ifdef DEBUG
+char* OBJECT_CLASS = "Object";
-void Object_new() {
- Object* this;
- this = malloc(sizeof(Object));
- this->class = OBJECT_CLASS;
- this->display = Object_display;
- this->compare = Object_compare;
- this->delete = Object_delete;
-}
+#else
+#define OBJECT_CLASS NULL
+#endif
-bool Object_instanceOf(Object* this, char* class) {
- return this->class == class;
-}
+#ifdef DEBUG
-void Object_delete(Object* this) {
- free(this);
+void Object_setClass(void* this, char* class) {
+ ((Object*)this)->class = class;
}
void Object_display(Object* this, RichString* out) {
@@ -54,6 +54,4 @@ void Object_display(Object* this, RichString* out) {
RichString_write(out, CRT_colors[DEFAULT_COLOR], objAddress);
}
-int Object_compare(const Object* this, const Object* o) {
- return (this - o);
-}
+#endif
diff --git a/Object.h b/Object.h
index b4c3dffb..f8a8c6d2 100644
--- a/Object.h
+++ b/Object.h
@@ -17,27 +17,38 @@ in the source distribution for its full text.
#include "debug.h"
+
+#ifndef DEBUG
+#define Object_setClass(obj, class)
+#endif
+
typedef struct Object_ Object;
typedef void(*Object_Display)(Object*, RichString*);
-typedef int(*Object_Compare)(const Object*, const Object*);
+typedef int(*Object_Compare)(const void*, const void*);
typedef void(*Object_Delete)(Object*);
struct Object_ {
+ #ifdef DEBUG
char* class;
+ #endif
Object_Display display;
- Object_Compare compare;
Object_Delete delete;
};
-void Object_new();
+#ifdef DEBUG
+extern char* OBJECT_CLASS;
-bool Object_instanceOf(Object* this, char* class);
+#else
+#define OBJECT_CLASS NULL
+#endif
+
+#ifdef DEBUG
-void Object_delete(Object* this);
+void Object_setClass(void* this, char* class);
void Object_display(Object* this, RichString* out);
-int Object_compare(const Object* this, const Object* o);
+#endif
#endif
diff --git a/Panel.c b/Panel.c
index 081306cf..fef7018b 100644
--- a/Panel.c
+++ b/Panel.c
@@ -10,6 +10,7 @@ in the source distribution for its full text.
#include "Vector.h"
#include "CRT.h"
#include "RichString.h"
+#include "ListItem.h"
#include <math.h>
#include <stdbool.h>
@@ -54,12 +55,18 @@ struct Panel_ {
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
+#ifdef DEBUG
char* PANEL_CLASS = "Panel";
+#else
+#define PANEL_CLASS NULL
+#endif
+
-Panel* Panel_new(int x, int y, int w, int h, char* type, bool owner) {
+Panel* Panel_new(int x, int y, int w, int h, char* type, bool owner, Object_Compare compare) {
Panel* this;
this = malloc(sizeof(Panel));
Panel_init(this, x, y, w, h, type, owner);
+ this->items->compare = compare;
return this;
}
@@ -71,14 +78,14 @@ void Panel_delete(Object* cast) {
void Panel_init(Panel* this, int x, int y, int w, int h, char* type, bool owner) {
Object* super = (Object*) this;
- super->class = PANEL_CLASS;
+ Object_setClass(this, PANEL_CLASS);
super->delete = Panel_delete;
this->x = x;
this->y = y;
this->w = w;
this->h = h;
this->eventHandler = NULL;
- this->items = Vector_new(type, owner, DEFAULT_SIZE);
+ this->items = Vector_new(type, owner, DEFAULT_SIZE, ListItem_compare);
this->scrollV = 0;
this->scrollH = 0;
this->selected = 0;
diff --git a/Panel.h b/Panel.h
index 4b96fe48..eda9c85d 100644
--- a/Panel.h
+++ b/Panel.h
@@ -55,9 +55,14 @@ struct Panel_ {
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
+#ifdef DEBUG
extern char* PANEL_CLASS;
+#else
+#define PANEL_CLASS NULL
+#endif
+
-Panel* Panel_new(int x, int y, int w, int h, char* type, bool owner);
+Panel* Panel_new(int x, int y, int w, int h, char* type, bool owner, Object_Compare compare);
void Panel_delete(Object* cast);
diff --git a/Process.c b/Process.c
index a97d5d13..7707a1a1 100644
--- a/Process.c
+++ b/Process.c
@@ -62,16 +62,19 @@ typedef struct Process_ {
int tty_nr;
int tpgid;
unsigned long int flags;
+ #ifdef DEBUG
unsigned long int minflt;
unsigned long int cminflt;
unsigned long int majflt;
unsigned long int cmajflt;
+ #endif
unsigned long int utime;
unsigned long int stime;
long int cutime;
long int cstime;
long int priority;
long int nice;
+ #ifdef DEBUG
long int itrealvalue;
unsigned long int starttime;
unsigned long int vsize;
@@ -89,6 +92,7 @@ typedef struct Process_ {
unsigned long int wchan;
unsigned long int nswap;
unsigned long int cnswap;
+ #endif
int exit_signal;
int processor;
int m_size;
@@ -106,7 +110,11 @@ typedef struct Process_ {
}*/
+#ifdef DEBUG
char* PROCESS_CLASS = "Process";
+#else
+#define PROCESS_CLASS NULL
+#endif
char *Process_fieldNames[] = {
"", "PID", "Command", "STATE", "PPID", "PGRP", "SESSION", "TTY_NR", "TPGID", "FLAGS", "MINFLT", "CMINFLT", "MAJFLT", "CMAJFLT", "UTIME", "STIME", "CUTIME", "CSTIME", "PRIORITY", "NICE", "ITREALVALUE", "STARTTIME", "VSIZE", "RSS", "RLIM", "STARTCODE", "ENDCODE", "STARTSTACK", "KSTKESP", "KSTKEIP", "SIGNAL", "BLOCKED", "SIGIGNORE", "SIGCATCH", "WCHAN", "NSWAP", "CNSWAP", "EXIT_SIGNAL", "PROCESSOR", "M_SIZE", "M_RESIDENT", "M_SHARE", "M_TRS", "M_DRS", "M_LRS", "M_DT", "ST_UID", "PERCENT_CPU", "PERCENT_MEM", "USER", "TIME", "*** report bug! ***"
@@ -114,9 +122,8 @@ char *Process_fieldNames[] = {
Process* Process_new(struct ProcessList_ *pl) {
Process* this = malloc(sizeof(Process));
- ((Object*)this)->class = PROCESS_CLASS;
+ Object_setClass(this, PROCESS_CLASS);
((Object*)this)->display = Process_display;
- ((Object*)this)->compare = Process_compare;
((Object*)this)->delete = Process_delete;
this->pl = pl;
this->tag = false;
@@ -265,21 +272,21 @@ void Process_writeField(Process* this, RichString* str, ProcessField field) {
for (int i = 0; i < 32; i++)
if (this->indent & (1 << i))
maxIndent = i+1;
- for (int i = 0; i < maxIndent - 1; i++) {
+ for (int i = 0; i < maxIndent - 1; i++) {
if (this->indent & (1 << i))
snprintf(buf, n, " | ");
else
snprintf(buf, n, " ");
buf += 4;
n -= 4;
- }
+ }
if (this->pl->direction == 1)
snprintf(buf, n, " `- ");
else
snprintf(buf, n, " ,- ");
RichString_append(str, CRT_colors[PROCESS_TREE], buffer);
Process_writeCommand(this, attr, str);
- return;
+ return;
}
}
case STATE: {
@@ -345,44 +352,57 @@ void Process_writeField(Process* this, RichString* str, ProcessField field) {
return;
}
-int Process_compare(const Object* v1, const Object* v2) {
+int Process_pidCompare(const void* v1, const void* v2) {
Process* p1 = (Process*)v1;
Process* p2 = (Process*)v2;
- int direction = p1->pl->direction;
- switch (p1->pl->sortKey) {
+ return (p1->pid - p2->pid);
+}
+
+int Process_compare(const void* v1, const void* v2) {
+ Process *p1, *p2;
+ ProcessList *pl = ((Process*)v1)->pl;
+ if (pl->direction == 1) {
+ p1 = (Process*)v1;
+ p2 = (Process*)v2;
+ } else {
+ p2 = (Process*)v1;
+ p1 = (Process*)v2;
+ }
+ switch (pl->sortKey) {
case PID:
- return (p2->pid - p1->pid) * direction;
+ return (p1->pid - p2->pid);
case PPID:
- return (p2->ppid - p1->ppid) * direction;
+ return (p1->ppid - p2->ppid);
case USER:
- return strcmp(p2->user, p1->user) * direction;
+ return strcmp(p1->user, p2->user);
case PRIORITY:
- return (p2->priority - p1->priority) * direction;
+ return (p1->priority - p2->priority);
case STATE:
- return (p2->state - p1->state) * direction;
+ return (p1->state - p2->state);
case NICE:
- return (p2->nice - p1->nice) * direction;
+ return (p1->nice - p2->nice);
case M_SIZE:
- return (p1->m_size - p2->m_size) * direction;
+ return (p2->m_size - p1->m_size);
case M_RESIDENT:
- return (p1->m_resident - p2->m_resident) * direction;
+ return (p2->m_resident - p1->m_resident);
case M_SHARE:
- return (p1->m_share - p2->m_share) * direction;
+ return (p2->m_share - p1->m_share);
case PERCENT_CPU:
- return (p1->percent_cpu < p2->percent_cpu ? -1 : 1) * direction;
+ return (p2->percent_cpu > p1->percent_cpu ? 1 : -1);
case PERCENT_MEM:
- return (p1->percent_mem < p2->percent_mem ? -1 : 1) * direction;
+ return (p2->m_resident - p1->m_resident);
case UTIME:
- return (p1->utime - p2->utime) * direction;
+ return (p2->utime - p1->utime);
case STIME:
- return (p1->stime - p2->stime) * direction;
+ return (p2->stime - p1->stime);
case TIME:
- return ((p1->utime+p1->stime) - (p2->utime+p2->stime)) * direction;
+ return ((p2->utime+p2->stime) - (p1->utime+p1->stime));
case COMM:
- return strcmp(p2->comm, p1->comm) * direction;
+ return strcmp(p1->comm, p2->comm);
default:
- return (p2->pid - p1->pid) * direction;
+ return (p1->pid - p2->pid);
}
+
}
char* Process_printField(ProcessField field) {
diff --git a/Process.h b/Process.h
index 51b11d9a..680b0d4a 100644
--- a/Process.h
+++ b/Process.h
@@ -64,16 +64,19 @@ typedef struct Process_ {
int tty_nr;
int tpgid;
unsigned long int flags;
+ #ifdef DEBUG
unsigned long int minflt;
unsigned long int cminflt;
unsigned long int majflt;
unsigned long int cmajflt;
+ #endif
unsigned long int utime;
unsigned long int stime;
long int cutime;
long int cstime;
long int priority;
long int nice;
+ #ifdef DEBUG
long int itrealvalue;
unsigned long int starttime;
unsigned long int vsize;
@@ -91,6 +94,7 @@ typedef struct Process_ {
unsigned long int wchan;
unsigned long int nswap;
unsigned long int cnswap;
+ #endif
int exit_signal;
int processor;
int m_size;
@@ -107,7 +111,11 @@ typedef struct Process_ {
} Process;
+#ifdef DEBUG
extern char* PROCESS_CLASS;
+#else
+#define PROCESS_CLASS NULL
+#endif
extern char *Process_fieldNames[];
@@ -131,7 +139,9 @@ void Process_sendSignal(Process* this, int signal);
void Process_writeField(Process* this, RichString* str, ProcessField field);
-int Process_compare(const Object* v1, const Object* v2);
+int Process_pidCompare(const void* v1, const void* v2);
+
+int Process_compare(const void* v1, const void* v2);
char* Process_printField(ProcessField field);
diff --git a/ProcessList.c b/ProcessList.c
index fb7f8e9d..d6984568 100644
--- a/ProcessList.c
+++ b/ProcessList.c
@@ -15,6 +15,7 @@ in the source distribution for its full text.
#include "Vector.h"
#include "UsersTable.h"
#include "Hashtable.h"
+#include "String.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -48,13 +49,17 @@ in the source distribution for its full text.
#endif
#ifndef MAX_READ
-#define MAX_READ 8192
+#define MAX_READ 2048
#endif
}*/
/*{
+#ifdef DEBUG
+typedef int(*vxscanf)(void*, const char*, va_list);
+#endif
+
typedef struct ProcessList_ {
Vector* processes;
Vector* processes2;
@@ -108,8 +113,6 @@ static ProcessField defaultHeaders[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RE
#ifdef DEBUG
-typedef int(*vxscanf)(void*, const char*, va_list);
-
#define ProcessList_read(this, buffer, format, ...) ProcessList_xread(this, (vxscanf) vsscanf, buffer, format, ## __VA_ARGS__ )
#define ProcessList_fread(this, file, format, ...) ProcessList_xread(this, (vxscanf) vfscanf, file, format, ## __VA_ARGS__ )
@@ -173,13 +176,13 @@ static inline int ProcessList_xread(ProcessList* this, vxscanf fn, void* buffer,
ProcessList* ProcessList_new(UsersTable* usersTable) {
ProcessList* this;
this = malloc(sizeof(ProcessList));
- this->processes = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE);
+ this->processes = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE, Process_compare);
this->processTable = Hashtable_new(20, false);
this->prototype = Process_new(this);
this->usersTable = usersTable;
/* tree-view auxiliary buffers */
- this->processes2 = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE);
+ this->processes2 = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE, Process_compare);
#ifdef DEBUG
this->traceFile = fopen("/tmp/htop-proc-trace", "w");
@@ -286,11 +289,8 @@ void ProcessList_add(ProcessList* this, Process* p) {
void ProcessList_remove(ProcessList* this, Process* p) {
Hashtable_remove(this->processTable, p->pid);
- ProcessField pf = this->sortKey;
- this->sortKey = PID;
- int index = Vector_indexOf(this->processes, p);
+ int index = Vector_indexOf(this->processes, p, Process_pidCompare);
Vector_remove(this->processes, index);
- this->sortKey = pf;
}
Process* ProcessList_get(ProcessList* this, int index) {
@@ -302,7 +302,7 @@ int ProcessList_size(ProcessList* this) {
}
static void ProcessList_buildTree(ProcessList* this, int pid, int level, int indent, int direction) {
- Vector* children = Vector_new(PROCESS_CLASS, false, DEFAULT_SIZE);
+ Vector* children = Vector_new(PROCESS_CLASS, false, DEFAULT_SIZE, Process_compare);
for (int i = 0; i < Vector_size(this->processes); i++) {
Process* process = (Process*) (Vector_get(this->processes, i));
@@ -352,7 +352,7 @@ void ProcessList_sort(ProcessList* this) {
static int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, char *command) {
static char buf[MAX_READ];
- long int zero;
+ unsigned long int zero;
int size = fread(buf, 1, MAX_READ, f);
if(!size) return 0;
@@ -370,6 +370,7 @@ static int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, c
command[commsize] = '\0';
location = end + 2;
+ #ifdef DEBUG
int num = ProcessList_read(this, location,
"%c %d %d %d %d %d %lu %lu %lu %lu "
"%lu %lu %lu %ld %ld %ld %ld %ld %ld "
@@ -377,14 +378,34 @@ static int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, c
"%lu %lu %lu %lu %lu %lu %lu %lu "
"%d %d",
&proc->state, &proc->ppid, &proc->pgrp, &proc->session, &proc->tty_nr,
- &proc->tpgid, &proc->flags, &proc->minflt, &proc->cminflt, &proc->majflt,
- &proc->cmajflt, &proc->utime, &proc->stime, &proc->cutime, &proc->cstime,
+ &proc->tpgid, &proc->flags,
+ &proc->minflt, &proc->cminflt, &proc->majflt, &proc->cmajflt,
+ &proc->utime, &proc->stime, &proc->cutime, &proc->cstime,
&proc->priority, &proc->nice, &zero, &proc->itrealvalue,
&proc->starttime, &proc->vsize, &proc->rss, &proc->rlim,
&proc->startcode, &proc->endcode, &proc->startstack, &proc->kstkesp,
&proc->kstkeip, &proc->signal, &proc->blocked, &proc->sigignore,
&proc->sigcatch, &proc->wchan, &proc->nswap, &proc->cnswap,
&proc->exit_signal, &proc->processor);
+ #else
+ long int uzero;
+ int num = ProcessList_read(this, location,
+ "%c %d %d %d %d %d %lu %lu %lu %lu "
+ "%lu %lu %lu %ld %ld %ld %ld %ld %ld "
+ "%lu %lu %ld %lu %lu %lu %lu %lu "
+ "%lu %lu %lu %lu %lu %lu %lu %lu "
+ "%d %d",
+ &proc->state, &proc->ppid, &proc->pgrp, &proc->session, &proc->tty_nr,
+ &proc->tpgid, &proc->flags,
+ &zero, &zero, &zero, &zero,
+ &proc->utime, &proc->stime, &proc->cutime, &proc->cstime,
+ &proc->priority, &proc->nice, &uzero, &uzero,
+ &zero, &zero, &uzero, &zero,
+ &zero, &zero, &zero, &zero,
+ &zero, &zero, &zero, &zero,
+ &zero, &zero, &zero, &zero,
+ &proc->exit_signal, &proc->processor);
+ #endif
// This assert is always valid on 2.4, but reportedly not always valid on 2.6.
// TODO: Check if the semantics of this field has changed.
@@ -397,14 +418,15 @@ static int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, c
bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* dirname, char* name) {
char statusfilename[MAX_NAME+1];
statusfilename[MAX_NAME] = '\0';
+ /*
+ bool success = false;
+ char buffer[256];
+ buffer[255] = '\0';
snprintf(statusfilename, MAX_NAME, "%s/%s/status", dirname, name);
FILE* status = ProcessList_fopen(this, statusfilename, "r");
- bool success = false;
if (status) {
- char buffer[1024];
- buffer[1023] = '\0';
while (!feof(status)) {
- char* ok = fgets(buffer, 1023, status);
+ char* ok = fgets(buffer, 255, status);
if (!ok)
break;
if (String_startsWith(buffer, "Uid:")) {
@@ -421,14 +443,18 @@ bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* dirname,
fclose(status);
}
if (!success) {
- snprintf(statusfilename, MAX_NAME, "%s/%s/stat", dirname, name);
+ */
+ snprintf(statusfilename, MAX_NAME, "%s/%s", dirname, name);
struct stat sstat;
int statok = stat(statusfilename, &sstat);
if (statok == -1)
return false;
proc->st_uid = sstat.st_uid;
- }
- return success;
+ return true;
+ /*
+ } else
+ return true;
+ */
}
void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, float period) {
@@ -469,25 +495,25 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
char command[PROCESS_COMM_LEN + 1];
Process* process;
+
Process* existingProcess = (Process*) Hashtable_get(this->processTable, pid);
- if (!existingProcess) {
- process = Process_clone(prototype);
+ if (existingProcess) {
+ process = existingProcess;
+ } else {
+ process = prototype;
+ process->comm = NULL;
process->pid = pid;
- ProcessList_add(this, process);
if (! ProcessList_readStatusFile(this, process, dirname, name))
goto errorReadingProcess;
- } else {
- process = 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);
+ }
}
process->updated = true;
- 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);
- }
-
int lasttimes = (process->utime + process->stime);
snprintf(statusfilename, MAX_NAME, "%s/%s/stat", dirname, name);
@@ -498,13 +524,30 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
int success = ProcessList_readStatFile(this, process, status, command);
fclose(status);
- if(!success) {
+ 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");
+
+ if(!status) {
+ goto errorReadingProcess;
+ }
+ int num = ProcessList_fread(this, status, "%d %d %d %d %d %d %d",
+ &process->m_size, &process->m_resident, &process->m_share,
+ &process->m_trs, &process->m_drs, &process->m_lrs,
+ &process->m_dt);
+
+ fclose(status);
+ if(num != 7)
+ goto errorReadingProcess;
+
+ if (this->hideKernelThreads && process->m_size == 0)
+ goto errorReadingProcess;
+
if(!existingProcess) {
snprintf(statusfilename, MAX_NAME, "%s/%s/cmdline", dirname, name);
status = ProcessList_fopen(this, statusfilename, "r");
@@ -524,21 +567,6 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
fclose(status);
}
- snprintf(statusfilename, MAX_NAME, "%s/%s/statm", dirname, name);
- status = ProcessList_fopen(this, statusfilename, "r");
-
- if(!status) {
- goto errorReadingProcess;
- }
- int num = ProcessList_fread(this, status, "%d %d %d %d %d %d %d",
- &process->m_size, &process->m_resident, &process->m_share,
- &process->m_trs, &process->m_drs, &process->m_lrs,
- &process->m_dt);
-
- fclose(status);
- if(num != 7)
- goto errorReadingProcess;
-
process->percent_mem = process->m_resident /
(float)(this->usedMem - this->cachedMem - this->buffersMem) *
100.0;
@@ -548,17 +576,25 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
this->runningTasks++;
}
- if (this->hideKernelThreads && process->m_size == 0)
- ProcessList_remove(this, process);
+ if (!existingProcess) {
+ process = Process_clone(process);
+ ProcessList_add(this, process);
+ }
continue;
// Exception handler.
errorReadingProcess: {
- ProcessList_remove(this, process);
+ if (existingProcess)
+ ProcessList_remove(this, process);
+ else {
+ if (process->comm)
+ free(process->comm);
+ }
}
}
}
+ prototype->comm = NULL;
closedir(dir);
}
diff --git a/ProcessList.h b/ProcessList.h
index 15fc2824..b38cefcd 100644
--- a/ProcessList.h
+++ b/ProcessList.h
@@ -18,6 +18,7 @@ in the source distribution for its full text.
#include "Vector.h"
#include "UsersTable.h"
#include "Hashtable.h"
+#include "String.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -50,11 +51,15 @@ in the source distribution for its full text.
#endif
#ifndef MAX_READ
-#define MAX_READ 8192
+#define MAX_READ 2048
#endif
+#ifdef DEBUG
+typedef int(*vxscanf)(void*, const char*, va_list);
+#endif
+
typedef struct ProcessList_ {
Vector* processes;
Vector* processes2;
diff --git a/ScreenManager.c b/ScreenManager.c
index 7ec30ab2..8e88e28d 100644
--- a/ScreenManager.c
+++ b/ScreenManager.c
@@ -47,8 +47,8 @@ ScreenManager* ScreenManager_new(int x1, int y1, int x2, int y2, Orientation ori
this->y2 = y2;
this->fuBar = NULL;
this->orientation = orientation;
- this->items = Vector_new(PANEL_CLASS, owner, DEFAULT_SIZE);
- this->fuBars = Vector_new(FUNCTIONBAR_CLASS, true, DEFAULT_SIZE);
+ this->items = Vector_new(PANEL_CLASS, owner, DEFAULT_SIZE, NULL);
+ this->fuBars = Vector_new(FUNCTIONBAR_CLASS, true, DEFAULT_SIZE, NULL);
this->itemCount = 0;
this->owner = owner;
return this;
@@ -130,7 +130,7 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
if (this->fuBar)
FunctionBar_draw(this->fuBar, NULL);
- int ch;
+ int ch = 0;
while (!quit) {
int items = this->itemCount;
for (int i = 0; i < items; i++) {
diff --git a/SignalItem.c b/SignalItem.c
index ae84fa86..81f564d2 100644
--- a/SignalItem.c
+++ b/SignalItem.c
@@ -25,11 +25,15 @@ typedef struct Signal_ {
}*/
+#ifdef DEBUG
char* SIGNAL_CLASS = "Signal";
+#else
+#define SIGNAL_CLASS NULL
+#endif
Signal* Signal_new(char* name, int number) {
Signal* this = malloc(sizeof(Signal));
- ((Object*)this)->class = SIGNAL_CLASS;
+ Object_setClass(this, SIGNAL_CLASS);
((Object*)this)->display = Signal_display;
((Object*)this)->delete = Signal_delete;
this->name = name;
diff --git a/SignalItem.h b/SignalItem.h
index 04828c0a..c60dfa40 100644
--- a/SignalItem.h
+++ b/SignalItem.h
@@ -26,7 +26,11 @@ typedef struct Signal_ {
} Signal;
+#ifdef DEBUG
extern char* SIGNAL_CLASS;
+#else
+#define SIGNAL_CLASS NULL
+#endif
Signal* Signal_new(char* name, int number);
diff --git a/String.c b/String.c
index 00cd4f2c..e862bff5 100644
--- a/String.c
+++ b/String.c
@@ -14,6 +14,10 @@ in the source distribution for its full text.
#include "debug.h"
+/*{
+#define String_startsWith(s, match) (strstr((s), (match)) == (s))
+}*/
+
inline void String_delete(char* s) {
free(s);
}
@@ -102,10 +106,6 @@ inline int String_eq(char* s1, char* s2) {
return (strcmp(s1, s2) == 0);
}
-inline int String_startsWith(char* s, char* match) {
- return (strstr(s, match) == s);
-}
-
char** String_split(char* s, char sep) {
const int rate = 10;
char** out = (char**) malloc(sizeof(char*) * rate);
diff --git a/String.h b/String.h
index 8539f613..3a348c2a 100644
--- a/String.h
+++ b/String.h
@@ -17,6 +17,8 @@ in the source distribution for its full text.
#include "debug.h"
+#define String_startsWith(s, match) (strstr((s), (match)) == (s))
+
inline void String_delete(char* s);
inline char* String_copy(char* orig);
@@ -39,8 +41,6 @@ void String_printPointer(void* p);
inline int String_eq(char* s1, char* s2);
-inline int String_startsWith(char* s, char* match);
-
char** String_split(char* s, char sep);
void String_freeArray(char** s);
diff --git a/TraceScreen.c b/TraceScreen.c
index 001ef571..ff470c4f 100644
--- a/TraceScreen.c
+++ b/TraceScreen.c
@@ -41,7 +41,7 @@ static int tbEvents[3] = {KEY_F(4), KEY_F(5), 27};
TraceScreen* TraceScreen_new(Process* process) {
TraceScreen* this = (TraceScreen*) malloc(sizeof(TraceScreen));
this->process = process;
- this->display = Panel_new(0, 1, COLS, LINES-2, LISTITEM_CLASS, true);
+ this->display = Panel_new(0, 1, COLS, LINES-2, LISTITEM_CLASS, true, ListItem_compare);
this->bar = FunctionBar_new(3, tbFunctions, tbKeys, tbEvents);
this->tracing = true;
return this;
diff --git a/Vector.c b/Vector.c
index 349dd127..4ad697cb 100644
--- a/Vector.c
+++ b/Vector.c
@@ -24,6 +24,7 @@ typedef void(*Vector_procedure)(void*);
typedef struct Vector_ {
Object **array;
+ Object_Compare compare;
int arraySize;
int growthRate;
int items;
@@ -33,7 +34,7 @@ typedef struct Vector_ {
}*/
-Vector* Vector_new(char* vectorType_, bool owner, int size) {
+Vector* Vector_new(char* vectorType_, bool owner, int size, Object_Compare compare) {
Vector* this;
if (size == DEFAULT_SIZE)
@@ -45,6 +46,7 @@ Vector* Vector_new(char* vectorType_, bool owner, int size) {
this->items = 0;
this->vectorType = vectorType_;
this->owner = owner;
+ this->compare = compare;
return this;
}
@@ -58,6 +60,8 @@ void Vector_delete(Vector* this) {
free(this);
}
+#ifdef DEBUG
+
static inline bool Vector_isConsistent(Vector* this) {
if (this->owner) {
for (int i = 0; i < this->items; i++)
@@ -69,6 +73,8 @@ static inline bool Vector_isConsistent(Vector* this) {
}
}
+#endif
+
void Vector_prune(Vector* this) {
assert(Vector_isConsistent(this));
int i;
@@ -83,27 +89,18 @@ void Vector_prune(Vector* this) {
}
void Vector_sort(Vector* this) {
+ assert(this->compare);
assert(Vector_isConsistent(this));
- int i, j;
- for (i = 1; i < this->items; i++) {
+ Object_Compare compare = this->compare;
+ /* Insertion sort works best on mostly-sorted arrays. */
+ for (int i = 1; i < this->items; i++) {
+ int j;
void* t = this->array[i];
- for (j = i-1; j >= 0 && this->array[j]->compare(this->array[j], t) < 0; j--)
+ for (j = i-1; j >= 0 && compare(this->array[j], t) > 0; j--)
this->array[j+1] = this->array[j];
this->array[j+1] = t;
}
assert(Vector_isConsistent(this));
-
- /*
- for (int i = 0; i < this->items; i++) {
- for (int j = i+1; j < this->items; j++) {
- if (this->array[j]->compare(this->array[j], t) < 0) {
- void* tmp = this->array[i];
- this->array[i] = this->array[j];
- this->array[j] = tmp;
- }
- }
- }
- */
}
static void Vector_checkArraySize(Vector* this) {
@@ -230,16 +227,14 @@ void Vector_add(Vector* this, void* data_) {
assert(Vector_isConsistent(this));
}
-inline int Vector_indexOf(Vector* this, void* search_) {
+inline int Vector_indexOf(Vector* this, void* search_, Object_Compare compare) {
assert(((Object*)search_)->class == this->vectorType);
+ assert(this->compare);
Object* search = search_;
assert(Vector_isConsistent(this));
-
- int i;
-
- for (i = 0; i < this->items; i++) {
+ for (int i = 0; i < this->items; i++) {
Object* o = (Object*)this->array[i];
- if (o && o->compare(o, search) == 0)
+ if (o && compare(search, o) == 0)
return i;
}
return -1;
diff --git a/Vector.h b/Vector.h
index a01c8fa7..b332ae80 100644
--- a/Vector.h
+++ b/Vector.h
@@ -26,6 +26,7 @@ typedef void(*Vector_procedure)(void*);
typedef struct Vector_ {
Object **array;
+ Object_Compare compare;
int arraySize;
int growthRate;
int items;
@@ -34,10 +35,14 @@ typedef struct Vector_ {
} Vector;
-Vector* Vector_new(char* vectorType_, bool owner, int size);
+Vector* Vector_new(char* vectorType_, bool owner, int size, Object_Compare compare);
void Vector_delete(Vector* this);
+#ifdef DEBUG
+
+#endif
+
void Vector_prune(Vector* this);
void Vector_sort(Vector* this);
@@ -62,7 +67,7 @@ void Vector_merge(Vector* this, Vector* v2);
void Vector_add(Vector* this, void* data_);
-inline int Vector_indexOf(Vector* this, void* search_);
+inline int Vector_indexOf(Vector* this, void* search_, Object_Compare compare);
void Vector_foreach(Vector* this, Vector_procedure f);
diff --git a/htop.c b/htop.c
index de3f14eb..7ffccaa2 100644
--- a/htop.c
+++ b/htop.c
@@ -245,7 +245,7 @@ int main(int argc, char** argv) {
CRT_init(settings->delay, settings->colorScheme);
- panel = Panel_new(0, headerHeight, COLS, LINES - headerHeight - 2, PROCESS_CLASS, false);
+ panel = Panel_new(0, headerHeight, COLS, LINES - headerHeight - 2, PROCESS_CLASS, false, NULL);
Panel_setRichHeader(panel, ProcessList_printHeader(pl));
char* searchFunctions[3] = {"Next ", "Exit ", " Search: "};
@@ -506,7 +506,7 @@ int main(int argc, char** argv) {
}
case 'u':
{
- Panel* usersPanel = Panel_new(0, 0, 0, 0, LISTITEM_CLASS, true);
+ Panel* usersPanel = Panel_new(0, 0, 0, 0, LISTITEM_CLASS, true, ListItem_compare);
Panel_setHeader(usersPanel, "Show processes of:");
UsersTable_foreach(ut, addUserToList, usersPanel);
Vector_sort(usersPanel->items);
@@ -569,7 +569,7 @@ int main(int argc, char** argv) {
case '.':
case KEY_F(6):
{
- Panel* sortPanel = Panel_new(0,0,0,0,LISTITEM_CLASS,true);
+ Panel* sortPanel = Panel_new(0, 0, 0, 0, LISTITEM_CLASS, true, ListItem_compare);
Panel_setHeader(sortPanel, "Sort by");
char* fuFunctions[2] = {"Sort ", "Cancel "};
ProcessField* fields = pl->fields;

© 2014-2024 Faster IT GmbH | imprint | privacy policy